ipn,cmd/tailscale/cli: set correct SNI name for TLS-terminated TCP Services (#17752)
Fixes #17749. Signed-off-by: Naman Sood <mail@nsood.in>
This commit is contained in:
@@ -923,7 +923,7 @@ func (e *serveEnv) setServe(sc *ipn.ServeConfig, dnsName string, srvType serveTy
|
|||||||
if e.setPath != "" {
|
if e.setPath != "" {
|
||||||
return fmt.Errorf("cannot mount a path for TCP serve")
|
return fmt.Errorf("cannot mount a path for TCP serve")
|
||||||
}
|
}
|
||||||
err := e.applyTCPServe(sc, dnsName, srvType, srvPort, target, proxyProtocol)
|
err := e.applyTCPServe(sc, dnsName, srvType, srvPort, target, mds, proxyProtocol)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return fmt.Errorf("failed to apply TCP serve: %w", err)
|
return fmt.Errorf("failed to apply TCP serve: %w", err)
|
||||||
}
|
}
|
||||||
@@ -1203,7 +1203,7 @@ func (e *serveEnv) applyWebServe(sc *ipn.ServeConfig, dnsName string, srvPort ui
|
|||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
|
|
||||||
func (e *serveEnv) applyTCPServe(sc *ipn.ServeConfig, dnsName string, srcType serveType, srcPort uint16, target string, proxyProtocol int) error {
|
func (e *serveEnv) applyTCPServe(sc *ipn.ServeConfig, dnsName string, srcType serveType, srcPort uint16, target string, mds string, proxyProtocol int) error {
|
||||||
var terminateTLS bool
|
var terminateTLS bool
|
||||||
switch srcType {
|
switch srcType {
|
||||||
case serveTypeTCP:
|
case serveTypeTCP:
|
||||||
@@ -1226,11 +1226,22 @@ func (e *serveEnv) applyTCPServe(sc *ipn.ServeConfig, dnsName string, srcType se
|
|||||||
return fmt.Errorf("invalid TCP target %q: %v", target, err)
|
return fmt.Errorf("invalid TCP target %q: %v", target, err)
|
||||||
}
|
}
|
||||||
|
|
||||||
// TODO: needs to account for multiple configs from foreground mode
|
|
||||||
if sc.IsServingWeb(srcPort, svcName) {
|
if sc.IsServingWeb(srcPort, svcName) {
|
||||||
return fmt.Errorf("cannot serve TCP; already serving web on %d for %s", srcPort, dnsName)
|
return fmt.Errorf("cannot serve TCP; already serving web on %d for %s", srcPort, dnsName)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// TODO: needs to account for multiple configs from foreground mode
|
||||||
|
if svcName := tailcfg.AsServiceName(dnsName); svcName != "" {
|
||||||
|
sc.SetTCPForwardingForService(srcPort, dstURL.Host, terminateTLS, svcName, proxyProtocol, mds)
|
||||||
|
return nil
|
||||||
|
}
|
||||||
|
|
||||||
|
// TODO: needs to account for multiple configs from foreground mode
|
||||||
|
if svcName != "" {
|
||||||
|
sc.SetTCPForwardingForService(srcPort, dstURL.Host, terminateTLS, svcName, proxyProtocol, mds)
|
||||||
|
return nil
|
||||||
|
}
|
||||||
|
|
||||||
sc.SetTCPForwarding(srcPort, dstURL.Host, terminateTLS, proxyProtocol, dnsName)
|
sc.SetTCPForwarding(srcPort, dstURL.Host, terminateTLS, proxyProtocol, dnsName)
|
||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -2077,9 +2077,11 @@ func TestSetServe(t *testing.T) {
|
|||||||
if err == nil && tt.expectErr {
|
if err == nil && tt.expectErr {
|
||||||
t.Fatalf("got no error; expected error.")
|
t.Fatalf("got no error; expected error.")
|
||||||
}
|
}
|
||||||
if !tt.expectErr && !reflect.DeepEqual(tt.cfg, tt.expected) {
|
if !tt.expectErr {
|
||||||
svcName := tailcfg.ServiceName(tt.dnsName)
|
if diff := cmp.Diff(tt.expected, tt.cfg); diff != "" {
|
||||||
t.Fatalf("got: %v; expected: %v", tt.cfg.Services[svcName], tt.expected.Services[svcName])
|
// svcName := tailcfg.ServiceName(tt.dnsName)
|
||||||
|
t.Fatalf("got diff:\n%s", diff)
|
||||||
|
}
|
||||||
}
|
}
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
|
|||||||
+27
-14
@@ -433,24 +433,37 @@ func (sc *ServeConfig) SetTCPForwarding(port uint16, fwdAddr string, terminateTL
|
|||||||
if sc == nil {
|
if sc == nil {
|
||||||
sc = new(ServeConfig)
|
sc = new(ServeConfig)
|
||||||
}
|
}
|
||||||
tcpPortHandler := &sc.TCP
|
mak.Set(&sc.TCP, port, &TCPPortHandler{
|
||||||
if svcName := tailcfg.AsServiceName(host); svcName != "" {
|
|
||||||
svcConfig, ok := sc.Services[svcName]
|
|
||||||
if !ok {
|
|
||||||
svcConfig = new(ServiceConfig)
|
|
||||||
mak.Set(&sc.Services, svcName, svcConfig)
|
|
||||||
}
|
|
||||||
tcpPortHandler = &svcConfig.TCP
|
|
||||||
}
|
|
||||||
|
|
||||||
handler := &TCPPortHandler{
|
|
||||||
TCPForward: fwdAddr,
|
TCPForward: fwdAddr,
|
||||||
ProxyProtocol: proxyProtocol, // can be 0
|
ProxyProtocol: proxyProtocol, // can be 0
|
||||||
}
|
})
|
||||||
|
|
||||||
if terminateTLS {
|
if terminateTLS {
|
||||||
handler.TerminateTLS = host
|
sc.TCP[port].TerminateTLS = host
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// SetTCPForwardingForService sets the fwdAddr (IP:port form) to which to
|
||||||
|
// forward connections from the given port on the service. If terminateTLS
|
||||||
|
// is true, TLS connections are terminated, with only the FQDN that corresponds
|
||||||
|
// to the given service being permitted, before passing them to the fwdAddr.
|
||||||
|
func (sc *ServeConfig) SetTCPForwardingForService(port uint16, fwdAddr string, terminateTLS bool, svcName tailcfg.ServiceName, proxyProtocol int, magicDNSSuffix string) {
|
||||||
|
if sc == nil {
|
||||||
|
sc = new(ServeConfig)
|
||||||
|
}
|
||||||
|
svcConfig, ok := sc.Services[svcName]
|
||||||
|
if !ok {
|
||||||
|
svcConfig = new(ServiceConfig)
|
||||||
|
mak.Set(&sc.Services, svcName, svcConfig)
|
||||||
|
}
|
||||||
|
mak.Set(&svcConfig.TCP, port, &TCPPortHandler{
|
||||||
|
TCPForward: fwdAddr,
|
||||||
|
ProxyProtocol: proxyProtocol, // can be 0
|
||||||
|
})
|
||||||
|
|
||||||
|
if terminateTLS {
|
||||||
|
svcConfig.TCP[port].TerminateTLS = fmt.Sprintf("%s.%s", svcName.WithoutPrefix(), magicDNSSuffix)
|
||||||
}
|
}
|
||||||
mak.Set(tcpPortHandler, port, handler)
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// SetFunnel sets the sc.AllowFunnel value for the given host and port.
|
// SetFunnel sets the sc.AllowFunnel value for the given host and port.
|
||||||
|
|||||||
Reference in New Issue
Block a user