This commit is contained in:
bluepython508 committed 2026-10-22 12:27:19 +01:00
1 parent 3530afb854
commit 6903fcff27
2146 files changed
+112256 -190703

No files matched your search

+65 -19
View File
@@ -1,4 +1,4 @@
// Copyright (c) Tailscale Inc & AUTHORS
// Copyright (c) Tailscale Inc & contributors
// SPDX-License-Identifier: BSD-3-Clause
package ipn
@@ -17,6 +17,8 @@ import (
"tailscale.com/ipn/ipnstate"
"tailscale.com/tailcfg"
"tailscale.com/tailcfg/nodecap"
"tailscale.com/tailcfg/peercap"
"tailscale.com/types/ipproto"
"tailscale.com/util/dnsname"
"tailscale.com/util/mak"
@@ -139,7 +141,10 @@ type TCPPortHandler struct {
// It is mutually exclusive with TCPForward.
HTTP bool `json:",omitempty"`
// TCPForward is the IP:port to forward TCP connections to.
// TCPForward is the address to forward TCP connections to.
// It is either a host:port (e.g. "127.0.0.1:3128", "localhost:5432")
// or a Unix socket path prefixed with "unix:"
// (e.g. "unix:/var/run/app.sock" or "unix:relative.sock").
// Whether or not TLS is terminated by tailscaled depends on
// TerminateTLS.
//
@@ -168,7 +173,7 @@ type HTTPHandler struct {
Text string `json:",omitempty"` // plaintext to serve (primarily for testing)
AcceptAppCaps []tailcfg.PeerCapability `json:",omitempty"` // peer capabilities to forward in grant header, e.g. example.com/cap/mon
AcceptAppCaps []peercap.Cap `json:",omitempty"` // peer capabilities to forward in grant header, e.g. example.com/cap/mon
// Redirect, if not empty, is the target URL to redirect requests to.
// By default, we redirect with HTTP 302 (Found) status.
@@ -191,7 +196,7 @@ func (sc *ServeConfig) WebHandlerExists(svcName tailcfg.ServiceName, hp HostPort
}
// GetWebHandler returns the HTTPHandler for the given host:port and mount point.
// Returns nil if the handler does not exist.
// It returns nil if the handler does not exist.
func (sc *ServeConfig) GetWebHandler(svcName tailcfg.ServiceName, hp HostPort, mount string) *HTTPHandler {
if sc == nil {
return nil
@@ -264,6 +269,46 @@ func (sc *ServeConfig) HasPathHandler() bool {
return false
}
// IsServingUnixAny reports whether ServeConfig is serving Unix targets on any
// port or web handler.
func (sc *ServeConfig) IsServingUnixAny() bool {
if sc == nil {
return false
}
for _, fgSrvCfg := range sc.Foreground {
if fgSrvCfg.IsServingUnixAny() {
return true
}
}
for _, ph := range sc.TCP {
if strings.HasPrefix(ph.TCPForward, "unix:") {
return true
}
}
for _, web := range sc.Web {
for _, h := range web.Handlers {
if strings.HasPrefix(h.Proxy, "unix:") {
return true
}
}
}
for _, svcCfg := range sc.Services {
for _, ph := range svcCfg.TCP {
if strings.HasPrefix(ph.TCPForward, "unix:") {
return true
}
}
for _, web := range svcCfg.Web {
for _, h := range web.Handlers {
if strings.HasPrefix(h.Proxy, "unix:") {
return true
}
}
}
}
return false
}
// IsTCPForwardingAny reports whether ServeConfig is currently forwarding in
// TCPForward mode on any port. This is exclusive of Web/HTTPS serving.
func (sc *ServeConfig) IsTCPForwardingAny() bool {
@@ -422,10 +467,10 @@ func (sc *ServeConfig) SetWebHandler(handler *HTTPHandler, host string, port uin
}
}
// SetTCPForwarding sets the fwdAddr (IP:port form) to which to forward
// connections from the given port. If terminateTLS is true, TLS connections
// are terminated with only the given host name permitted before passing them
// to the fwdAddr.
// SetTCPForwarding sets the fwdAddr to which to forward connections from the
// given port. fwdAddr is either an IP:port or "unix:/path/to/socket".
// If terminateTLS is true, TLS connections are terminated with only the given
// host name permitted before passing them to the fwdAddr.
//
// If proxyProtocol is non-zero, the corresponding PROXY protocol version
// header is sent before forwarding the connection.
@@ -443,10 +488,11 @@ func (sc *ServeConfig) SetTCPForwarding(port uint16, fwdAddr string, terminateTL
}
}
// 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.
// SetTCPForwardingForService sets the fwdAddr to which to forward connections
// from the given port on the service. fwdAddr is either a host:port or
// "unix:/path" (absolute or relative). 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)
@@ -608,10 +654,10 @@ func CheckFunnelAccess(port uint16, node *ipnstate.PeerStatus) error {
// NodeCanFunnel returns an error if the given node is not configured to allow
// for Tailscale Funnel usage.
func NodeCanFunnel(node *ipnstate.PeerStatus) error {
if !node.HasCap(tailcfg.CapabilityHTTPS) {
if !node.HasCap(nodecap.HTTPS) {
return errors.New("Funnel not available; HTTPS must be enabled. See https://tailscale.com/s/https.")
}
if !node.HasCap(tailcfg.NodeAttrFunnel) {
if !node.HasCap(nodecap.Funnel) {
return errors.New("Funnel not available; \"funnel\" node attribute not set. See https://tailscale.com/s/no-funnel.")
}
return nil
@@ -638,14 +684,14 @@ func CheckFunnelPort(wantedPort uint16, node *ipnstate.PeerStatus) error {
return "", deny("")
}
u.RawQuery = ""
if u.String() != string(tailcfg.CapabilityFunnelPorts) {
if u.String() != string(nodecap.FunnelPorts) {
return "", deny("")
}
return portsStr, nil
}
for attr := range node.CapMap {
attr := string(attr)
if !strings.HasPrefix(attr, string(tailcfg.CapabilityFunnelPorts)) {
if !strings.HasPrefix(attr, string(nodecap.FunnelPorts)) {
continue
}
var err error
@@ -658,7 +704,7 @@ func CheckFunnelPort(wantedPort uint16, node *ipnstate.PeerStatus) error {
if portsStr == "" {
for attr := range node.CapMap {
attr := string(attr)
if !strings.HasPrefix(attr, string(tailcfg.CapabilityFunnelPorts)) {
if !strings.HasPrefix(attr, string(nodecap.FunnelPorts)) {
continue
}
var err error
@@ -673,7 +719,7 @@ func CheckFunnelPort(wantedPort uint16, node *ipnstate.PeerStatus) error {
return deny("")
}
wantedPortString := strconv.Itoa(int(wantedPort))
for _, ps := range strings.Split(portsStr, ",") {
for ps := range strings.SplitSeq(portsStr, ",") {
if ps == "" {
continue
}
@@ -785,7 +831,7 @@ func ExpandProxyTargetValue(target string, supportedSchemes []string, defaultSch
return "", fmt.Errorf("invalid port %q", u.Port())
}
u.Host = fmt.Sprintf("%s:%d", u.Hostname(), port)
u.Host = net.JoinHostPort(u.Hostname(), strconv.Itoa(int(port)))
return u.String(), nil
}