2023-01-27 13:37:20 -08:00
|
|
|
// Copyright (c) Tailscale Inc & AUTHORS
|
|
|
|
// SPDX-License-Identifier: BSD-3-Clause
|
2022-11-19 09:42:14 -05:00
|
|
|
|
|
|
|
package ipn
|
|
|
|
|
2023-03-08 12:36:41 -08:00
|
|
|
import (
|
2023-03-10 11:44:28 -08:00
|
|
|
"errors"
|
2023-03-11 08:45:40 -08:00
|
|
|
"fmt"
|
2025-01-04 13:46:09 -08:00
|
|
|
"iter"
|
2023-03-08 12:36:41 -08:00
|
|
|
"net"
|
|
|
|
"net/netip"
|
2023-03-11 08:45:40 -08:00
|
|
|
"net/url"
|
2024-03-05 13:54:37 -05:00
|
|
|
"slices"
|
2023-03-11 08:45:40 -08:00
|
|
|
"strconv"
|
|
|
|
"strings"
|
2023-03-10 11:44:28 -08:00
|
|
|
|
2023-09-27 23:01:09 -07:00
|
|
|
"tailscale.com/ipn/ipnstate"
|
2023-03-10 11:44:28 -08:00
|
|
|
"tailscale.com/tailcfg"
|
2025-01-06 11:27:11 -05:00
|
|
|
"tailscale.com/types/ipproto"
|
2024-03-05 18:46:42 -05:00
|
|
|
"tailscale.com/util/mak"
|
2025-01-06 11:27:11 -05:00
|
|
|
"tailscale.com/util/set"
|
2023-03-08 12:36:41 -08:00
|
|
|
)
|
|
|
|
|
2022-11-19 09:42:14 -05:00
|
|
|
// ServeConfigKey returns a StateKey that stores the
|
|
|
|
// JSON-encoded ServeConfig for a config profile.
|
|
|
|
func ServeConfigKey(profileID ProfileID) StateKey {
|
|
|
|
return StateKey("_serve/" + profileID)
|
|
|
|
}
|
|
|
|
|
2024-11-28 12:49:37 -05:00
|
|
|
// ServiceConfig contains the config information for a single service.
|
|
|
|
// it contains a bool to indicate if the service is in Tun mode (L3 forwarding).
|
|
|
|
// If the service is not in Tun mode, the service is configured by the L4 forwarding
|
|
|
|
// (TCP ports) and/or the L7 forwarding (http handlers) information.
|
|
|
|
type ServiceConfig struct {
|
|
|
|
// TCP are the list of TCP port numbers that tailscaled should handle for
|
|
|
|
// the Tailscale IP addresses. (not subnet routers, etc)
|
|
|
|
TCP map[uint16]*TCPPortHandler `json:",omitempty"`
|
|
|
|
|
|
|
|
// Web maps from "$SNI_NAME:$PORT" to a set of HTTP handlers
|
|
|
|
// keyed by mount point ("/", "/foo", etc)
|
|
|
|
Web map[HostPort]*WebServerConfig `json:",omitempty"`
|
|
|
|
|
|
|
|
// Tun determines if the service should be using L3 forwarding (Tun mode).
|
|
|
|
Tun bool `json:",omitempty"`
|
|
|
|
}
|
|
|
|
|
2022-11-19 09:42:14 -05:00
|
|
|
// ServeConfig is the JSON type stored in the StateStore for
|
|
|
|
// StateKey "_serve/$PROFILE_ID" as returned by ServeConfigKey.
|
|
|
|
type ServeConfig struct {
|
|
|
|
// TCP are the list of TCP port numbers that tailscaled should handle for
|
|
|
|
// the Tailscale IP addresses. (not subnet routers, etc)
|
|
|
|
TCP map[uint16]*TCPPortHandler `json:",omitempty"`
|
|
|
|
|
|
|
|
// Web maps from "$SNI_NAME:$PORT" to a set of HTTP handlers
|
|
|
|
// keyed by mount point ("/", "/foo", etc)
|
|
|
|
Web map[HostPort]*WebServerConfig `json:",omitempty"`
|
2024-11-28 12:49:37 -05:00
|
|
|
|
2025-01-20 12:02:53 -05:00
|
|
|
// Services maps from service name (in the form "svc:dns-label") to a ServiceConfig.
|
|
|
|
// Which describes the L3, L4, and L7 forwarding information for the service.
|
2025-01-21 17:07:34 -05:00
|
|
|
Services map[tailcfg.ServiceName]*ServiceConfig `json:",omitempty"`
|
2022-11-19 09:42:14 -05:00
|
|
|
|
|
|
|
// AllowFunnel is the set of SNI:port values for which funnel
|
|
|
|
// traffic is allowed, from trusted ingress peers.
|
|
|
|
AllowFunnel map[HostPort]bool `json:",omitempty"`
|
2023-09-05 14:33:18 -04:00
|
|
|
|
2025-01-19 19:00:21 +00:00
|
|
|
// Foreground is a map of an IPN Bus session ID to an alternate foreground serve config that's valid for the
|
|
|
|
// life of that WatchIPNBus session ID. This allows the config to specify ephemeral configs that are used
|
|
|
|
// in the CLI's foreground mode to ensure ungraceful shutdowns of either the client or the LocalBackend does not
|
|
|
|
// expose ports that users are not aware of. In practice this contains any serve config set via 'tailscale
|
|
|
|
// serve' command run without the '--bg' flag. ServeConfig contained by Foreground is not expected itself to contain
|
|
|
|
// another Foreground block.
|
2023-09-05 14:33:18 -04:00
|
|
|
Foreground map[string]*ServeConfig `json:",omitempty"`
|
2023-09-11 21:32:51 -04:00
|
|
|
|
|
|
|
// ETag is the checksum of the serve config that's populated
|
|
|
|
// by the LocalClient through the HTTP ETag header during a
|
|
|
|
// GetServeConfig request and is translated to an If-Match header
|
|
|
|
// during a SetServeConfig request.
|
|
|
|
ETag string `json:"-"`
|
2022-11-19 09:42:14 -05:00
|
|
|
}
|
|
|
|
|
|
|
|
// HostPort is an SNI name and port number, joined by a colon.
|
|
|
|
// There is no implicit port 443. It must contain a colon.
|
|
|
|
type HostPort string
|
|
|
|
|
2023-08-17 11:47:35 -04:00
|
|
|
// Port extracts just the port number from hp.
|
|
|
|
// An error is reported in the case that the hp does not
|
|
|
|
// have a valid numeric port ending.
|
|
|
|
func (hp HostPort) Port() (uint16, error) {
|
|
|
|
_, port, err := net.SplitHostPort(string(hp))
|
|
|
|
if err != nil {
|
|
|
|
return 0, err
|
|
|
|
}
|
|
|
|
port16, err := strconv.ParseUint(port, 10, 16)
|
|
|
|
if err != nil {
|
|
|
|
return 0, err
|
|
|
|
}
|
|
|
|
return uint16(port16), nil
|
|
|
|
}
|
|
|
|
|
2023-03-08 12:36:41 -08:00
|
|
|
// A FunnelConn wraps a net.Conn that is coming over a
|
|
|
|
// Funnel connection. It can be used to determine further
|
|
|
|
// information about the connection, like the source address
|
|
|
|
// and the target SNI name.
|
|
|
|
type FunnelConn struct {
|
|
|
|
// Conn is the underlying connection.
|
|
|
|
net.Conn
|
|
|
|
|
|
|
|
// Target is what was presented in the "Tailscale-Ingress-Target"
|
|
|
|
// HTTP header.
|
|
|
|
Target HostPort
|
|
|
|
|
|
|
|
// Src is the source address of the connection.
|
|
|
|
// This is the address of the client that initiated the
|
|
|
|
// connection, not the address of the Tailscale Funnel
|
|
|
|
// node which is relaying the connection. That address
|
|
|
|
// can be found in Conn.RemoteAddr.
|
|
|
|
Src netip.AddrPort
|
|
|
|
}
|
|
|
|
|
2022-11-19 09:42:14 -05:00
|
|
|
// WebServerConfig describes a web server's configuration.
|
|
|
|
type WebServerConfig struct {
|
|
|
|
Handlers map[string]*HTTPHandler // mountPoint => handler
|
|
|
|
}
|
|
|
|
|
|
|
|
// TCPPortHandler describes what to do when handling a TCP
|
|
|
|
// connection.
|
|
|
|
type TCPPortHandler struct {
|
|
|
|
// HTTPS, if true, means that tailscaled should handle this connection as an
|
|
|
|
// HTTPS request as configured by ServeConfig.Web.
|
|
|
|
//
|
|
|
|
// It is mutually exclusive with TCPForward.
|
|
|
|
HTTPS bool `json:",omitempty"`
|
|
|
|
|
2023-06-21 12:32:20 -04:00
|
|
|
// HTTP, if true, means that tailscaled should handle this connection as an
|
|
|
|
// HTTP request as configured by ServeConfig.Web.
|
|
|
|
//
|
|
|
|
// It is mutually exclusive with TCPForward.
|
|
|
|
HTTP bool `json:",omitempty"`
|
|
|
|
|
2022-11-19 09:42:14 -05:00
|
|
|
// TCPForward is the IP:port to forward TCP connections to.
|
|
|
|
// Whether or not TLS is terminated by tailscaled depends on
|
|
|
|
// TerminateTLS.
|
|
|
|
//
|
|
|
|
// It is mutually exclusive with HTTPS.
|
|
|
|
TCPForward string `json:",omitempty"`
|
|
|
|
|
|
|
|
// TerminateTLS, if non-empty, means that tailscaled should terminate the
|
|
|
|
// TLS connections before forwarding them to TCPForward, permitting only the
|
|
|
|
// SNI name with this value. It is only used if TCPForward is non-empty.
|
|
|
|
// (the HTTPS mode uses ServeConfig.Web)
|
|
|
|
TerminateTLS string `json:",omitempty"`
|
|
|
|
}
|
|
|
|
|
|
|
|
// HTTPHandler is either a path or a proxy to serve.
|
|
|
|
type HTTPHandler struct {
|
|
|
|
// Exactly one of the following may be set.
|
|
|
|
|
|
|
|
Path string `json:",omitempty"` // absolute path to directory or file to serve
|
|
|
|
Proxy string `json:",omitempty"` // http://localhost:3000/, localhost:3030, 3030
|
|
|
|
|
|
|
|
Text string `json:",omitempty"` // plaintext to serve (primarily for testing)
|
|
|
|
|
|
|
|
// TODO(bradfitz): bool to not enumerate directories? TTL on mapping for
|
|
|
|
// temporary ones? Error codes? Redirects?
|
|
|
|
}
|
|
|
|
|
2023-06-21 12:32:20 -04:00
|
|
|
// WebHandlerExists reports whether if the ServeConfig Web handler exists for
|
2022-11-19 09:42:14 -05:00
|
|
|
// the given host:port and mount point.
|
cmd/tailscale/cli: Add service flag to serve command
This commit adds the service flag to serve command which allows serving a service and add the service
to the advertisedServices field in prefs (What advertise command does that will be removed later).
When adding proxies, TCP proxies and WEB proxies work the same way as normal serve, just under a
different DNSname. There is a services specific L3 serving mode called Tun, can be set via --tun flag.
Serving a service is always in --bg mode. If --bg is explicitly set t o false, an error message will
be sent out. The restriction on proxy target being localhost or 127.0.0.1 also applies to services.
When removing proxies, TCP proxies can be removed with type and port flag and off argument. Web proxies
can be removed with type, port, setPath flag and off argument. To align with normal serve, when setPath
is not set, all handler under the hostport will be removed. When flags are not set but off argument was
passed by user, it will be a noop. Removing all config for a service will be available later with a new
subcommand clear.
Updates tailscale/corp#22954
Signed-off-by: KevinLiang10 <37811973+KevinLiang10@users.noreply.github.com>
2025-06-04 12:09:46 -04:00
|
|
|
func (sc *ServeConfig) WebHandlerExists(dnsName string, hp HostPort, mount string) bool {
|
|
|
|
h := sc.GetWebHandler(dnsName, hp, mount)
|
2022-11-19 09:42:14 -05:00
|
|
|
return h != nil
|
|
|
|
}
|
|
|
|
|
|
|
|
// GetWebHandler returns the HTTPHandler for the given host:port and mount point.
|
|
|
|
// Returns nil if the handler does not exist.
|
cmd/tailscale/cli: Add service flag to serve command
This commit adds the service flag to serve command which allows serving a service and add the service
to the advertisedServices field in prefs (What advertise command does that will be removed later).
When adding proxies, TCP proxies and WEB proxies work the same way as normal serve, just under a
different DNSname. There is a services specific L3 serving mode called Tun, can be set via --tun flag.
Serving a service is always in --bg mode. If --bg is explicitly set t o false, an error message will
be sent out. The restriction on proxy target being localhost or 127.0.0.1 also applies to services.
When removing proxies, TCP proxies can be removed with type and port flag and off argument. Web proxies
can be removed with type, port, setPath flag and off argument. To align with normal serve, when setPath
is not set, all handler under the hostport will be removed. When flags are not set but off argument was
passed by user, it will be a noop. Removing all config for a service will be available later with a new
subcommand clear.
Updates tailscale/corp#22954
Signed-off-by: KevinLiang10 <37811973+KevinLiang10@users.noreply.github.com>
2025-06-04 12:09:46 -04:00
|
|
|
func (sc *ServeConfig) GetWebHandler(dnsName string, hp HostPort, mount string) *HTTPHandler {
|
|
|
|
if sc == nil {
|
|
|
|
return nil
|
|
|
|
}
|
|
|
|
if IsServiceName(dnsName) {
|
|
|
|
if svc, ok := sc.Services[tailcfg.ServiceName(dnsName)]; ok && svc.Web != nil {
|
|
|
|
if webCfg, ok := svc.Web[hp]; ok {
|
|
|
|
return webCfg.Handlers[mount]
|
|
|
|
}
|
|
|
|
}
|
|
|
|
return nil
|
|
|
|
}
|
|
|
|
if sc.Web[hp] == nil {
|
2022-12-07 22:17:40 -05:00
|
|
|
return nil
|
2022-11-19 09:42:14 -05:00
|
|
|
}
|
2022-12-07 22:17:40 -05:00
|
|
|
return sc.Web[hp].Handlers[mount]
|
2022-11-19 09:42:14 -05:00
|
|
|
}
|
|
|
|
|
|
|
|
// GetTCPPortHandler returns the TCPPortHandler for the given port.
|
|
|
|
// If the port is not configured, nil is returned.
|
cmd/tailscale/cli: Add service flag to serve command
This commit adds the service flag to serve command which allows serving a service and add the service
to the advertisedServices field in prefs (What advertise command does that will be removed later).
When adding proxies, TCP proxies and WEB proxies work the same way as normal serve, just under a
different DNSname. There is a services specific L3 serving mode called Tun, can be set via --tun flag.
Serving a service is always in --bg mode. If --bg is explicitly set t o false, an error message will
be sent out. The restriction on proxy target being localhost or 127.0.0.1 also applies to services.
When removing proxies, TCP proxies can be removed with type and port flag and off argument. Web proxies
can be removed with type, port, setPath flag and off argument. To align with normal serve, when setPath
is not set, all handler under the hostport will be removed. When flags are not set but off argument was
passed by user, it will be a noop. Removing all config for a service will be available later with a new
subcommand clear.
Updates tailscale/corp#22954
Signed-off-by: KevinLiang10 <37811973+KevinLiang10@users.noreply.github.com>
2025-06-04 12:09:46 -04:00
|
|
|
func (sc *ServeConfig) GetTCPPortHandler(port uint16, dnsName string) *TCPPortHandler {
|
2022-12-07 22:17:40 -05:00
|
|
|
if sc == nil {
|
|
|
|
return nil
|
|
|
|
}
|
cmd/tailscale/cli: Add service flag to serve command
This commit adds the service flag to serve command which allows serving a service and add the service
to the advertisedServices field in prefs (What advertise command does that will be removed later).
When adding proxies, TCP proxies and WEB proxies work the same way as normal serve, just under a
different DNSname. There is a services specific L3 serving mode called Tun, can be set via --tun flag.
Serving a service is always in --bg mode. If --bg is explicitly set t o false, an error message will
be sent out. The restriction on proxy target being localhost or 127.0.0.1 also applies to services.
When removing proxies, TCP proxies can be removed with type and port flag and off argument. Web proxies
can be removed with type, port, setPath flag and off argument. To align with normal serve, when setPath
is not set, all handler under the hostport will be removed. When flags are not set but off argument was
passed by user, it will be a noop. Removing all config for a service will be available later with a new
subcommand clear.
Updates tailscale/corp#22954
Signed-off-by: KevinLiang10 <37811973+KevinLiang10@users.noreply.github.com>
2025-06-04 12:09:46 -04:00
|
|
|
if IsServiceName(dnsName) {
|
|
|
|
if svc, ok := sc.Services[tailcfg.ServiceName(dnsName)]; ok && svc != nil {
|
|
|
|
return svc.TCP[port]
|
|
|
|
}
|
|
|
|
return nil
|
|
|
|
}
|
2022-11-19 09:42:14 -05:00
|
|
|
return sc.TCP[port]
|
|
|
|
}
|
|
|
|
|
2023-10-26 14:40:44 -07:00
|
|
|
// HasPathHandler reports whether if ServeConfig has at least
|
|
|
|
// one path handler, including foreground configs.
|
|
|
|
func (sc *ServeConfig) HasPathHandler() bool {
|
|
|
|
if sc.Web != nil {
|
|
|
|
for _, webServerConfig := range sc.Web {
|
|
|
|
for _, httpHandler := range webServerConfig.Handlers {
|
|
|
|
if httpHandler.Path != "" {
|
|
|
|
return true
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
if sc.Foreground != nil {
|
|
|
|
for _, fgConfig := range sc.Foreground {
|
|
|
|
if fgConfig.HasPathHandler() {
|
|
|
|
return true
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
return false
|
|
|
|
}
|
|
|
|
|
2023-06-21 12:32:20 -04:00
|
|
|
// IsTCPForwardingAny reports whether ServeConfig is currently forwarding in
|
|
|
|
// TCPForward mode on any port. This is exclusive of Web/HTTPS serving.
|
2022-11-19 09:42:14 -05:00
|
|
|
func (sc *ServeConfig) IsTCPForwardingAny() bool {
|
2022-12-07 22:17:40 -05:00
|
|
|
if sc == nil || len(sc.TCP) == 0 {
|
2022-11-19 09:42:14 -05:00
|
|
|
return false
|
|
|
|
}
|
|
|
|
for _, h := range sc.TCP {
|
|
|
|
if h.TCPForward != "" {
|
|
|
|
return true
|
|
|
|
}
|
|
|
|
}
|
|
|
|
return false
|
|
|
|
}
|
|
|
|
|
cmd/tailscale/cli: Add service flag to serve command
This commit adds the service flag to serve command which allows serving a service and add the service
to the advertisedServices field in prefs (What advertise command does that will be removed later).
When adding proxies, TCP proxies and WEB proxies work the same way as normal serve, just under a
different DNSname. There is a services specific L3 serving mode called Tun, can be set via --tun flag.
Serving a service is always in --bg mode. If --bg is explicitly set t o false, an error message will
be sent out. The restriction on proxy target being localhost or 127.0.0.1 also applies to services.
When removing proxies, TCP proxies can be removed with type and port flag and off argument. Web proxies
can be removed with type, port, setPath flag and off argument. To align with normal serve, when setPath
is not set, all handler under the hostport will be removed. When flags are not set but off argument was
passed by user, it will be a noop. Removing all config for a service will be available later with a new
subcommand clear.
Updates tailscale/corp#22954
Signed-off-by: KevinLiang10 <37811973+KevinLiang10@users.noreply.github.com>
2025-06-04 12:09:46 -04:00
|
|
|
// IsServiceName reports whether if the given string is a valid service name.
|
|
|
|
func IsServiceName(s string) bool {
|
|
|
|
return tailcfg.ServiceName(s).Validate() == nil
|
|
|
|
}
|
|
|
|
|
2025-06-26 13:31:34 -04:00
|
|
|
// asServiceName reports whether if the given string is a valid service name,
|
|
|
|
// and if so returns the name as a [tailcfg.ServiceName].
|
|
|
|
func asServiceName(s string) (svcName tailcfg.ServiceName, ok bool) {
|
|
|
|
svcName = tailcfg.ServiceName(s)
|
|
|
|
return svcName, svcName.Validate() == nil
|
|
|
|
}
|
|
|
|
|
cmd/tailscale/cli: Add service flag to serve command
This commit adds the service flag to serve command which allows serving a service and add the service
to the advertisedServices field in prefs (What advertise command does that will be removed later).
When adding proxies, TCP proxies and WEB proxies work the same way as normal serve, just under a
different DNSname. There is a services specific L3 serving mode called Tun, can be set via --tun flag.
Serving a service is always in --bg mode. If --bg is explicitly set t o false, an error message will
be sent out. The restriction on proxy target being localhost or 127.0.0.1 also applies to services.
When removing proxies, TCP proxies can be removed with type and port flag and off argument. Web proxies
can be removed with type, port, setPath flag and off argument. To align with normal serve, when setPath
is not set, all handler under the hostport will be removed. When flags are not set but off argument was
passed by user, it will be a noop. Removing all config for a service will be available later with a new
subcommand clear.
Updates tailscale/corp#22954
Signed-off-by: KevinLiang10 <37811973+KevinLiang10@users.noreply.github.com>
2025-06-04 12:09:46 -04:00
|
|
|
// IsTCPForwardingOnPort reports whether ServeConfig is currently forwarding
|
|
|
|
// in TCPForward mode on the given port for a DNSName. DNSName will be either node's DNSName, or a
|
|
|
|
// serviceName for service hosted on node. This is exclusive of Web/HTTPS serving.
|
|
|
|
func (sc *ServeConfig) IsTCPForwardingOnPort(port uint16, dnsName string) bool {
|
|
|
|
if sc == nil {
|
2022-11-19 09:42:14 -05:00
|
|
|
return false
|
|
|
|
}
|
cmd/tailscale/cli: Add service flag to serve command
This commit adds the service flag to serve command which allows serving a service and add the service
to the advertisedServices field in prefs (What advertise command does that will be removed later).
When adding proxies, TCP proxies and WEB proxies work the same way as normal serve, just under a
different DNSname. There is a services specific L3 serving mode called Tun, can be set via --tun flag.
Serving a service is always in --bg mode. If --bg is explicitly set t o false, an error message will
be sent out. The restriction on proxy target being localhost or 127.0.0.1 also applies to services.
When removing proxies, TCP proxies can be removed with type and port flag and off argument. Web proxies
can be removed with type, port, setPath flag and off argument. To align with normal serve, when setPath
is not set, all handler under the hostport will be removed. When flags are not set but off argument was
passed by user, it will be a noop. Removing all config for a service will be available later with a new
subcommand clear.
Updates tailscale/corp#22954
Signed-off-by: KevinLiang10 <37811973+KevinLiang10@users.noreply.github.com>
2025-06-04 12:09:46 -04:00
|
|
|
forService := IsServiceName(dnsName)
|
|
|
|
if forService {
|
|
|
|
svc, ok := sc.Services[tailcfg.ServiceName(dnsName)]
|
|
|
|
if !ok || svc == nil {
|
|
|
|
return false
|
|
|
|
}
|
|
|
|
if svc.TCP[port] == nil {
|
|
|
|
return false
|
|
|
|
}
|
|
|
|
} else if sc.TCP[port] == nil {
|
|
|
|
return false
|
|
|
|
}
|
|
|
|
return !sc.IsServingWeb(port, dnsName)
|
2022-11-19 09:42:14 -05:00
|
|
|
}
|
|
|
|
|
cmd/tailscale/cli: Add service flag to serve command
This commit adds the service flag to serve command which allows serving a service and add the service
to the advertisedServices field in prefs (What advertise command does that will be removed later).
When adding proxies, TCP proxies and WEB proxies work the same way as normal serve, just under a
different DNSname. There is a services specific L3 serving mode called Tun, can be set via --tun flag.
Serving a service is always in --bg mode. If --bg is explicitly set t o false, an error message will
be sent out. The restriction on proxy target being localhost or 127.0.0.1 also applies to services.
When removing proxies, TCP proxies can be removed with type and port flag and off argument. Web proxies
can be removed with type, port, setPath flag and off argument. To align with normal serve, when setPath
is not set, all handler under the hostport will be removed. When flags are not set but off argument was
passed by user, it will be a noop. Removing all config for a service will be available later with a new
subcommand clear.
Updates tailscale/corp#22954
Signed-off-by: KevinLiang10 <37811973+KevinLiang10@users.noreply.github.com>
2025-06-04 12:09:46 -04:00
|
|
|
// IsServingWeb reports whether ServeConfig is currently serving Web
|
|
|
|
// (HTTP/HTTPS) on the given port for a DNSName. DNSName will be either node's DNSName, or a
|
|
|
|
// serviceName for service hosted on node. This is exclusive of TCPForwarding.
|
|
|
|
func (sc *ServeConfig) IsServingWeb(port uint16, dnsName string) bool {
|
|
|
|
return sc.IsServingHTTP(port, dnsName) || sc.IsServingHTTPS(port, dnsName)
|
2023-06-21 12:32:20 -04:00
|
|
|
}
|
|
|
|
|
cmd/tailscale/cli: Add service flag to serve command
This commit adds the service flag to serve command which allows serving a service and add the service
to the advertisedServices field in prefs (What advertise command does that will be removed later).
When adding proxies, TCP proxies and WEB proxies work the same way as normal serve, just under a
different DNSname. There is a services specific L3 serving mode called Tun, can be set via --tun flag.
Serving a service is always in --bg mode. If --bg is explicitly set t o false, an error message will
be sent out. The restriction on proxy target being localhost or 127.0.0.1 also applies to services.
When removing proxies, TCP proxies can be removed with type and port flag and off argument. Web proxies
can be removed with type, port, setPath flag and off argument. To align with normal serve, when setPath
is not set, all handler under the hostport will be removed. When flags are not set but off argument was
passed by user, it will be a noop. Removing all config for a service will be available later with a new
subcommand clear.
Updates tailscale/corp#22954
Signed-off-by: KevinLiang10 <37811973+KevinLiang10@users.noreply.github.com>
2025-06-04 12:09:46 -04:00
|
|
|
// IsServingHTTPS reports whether ServeConfig is currently serving HTTPS on
|
|
|
|
// the given port for a DNSName. DNSName will be either node's DNSName, or a
|
|
|
|
// serviceName for service hosted on node. This is exclusive of HTTP and TCPForwarding.
|
|
|
|
func (sc *ServeConfig) IsServingHTTPS(port uint16, dnsName string) bool {
|
|
|
|
if sc == nil {
|
|
|
|
return false
|
|
|
|
}
|
2025-06-26 13:31:34 -04:00
|
|
|
var tcpHandlers map[uint16]*TCPPortHandler
|
|
|
|
if svcName, ok := asServiceName(dnsName); ok {
|
|
|
|
if svc := sc.Services[svcName]; svc != nil {
|
|
|
|
tcpHandlers = svc.TCP
|
cmd/tailscale/cli: Add service flag to serve command
This commit adds the service flag to serve command which allows serving a service and add the service
to the advertisedServices field in prefs (What advertise command does that will be removed later).
When adding proxies, TCP proxies and WEB proxies work the same way as normal serve, just under a
different DNSname. There is a services specific L3 serving mode called Tun, can be set via --tun flag.
Serving a service is always in --bg mode. If --bg is explicitly set t o false, an error message will
be sent out. The restriction on proxy target being localhost or 127.0.0.1 also applies to services.
When removing proxies, TCP proxies can be removed with type and port flag and off argument. Web proxies
can be removed with type, port, setPath flag and off argument. To align with normal serve, when setPath
is not set, all handler under the hostport will be removed. When flags are not set but off argument was
passed by user, it will be a noop. Removing all config for a service will be available later with a new
subcommand clear.
Updates tailscale/corp#22954
Signed-off-by: KevinLiang10 <37811973+KevinLiang10@users.noreply.github.com>
2025-06-04 12:09:46 -04:00
|
|
|
}
|
2025-06-26 13:31:34 -04:00
|
|
|
} else {
|
|
|
|
tcpHandlers = sc.TCP
|
cmd/tailscale/cli: Add service flag to serve command
This commit adds the service flag to serve command which allows serving a service and add the service
to the advertisedServices field in prefs (What advertise command does that will be removed later).
When adding proxies, TCP proxies and WEB proxies work the same way as normal serve, just under a
different DNSname. There is a services specific L3 serving mode called Tun, can be set via --tun flag.
Serving a service is always in --bg mode. If --bg is explicitly set t o false, an error message will
be sent out. The restriction on proxy target being localhost or 127.0.0.1 also applies to services.
When removing proxies, TCP proxies can be removed with type and port flag and off argument. Web proxies
can be removed with type, port, setPath flag and off argument. To align with normal serve, when setPath
is not set, all handler under the hostport will be removed. When flags are not set but off argument was
passed by user, it will be a noop. Removing all config for a service will be available later with a new
subcommand clear.
Updates tailscale/corp#22954
Signed-off-by: KevinLiang10 <37811973+KevinLiang10@users.noreply.github.com>
2025-06-04 12:09:46 -04:00
|
|
|
}
|
2025-06-26 13:31:34 -04:00
|
|
|
|
|
|
|
th := tcpHandlers[port]
|
|
|
|
if th == nil {
|
2022-11-19 09:42:14 -05:00
|
|
|
return false
|
|
|
|
}
|
2025-06-26 13:31:34 -04:00
|
|
|
return th.HTTPS
|
2022-11-19 09:42:14 -05:00
|
|
|
}
|
|
|
|
|
cmd/tailscale/cli: Add service flag to serve command
This commit adds the service flag to serve command which allows serving a service and add the service
to the advertisedServices field in prefs (What advertise command does that will be removed later).
When adding proxies, TCP proxies and WEB proxies work the same way as normal serve, just under a
different DNSname. There is a services specific L3 serving mode called Tun, can be set via --tun flag.
Serving a service is always in --bg mode. If --bg is explicitly set t o false, an error message will
be sent out. The restriction on proxy target being localhost or 127.0.0.1 also applies to services.
When removing proxies, TCP proxies can be removed with type and port flag and off argument. Web proxies
can be removed with type, port, setPath flag and off argument. To align with normal serve, when setPath
is not set, all handler under the hostport will be removed. When flags are not set but off argument was
passed by user, it will be a noop. Removing all config for a service will be available later with a new
subcommand clear.
Updates tailscale/corp#22954
Signed-off-by: KevinLiang10 <37811973+KevinLiang10@users.noreply.github.com>
2025-06-04 12:09:46 -04:00
|
|
|
// IsServingHTTP reports whether ServeConfig is currently serving HTTP on the
|
|
|
|
// given port for a DNSName. DNSName will be either node's DNSName, or a
|
|
|
|
// serviceName for service hosted on node. This is exclusive of HTTPS and TCPForwarding.
|
|
|
|
func (sc *ServeConfig) IsServingHTTP(port uint16, dnsName string) bool {
|
|
|
|
if sc == nil {
|
|
|
|
return false
|
|
|
|
}
|
|
|
|
if IsServiceName(dnsName) {
|
|
|
|
if svc, ok := sc.Services[tailcfg.ServiceName(dnsName)]; ok && svc != nil {
|
|
|
|
if svc.TCP[port] != nil {
|
|
|
|
return svc.TCP[port].HTTP
|
|
|
|
}
|
|
|
|
}
|
|
|
|
return false
|
|
|
|
}
|
|
|
|
|
|
|
|
if sc.TCP[port] == nil {
|
2023-06-21 12:32:20 -04:00
|
|
|
return false
|
|
|
|
}
|
|
|
|
return sc.TCP[port].HTTP
|
|
|
|
}
|
|
|
|
|
2024-03-05 13:54:37 -05:00
|
|
|
// FindConfig finds a config that contains the given port, which can be
|
|
|
|
// the top level background config or an inner foreground one.
|
|
|
|
// The second result is true if it's foreground.
|
|
|
|
func (sc *ServeConfig) FindConfig(port uint16) (*ServeConfig, bool) {
|
|
|
|
if sc == nil {
|
|
|
|
return nil, false
|
|
|
|
}
|
|
|
|
if _, ok := sc.TCP[port]; ok {
|
|
|
|
return sc, false
|
|
|
|
}
|
|
|
|
for _, sc := range sc.Foreground {
|
|
|
|
if _, ok := sc.TCP[port]; ok {
|
|
|
|
return sc, true
|
|
|
|
}
|
|
|
|
}
|
|
|
|
return nil, false
|
|
|
|
}
|
|
|
|
|
2024-03-05 18:46:42 -05:00
|
|
|
// SetWebHandler sets the given HTTPHandler at the specified host, port,
|
|
|
|
// and mount in the serve config. sc.TCP is also updated to reflect web
|
|
|
|
// serving usage of the given port.
|
cmd/tailscale/cli: Add service flag to serve command
This commit adds the service flag to serve command which allows serving a service and add the service
to the advertisedServices field in prefs (What advertise command does that will be removed later).
When adding proxies, TCP proxies and WEB proxies work the same way as normal serve, just under a
different DNSname. There is a services specific L3 serving mode called Tun, can be set via --tun flag.
Serving a service is always in --bg mode. If --bg is explicitly set t o false, an error message will
be sent out. The restriction on proxy target being localhost or 127.0.0.1 also applies to services.
When removing proxies, TCP proxies can be removed with type and port flag and off argument. Web proxies
can be removed with type, port, setPath flag and off argument. To align with normal serve, when setPath
is not set, all handler under the hostport will be removed. When flags are not set but off argument was
passed by user, it will be a noop. Removing all config for a service will be available later with a new
subcommand clear.
Updates tailscale/corp#22954
Signed-off-by: KevinLiang10 <37811973+KevinLiang10@users.noreply.github.com>
2025-06-04 12:09:46 -04:00
|
|
|
func (sc *ServeConfig) SetWebHandler(st *ipnstate.Status, handler *HTTPHandler, host string, port uint16, mount string, useTLS bool) {
|
2024-03-05 18:46:42 -05:00
|
|
|
if sc == nil {
|
|
|
|
sc = new(ServeConfig)
|
|
|
|
}
|
2025-06-26 13:31:34 -04:00
|
|
|
|
|
|
|
tcpMap := &sc.TCP
|
|
|
|
webServerMap := &sc.Web
|
|
|
|
hostName := host
|
cmd/tailscale/cli: Add service flag to serve command
This commit adds the service flag to serve command which allows serving a service and add the service
to the advertisedServices field in prefs (What advertise command does that will be removed later).
When adding proxies, TCP proxies and WEB proxies work the same way as normal serve, just under a
different DNSname. There is a services specific L3 serving mode called Tun, can be set via --tun flag.
Serving a service is always in --bg mode. If --bg is explicitly set t o false, an error message will
be sent out. The restriction on proxy target being localhost or 127.0.0.1 also applies to services.
When removing proxies, TCP proxies can be removed with type and port flag and off argument. Web proxies
can be removed with type, port, setPath flag and off argument. To align with normal serve, when setPath
is not set, all handler under the hostport will be removed. When flags are not set but off argument was
passed by user, it will be a noop. Removing all config for a service will be available later with a new
subcommand clear.
Updates tailscale/corp#22954
Signed-off-by: KevinLiang10 <37811973+KevinLiang10@users.noreply.github.com>
2025-06-04 12:09:46 -04:00
|
|
|
if IsServiceName(host) {
|
|
|
|
svcName := tailcfg.ServiceName(host)
|
2025-06-26 13:31:34 -04:00
|
|
|
hostName = svcName.WithoutPrefix() + "." + st.CurrentTailnet.MagicDNSSuffix
|
cmd/tailscale/cli: Add service flag to serve command
This commit adds the service flag to serve command which allows serving a service and add the service
to the advertisedServices field in prefs (What advertise command does that will be removed later).
When adding proxies, TCP proxies and WEB proxies work the same way as normal serve, just under a
different DNSname. There is a services specific L3 serving mode called Tun, can be set via --tun flag.
Serving a service is always in --bg mode. If --bg is explicitly set t o false, an error message will
be sent out. The restriction on proxy target being localhost or 127.0.0.1 also applies to services.
When removing proxies, TCP proxies can be removed with type and port flag and off argument. Web proxies
can be removed with type, port, setPath flag and off argument. To align with normal serve, when setPath
is not set, all handler under the hostport will be removed. When flags are not set but off argument was
passed by user, it will be a noop. Removing all config for a service will be available later with a new
subcommand clear.
Updates tailscale/corp#22954
Signed-off-by: KevinLiang10 <37811973+KevinLiang10@users.noreply.github.com>
2025-06-04 12:09:46 -04:00
|
|
|
if _, ok := sc.Services[svcName]; !ok {
|
|
|
|
mak.Set(&sc.Services, svcName, new(ServiceConfig))
|
|
|
|
}
|
2025-06-26 13:31:34 -04:00
|
|
|
tcpMap = &sc.Services[svcName].TCP
|
|
|
|
webServerMap = &sc.Services[svcName].Web
|
|
|
|
}
|
|
|
|
|
|
|
|
mak.Set(tcpMap, port, &TCPPortHandler{HTTPS: useTLS, HTTP: !useTLS})
|
|
|
|
hp := HostPort(net.JoinHostPort(hostName, strconv.Itoa(int(port))))
|
|
|
|
webCfg, ok := (*webServerMap)[hp]
|
|
|
|
if !ok {
|
|
|
|
webCfg = new(WebServerConfig)
|
|
|
|
mak.Set(webServerMap, hp, webCfg)
|
2024-03-05 18:46:42 -05:00
|
|
|
}
|
2025-06-26 13:31:34 -04:00
|
|
|
mak.Set(&webCfg.Handlers, mount, handler)
|
2024-03-05 18:46:42 -05:00
|
|
|
// TODO(tylersmalley): handle multiple web handlers from foreground mode
|
cmd/tailscale/cli: Add service flag to serve command
This commit adds the service flag to serve command which allows serving a service and add the service
to the advertisedServices field in prefs (What advertise command does that will be removed later).
When adding proxies, TCP proxies and WEB proxies work the same way as normal serve, just under a
different DNSname. There is a services specific L3 serving mode called Tun, can be set via --tun flag.
Serving a service is always in --bg mode. If --bg is explicitly set t o false, an error message will
be sent out. The restriction on proxy target being localhost or 127.0.0.1 also applies to services.
When removing proxies, TCP proxies can be removed with type and port flag and off argument. Web proxies
can be removed with type, port, setPath flag and off argument. To align with normal serve, when setPath
is not set, all handler under the hostport will be removed. When flags are not set but off argument was
passed by user, it will be a noop. Removing all config for a service will be available later with a new
subcommand clear.
Updates tailscale/corp#22954
Signed-off-by: KevinLiang10 <37811973+KevinLiang10@users.noreply.github.com>
2025-06-04 12:09:46 -04:00
|
|
|
for k, v := range webCfg.Handlers {
|
2024-03-05 18:46:42 -05:00
|
|
|
if v == handler {
|
|
|
|
continue
|
|
|
|
}
|
|
|
|
// If the new mount point ends in / and another mount point
|
|
|
|
// shares the same prefix, remove the other handler.
|
|
|
|
// (e.g. /foo/ overwrites /foo)
|
|
|
|
// The opposite example is also handled.
|
|
|
|
m1 := strings.TrimSuffix(mount, "/")
|
|
|
|
m2 := strings.TrimSuffix(k, "/")
|
|
|
|
if m1 == m2 {
|
cmd/tailscale/cli: Add service flag to serve command
This commit adds the service flag to serve command which allows serving a service and add the service
to the advertisedServices field in prefs (What advertise command does that will be removed later).
When adding proxies, TCP proxies and WEB proxies work the same way as normal serve, just under a
different DNSname. There is a services specific L3 serving mode called Tun, can be set via --tun flag.
Serving a service is always in --bg mode. If --bg is explicitly set t o false, an error message will
be sent out. The restriction on proxy target being localhost or 127.0.0.1 also applies to services.
When removing proxies, TCP proxies can be removed with type and port flag and off argument. Web proxies
can be removed with type, port, setPath flag and off argument. To align with normal serve, when setPath
is not set, all handler under the hostport will be removed. When flags are not set but off argument was
passed by user, it will be a noop. Removing all config for a service will be available later with a new
subcommand clear.
Updates tailscale/corp#22954
Signed-off-by: KevinLiang10 <37811973+KevinLiang10@users.noreply.github.com>
2025-06-04 12:09:46 -04:00
|
|
|
delete(webCfg.Handlers, k)
|
2024-03-05 18:46:42 -05:00
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
// 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.
|
|
|
|
func (sc *ServeConfig) SetTCPForwarding(port uint16, fwdAddr string, terminateTLS bool, host string) {
|
|
|
|
if sc == nil {
|
|
|
|
sc = new(ServeConfig)
|
|
|
|
}
|
2025-06-26 13:31:34 -04:00
|
|
|
tcpPortHandler := &sc.TCP
|
cmd/tailscale/cli: Add service flag to serve command
This commit adds the service flag to serve command which allows serving a service and add the service
to the advertisedServices field in prefs (What advertise command does that will be removed later).
When adding proxies, TCP proxies and WEB proxies work the same way as normal serve, just under a
different DNSname. There is a services specific L3 serving mode called Tun, can be set via --tun flag.
Serving a service is always in --bg mode. If --bg is explicitly set t o false, an error message will
be sent out. The restriction on proxy target being localhost or 127.0.0.1 also applies to services.
When removing proxies, TCP proxies can be removed with type and port flag and off argument. Web proxies
can be removed with type, port, setPath flag and off argument. To align with normal serve, when setPath
is not set, all handler under the hostport will be removed. When flags are not set but off argument was
passed by user, it will be a noop. Removing all config for a service will be available later with a new
subcommand clear.
Updates tailscale/corp#22954
Signed-off-by: KevinLiang10 <37811973+KevinLiang10@users.noreply.github.com>
2025-06-04 12:09:46 -04:00
|
|
|
if IsServiceName(host) {
|
|
|
|
svcName := tailcfg.ServiceName(host)
|
2025-06-26 13:31:34 -04:00
|
|
|
svcConfig, ok := sc.Services[svcName]
|
|
|
|
if !ok {
|
|
|
|
svcConfig = new(ServiceConfig)
|
|
|
|
mak.Set(&sc.Services, svcName, svcConfig)
|
cmd/tailscale/cli: Add service flag to serve command
This commit adds the service flag to serve command which allows serving a service and add the service
to the advertisedServices field in prefs (What advertise command does that will be removed later).
When adding proxies, TCP proxies and WEB proxies work the same way as normal serve, just under a
different DNSname. There is a services specific L3 serving mode called Tun, can be set via --tun flag.
Serving a service is always in --bg mode. If --bg is explicitly set t o false, an error message will
be sent out. The restriction on proxy target being localhost or 127.0.0.1 also applies to services.
When removing proxies, TCP proxies can be removed with type and port flag and off argument. Web proxies
can be removed with type, port, setPath flag and off argument. To align with normal serve, when setPath
is not set, all handler under the hostport will be removed. When flags are not set but off argument was
passed by user, it will be a noop. Removing all config for a service will be available later with a new
subcommand clear.
Updates tailscale/corp#22954
Signed-off-by: KevinLiang10 <37811973+KevinLiang10@users.noreply.github.com>
2025-06-04 12:09:46 -04:00
|
|
|
}
|
2025-06-26 13:31:34 -04:00
|
|
|
tcpPortHandler = &svcConfig.TCP
|
cmd/tailscale/cli: Add service flag to serve command
This commit adds the service flag to serve command which allows serving a service and add the service
to the advertisedServices field in prefs (What advertise command does that will be removed later).
When adding proxies, TCP proxies and WEB proxies work the same way as normal serve, just under a
different DNSname. There is a services specific L3 serving mode called Tun, can be set via --tun flag.
Serving a service is always in --bg mode. If --bg is explicitly set t o false, an error message will
be sent out. The restriction on proxy target being localhost or 127.0.0.1 also applies to services.
When removing proxies, TCP proxies can be removed with type and port flag and off argument. Web proxies
can be removed with type, port, setPath flag and off argument. To align with normal serve, when setPath
is not set, all handler under the hostport will be removed. When flags are not set but off argument was
passed by user, it will be a noop. Removing all config for a service will be available later with a new
subcommand clear.
Updates tailscale/corp#22954
Signed-off-by: KevinLiang10 <37811973+KevinLiang10@users.noreply.github.com>
2025-06-04 12:09:46 -04:00
|
|
|
}
|
2025-06-26 13:31:34 -04:00
|
|
|
mak.Set(tcpPortHandler, port, &TCPPortHandler{TCPForward: fwdAddr})
|
|
|
|
|
2024-03-05 18:46:42 -05:00
|
|
|
if terminateTLS {
|
2025-06-26 13:31:34 -04:00
|
|
|
(*tcpPortHandler)[port].TerminateTLS = host
|
2024-03-05 18:46:42 -05:00
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
// SetFunnel sets the sc.AllowFunnel value for the given host and port.
|
|
|
|
func (sc *ServeConfig) SetFunnel(host string, port uint16, setOn bool) {
|
|
|
|
if sc == nil {
|
|
|
|
sc = new(ServeConfig)
|
|
|
|
}
|
|
|
|
hp := HostPort(net.JoinHostPort(host, strconv.Itoa(int(port))))
|
|
|
|
|
|
|
|
// TODO(tylersmalley): should ensure there is no other conflicting funnel
|
|
|
|
// TODO(tylersmalley): add error handling for if toggling for existing sc
|
|
|
|
if setOn {
|
|
|
|
mak.Set(&sc.AllowFunnel, hp, true)
|
|
|
|
} else if _, exists := sc.AllowFunnel[hp]; exists {
|
|
|
|
delete(sc.AllowFunnel, hp)
|
|
|
|
// Clear map mostly for testing.
|
|
|
|
if len(sc.AllowFunnel) == 0 {
|
|
|
|
sc.AllowFunnel = nil
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
// RemoveWebHandler deletes the web handlers at all of the given mount points
|
cmd/tailscale/cli: Add service flag to serve command
This commit adds the service flag to serve command which allows serving a service and add the service
to the advertisedServices field in prefs (What advertise command does that will be removed later).
When adding proxies, TCP proxies and WEB proxies work the same way as normal serve, just under a
different DNSname. There is a services specific L3 serving mode called Tun, can be set via --tun flag.
Serving a service is always in --bg mode. If --bg is explicitly set t o false, an error message will
be sent out. The restriction on proxy target being localhost or 127.0.0.1 also applies to services.
When removing proxies, TCP proxies can be removed with type and port flag and off argument. Web proxies
can be removed with type, port, setPath flag and off argument. To align with normal serve, when setPath
is not set, all handler under the hostport will be removed. When flags are not set but off argument was
passed by user, it will be a noop. Removing all config for a service will be available later with a new
subcommand clear.
Updates tailscale/corp#22954
Signed-off-by: KevinLiang10 <37811973+KevinLiang10@users.noreply.github.com>
2025-06-04 12:09:46 -04:00
|
|
|
// for the provided host and port in the serve config for node. If cleanupFunnel is
|
2024-03-05 18:46:42 -05:00
|
|
|
// true, this also removes the funnel value for this port if no handlers remain.
|
|
|
|
func (sc *ServeConfig) RemoveWebHandler(host string, port uint16, mounts []string, cleanupFunnel bool) {
|
|
|
|
hp := HostPort(net.JoinHostPort(host, strconv.Itoa(int(port))))
|
|
|
|
|
|
|
|
// Delete existing handler, then cascade delete if empty.
|
|
|
|
for _, m := range mounts {
|
|
|
|
delete(sc.Web[hp].Handlers, m)
|
|
|
|
}
|
|
|
|
if len(sc.Web[hp].Handlers) == 0 {
|
|
|
|
delete(sc.Web, hp)
|
|
|
|
delete(sc.TCP, port)
|
|
|
|
if cleanupFunnel {
|
|
|
|
delete(sc.AllowFunnel, hp) // disable funnel if no mounts remain for the port
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
// Clear empty maps, mostly for testing.
|
|
|
|
if len(sc.Web) == 0 {
|
|
|
|
sc.Web = nil
|
|
|
|
}
|
|
|
|
if len(sc.TCP) == 0 {
|
|
|
|
sc.TCP = nil
|
|
|
|
}
|
|
|
|
if len(sc.AllowFunnel) == 0 {
|
|
|
|
sc.AllowFunnel = nil
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
cmd/tailscale/cli: Add service flag to serve command
This commit adds the service flag to serve command which allows serving a service and add the service
to the advertisedServices field in prefs (What advertise command does that will be removed later).
When adding proxies, TCP proxies and WEB proxies work the same way as normal serve, just under a
different DNSname. There is a services specific L3 serving mode called Tun, can be set via --tun flag.
Serving a service is always in --bg mode. If --bg is explicitly set t o false, an error message will
be sent out. The restriction on proxy target being localhost or 127.0.0.1 also applies to services.
When removing proxies, TCP proxies can be removed with type and port flag and off argument. Web proxies
can be removed with type, port, setPath flag and off argument. To align with normal serve, when setPath
is not set, all handler under the hostport will be removed. When flags are not set but off argument was
passed by user, it will be a noop. Removing all config for a service will be available later with a new
subcommand clear.
Updates tailscale/corp#22954
Signed-off-by: KevinLiang10 <37811973+KevinLiang10@users.noreply.github.com>
2025-06-04 12:09:46 -04:00
|
|
|
// RemoveServiceWebHandler deletes the web handlers at all of the given mount points
|
|
|
|
// for the provided host and port in the serve config for the given service.
|
|
|
|
func (sc *ServeConfig) RemoveServiceWebHandler(st *ipnstate.Status, svcName tailcfg.ServiceName, port uint16, mounts []string) {
|
|
|
|
dnsNameForService := svcName.WithoutPrefix() + "." + st.CurrentTailnet.MagicDNSSuffix
|
|
|
|
hp := HostPort(net.JoinHostPort(dnsNameForService, strconv.Itoa(int(port))))
|
|
|
|
|
|
|
|
svc, ok := sc.Services[svcName]
|
|
|
|
if !ok || svc == nil {
|
|
|
|
return
|
|
|
|
}
|
|
|
|
|
|
|
|
// Delete existing handler, then cascade delete if empty.
|
|
|
|
for _, m := range mounts {
|
|
|
|
delete(svc.Web[hp].Handlers, m)
|
|
|
|
}
|
|
|
|
if len(svc.Web[hp].Handlers) == 0 {
|
|
|
|
delete(svc.Web, hp)
|
|
|
|
delete(svc.TCP, port)
|
|
|
|
}
|
|
|
|
if len(svc.Web) == 0 && len(svc.TCP) == 0 {
|
|
|
|
delete(sc.Services, svcName)
|
|
|
|
}
|
|
|
|
if len(sc.Services) == 0 {
|
|
|
|
sc.Services = nil
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2024-03-05 18:46:42 -05:00
|
|
|
// RemoveTCPForwarding deletes the TCP forwarding configuration for the given
|
|
|
|
// port from the serve config.
|
cmd/tailscale/cli: Add service flag to serve command
This commit adds the service flag to serve command which allows serving a service and add the service
to the advertisedServices field in prefs (What advertise command does that will be removed later).
When adding proxies, TCP proxies and WEB proxies work the same way as normal serve, just under a
different DNSname. There is a services specific L3 serving mode called Tun, can be set via --tun flag.
Serving a service is always in --bg mode. If --bg is explicitly set t o false, an error message will
be sent out. The restriction on proxy target being localhost or 127.0.0.1 also applies to services.
When removing proxies, TCP proxies can be removed with type and port flag and off argument. Web proxies
can be removed with type, port, setPath flag and off argument. To align with normal serve, when setPath
is not set, all handler under the hostport will be removed. When flags are not set but off argument was
passed by user, it will be a noop. Removing all config for a service will be available later with a new
subcommand clear.
Updates tailscale/corp#22954
Signed-off-by: KevinLiang10 <37811973+KevinLiang10@users.noreply.github.com>
2025-06-04 12:09:46 -04:00
|
|
|
func (sc *ServeConfig) RemoveTCPForwarding(dnsName string, port uint16) {
|
|
|
|
if IsServiceName(dnsName) {
|
|
|
|
if svc, ok := sc.Services[tailcfg.ServiceName(dnsName)]; ok && svc != nil {
|
|
|
|
delete(svc.TCP, port)
|
|
|
|
if len(svc.TCP) == 0 {
|
|
|
|
svc.TCP = nil
|
|
|
|
}
|
|
|
|
if len(svc.Web) == 0 && len(svc.TCP) == 0 {
|
|
|
|
delete(sc.Services, tailcfg.ServiceName(dnsName))
|
|
|
|
}
|
|
|
|
if len(sc.Services) == 0 {
|
|
|
|
sc.Services = nil
|
|
|
|
}
|
|
|
|
}
|
|
|
|
return
|
|
|
|
}
|
2024-03-05 18:46:42 -05:00
|
|
|
delete(sc.TCP, port)
|
|
|
|
if len(sc.TCP) == 0 {
|
|
|
|
sc.TCP = nil
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2023-06-21 12:32:20 -04:00
|
|
|
// IsFunnelOn reports whether if ServeConfig is currently allowing funnel
|
|
|
|
// traffic for any host:port.
|
2023-04-04 22:20:27 -04:00
|
|
|
//
|
|
|
|
// View version of ServeConfig.IsFunnelOn.
|
|
|
|
func (v ServeConfigView) IsFunnelOn() bool { return v.ж.IsFunnelOn() }
|
|
|
|
|
2025-01-19 19:00:21 +00:00
|
|
|
// IsFunnelOn reports whether any funnel endpoint is currently enabled for this node.
|
2022-12-07 22:17:40 -05:00
|
|
|
func (sc *ServeConfig) IsFunnelOn() bool {
|
|
|
|
if sc == nil {
|
|
|
|
return false
|
|
|
|
}
|
|
|
|
for _, b := range sc.AllowFunnel {
|
|
|
|
if b {
|
|
|
|
return true
|
|
|
|
}
|
|
|
|
}
|
2025-01-19 19:00:21 +00:00
|
|
|
for _, conf := range sc.Foreground {
|
|
|
|
if conf.IsFunnelOn() {
|
|
|
|
return true
|
|
|
|
}
|
|
|
|
}
|
2022-12-07 22:17:40 -05:00
|
|
|
return false
|
2022-11-19 09:42:14 -05:00
|
|
|
}
|
2023-03-10 11:44:28 -08:00
|
|
|
|
2023-03-11 08:45:40 -08:00
|
|
|
// CheckFunnelAccess checks whether Funnel access is allowed for the given node
|
|
|
|
// and port.
|
|
|
|
// It checks:
|
2024-03-05 13:54:37 -05:00
|
|
|
// 1. HTTPS is enabled on the tailnet
|
2023-08-09 10:06:58 -04:00
|
|
|
// 2. the node has the "funnel" nodeAttr
|
|
|
|
// 3. the port is allowed for Funnel
|
2023-03-10 11:44:28 -08:00
|
|
|
//
|
2023-09-27 23:01:09 -07:00
|
|
|
// The node arg should be the ipnstate.Status.Self node.
|
|
|
|
func CheckFunnelAccess(port uint16, node *ipnstate.PeerStatus) error {
|
2024-03-05 13:54:37 -05:00
|
|
|
if err := NodeCanFunnel(node); err != nil {
|
|
|
|
return err
|
|
|
|
}
|
|
|
|
return CheckFunnelPort(port, node)
|
|
|
|
}
|
|
|
|
|
|
|
|
// NodeCanFunnel returns an error if the given node is not configured to allow
|
|
|
|
// for Tailscale Funnel usage.
|
|
|
|
func NodeCanFunnel(node *ipnstate.PeerStatus) error {
|
2023-09-27 23:01:09 -07:00
|
|
|
if !node.HasCap(tailcfg.CapabilityHTTPS) {
|
2023-03-13 12:33:16 -07:00
|
|
|
return errors.New("Funnel not available; HTTPS must be enabled. See https://tailscale.com/s/https.")
|
2023-03-10 11:44:28 -08:00
|
|
|
}
|
2023-09-27 23:01:09 -07:00
|
|
|
if !node.HasCap(tailcfg.NodeAttrFunnel) {
|
2023-03-13 12:33:16 -07:00
|
|
|
return errors.New("Funnel not available; \"funnel\" node attribute not set. See https://tailscale.com/s/no-funnel.")
|
2023-03-10 11:44:28 -08:00
|
|
|
}
|
2024-03-05 13:54:37 -05:00
|
|
|
return nil
|
2023-03-11 08:45:40 -08:00
|
|
|
}
|
|
|
|
|
2023-08-09 10:06:58 -04:00
|
|
|
// CheckFunnelPort checks whether the given port is allowed for Funnel.
|
2023-03-11 08:45:40 -08:00
|
|
|
// It uses the tailcfg.CapabilityFunnelPorts nodeAttr to determine the allowed
|
|
|
|
// ports.
|
2023-09-27 23:01:09 -07:00
|
|
|
func CheckFunnelPort(wantedPort uint16, node *ipnstate.PeerStatus) error {
|
2023-03-11 08:45:40 -08:00
|
|
|
deny := func(allowedPorts string) error {
|
|
|
|
if allowedPorts == "" {
|
|
|
|
return fmt.Errorf("port %d is not allowed for funnel", wantedPort)
|
|
|
|
}
|
|
|
|
return fmt.Errorf("port %d is not allowed for funnel; allowed ports are: %v", wantedPort, allowedPorts)
|
|
|
|
}
|
|
|
|
var portsStr string
|
2023-09-27 23:01:09 -07:00
|
|
|
parseAttr := func(attr string) (string, error) {
|
2023-03-11 08:45:40 -08:00
|
|
|
u, err := url.Parse(attr)
|
|
|
|
if err != nil {
|
2023-09-27 23:01:09 -07:00
|
|
|
return "", deny("")
|
2023-03-11 08:45:40 -08:00
|
|
|
}
|
2023-09-27 23:01:09 -07:00
|
|
|
portsStr := u.Query().Get("ports")
|
2023-03-11 08:45:40 -08:00
|
|
|
if portsStr == "" {
|
2023-09-27 23:01:09 -07:00
|
|
|
return "", deny("")
|
2023-03-11 08:45:40 -08:00
|
|
|
}
|
|
|
|
u.RawQuery = ""
|
2023-09-06 10:17:25 -07:00
|
|
|
if u.String() != string(tailcfg.CapabilityFunnelPorts) {
|
2023-09-27 23:01:09 -07:00
|
|
|
return "", deny("")
|
|
|
|
}
|
|
|
|
return portsStr, nil
|
|
|
|
}
|
|
|
|
for attr := range node.CapMap {
|
|
|
|
attr := string(attr)
|
|
|
|
if !strings.HasPrefix(attr, string(tailcfg.CapabilityFunnelPorts)) {
|
|
|
|
continue
|
|
|
|
}
|
|
|
|
var err error
|
|
|
|
portsStr, err = parseAttr(attr)
|
|
|
|
if err != nil {
|
|
|
|
return err
|
|
|
|
}
|
|
|
|
break
|
|
|
|
}
|
|
|
|
if portsStr == "" {
|
2024-03-23 16:23:59 -07:00
|
|
|
for attr := range node.CapMap {
|
2023-09-27 23:01:09 -07:00
|
|
|
attr := string(attr)
|
|
|
|
if !strings.HasPrefix(attr, string(tailcfg.CapabilityFunnelPorts)) {
|
|
|
|
continue
|
|
|
|
}
|
|
|
|
var err error
|
|
|
|
portsStr, err = parseAttr(attr)
|
|
|
|
if err != nil {
|
|
|
|
return err
|
|
|
|
}
|
|
|
|
break
|
2023-03-11 08:45:40 -08:00
|
|
|
}
|
|
|
|
}
|
2023-09-27 23:01:09 -07:00
|
|
|
if portsStr == "" {
|
|
|
|
return deny("")
|
|
|
|
}
|
2023-03-11 08:45:40 -08:00
|
|
|
wantedPortString := strconv.Itoa(int(wantedPort))
|
|
|
|
for _, ps := range strings.Split(portsStr, ",") {
|
|
|
|
if ps == "" {
|
|
|
|
continue
|
|
|
|
}
|
|
|
|
first, last, ok := strings.Cut(ps, "-")
|
|
|
|
if !ok {
|
|
|
|
if first == wantedPortString {
|
|
|
|
return nil
|
|
|
|
}
|
|
|
|
continue
|
|
|
|
}
|
|
|
|
fp, err := strconv.ParseUint(first, 10, 16)
|
|
|
|
if err != nil {
|
|
|
|
continue
|
|
|
|
}
|
|
|
|
lp, err := strconv.ParseUint(last, 10, 16)
|
|
|
|
if err != nil {
|
|
|
|
continue
|
|
|
|
}
|
|
|
|
pr := tailcfg.PortRange{First: uint16(fp), Last: uint16(lp)}
|
|
|
|
if pr.Contains(wantedPort) {
|
|
|
|
return nil
|
|
|
|
}
|
|
|
|
}
|
|
|
|
return deny(portsStr)
|
2023-03-10 11:44:28 -08:00
|
|
|
}
|
2023-09-05 13:51:52 -04:00
|
|
|
|
2024-03-05 13:54:37 -05:00
|
|
|
// ExpandProxyTargetValue expands the supported target values to be proxied
|
|
|
|
// allowing for input values to be a port number, a partial URL, or a full URL
|
|
|
|
// including a path.
|
|
|
|
//
|
|
|
|
// examples:
|
|
|
|
// - 3000
|
|
|
|
// - localhost:3000
|
|
|
|
// - tcp://localhost:3000
|
|
|
|
// - http://localhost:3000
|
|
|
|
// - https://localhost:3000
|
|
|
|
// - https-insecure://localhost:3000
|
|
|
|
// - https-insecure://localhost:3000/foo
|
|
|
|
func ExpandProxyTargetValue(target string, supportedSchemes []string, defaultScheme string) (string, error) {
|
|
|
|
const host = "127.0.0.1"
|
|
|
|
|
|
|
|
// support target being a port number
|
|
|
|
if port, err := strconv.ParseUint(target, 10, 16); err == nil {
|
|
|
|
return fmt.Sprintf("%s://%s:%d", defaultScheme, host, port), nil
|
|
|
|
}
|
|
|
|
|
|
|
|
// prepend scheme if not present
|
|
|
|
if !strings.Contains(target, "://") {
|
|
|
|
target = defaultScheme + "://" + target
|
|
|
|
}
|
|
|
|
|
|
|
|
// make sure we can parse the target
|
|
|
|
u, err := url.ParseRequestURI(target)
|
|
|
|
if err != nil {
|
|
|
|
return "", fmt.Errorf("invalid URL %w", err)
|
|
|
|
}
|
|
|
|
|
|
|
|
// ensure a supported scheme
|
|
|
|
if !slices.Contains(supportedSchemes, u.Scheme) {
|
|
|
|
return "", fmt.Errorf("must be a URL starting with one of the supported schemes: %v", supportedSchemes)
|
|
|
|
}
|
|
|
|
|
|
|
|
// validate the host.
|
|
|
|
switch u.Hostname() {
|
|
|
|
case "localhost", "127.0.0.1":
|
|
|
|
default:
|
|
|
|
return "", errors.New("only localhost or 127.0.0.1 proxies are currently supported")
|
|
|
|
}
|
|
|
|
|
|
|
|
// validate the port
|
|
|
|
port, err := strconv.ParseUint(u.Port(), 10, 16)
|
|
|
|
if err != nil || port == 0 {
|
|
|
|
return "", fmt.Errorf("invalid port %q", u.Port())
|
|
|
|
}
|
|
|
|
|
2024-05-20 17:38:08 -07:00
|
|
|
u.Host = fmt.Sprintf("%s:%d", u.Hostname(), port)
|
2024-03-05 13:54:37 -05:00
|
|
|
|
|
|
|
return u.String(), nil
|
|
|
|
}
|
|
|
|
|
2025-01-04 13:46:09 -08:00
|
|
|
// TCPs returns an iterator over both background and foreground TCP
|
|
|
|
// listeners.
|
|
|
|
//
|
|
|
|
// The key is the port number.
|
|
|
|
func (v ServeConfigView) TCPs() iter.Seq2[uint16, TCPPortHandlerView] {
|
|
|
|
return func(yield func(uint16, TCPPortHandlerView) bool) {
|
|
|
|
for k, v := range v.TCP().All() {
|
|
|
|
if !yield(k, v) {
|
2025-01-04 11:50:48 -08:00
|
|
|
return
|
|
|
|
}
|
|
|
|
}
|
2025-01-04 13:46:09 -08:00
|
|
|
for _, conf := range v.Foreground().All() {
|
|
|
|
for k, v := range conf.TCP().All() {
|
|
|
|
if !yield(k, v) {
|
|
|
|
return
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
2025-01-04 11:50:48 -08:00
|
|
|
}
|
2023-09-05 13:51:52 -04:00
|
|
|
}
|
|
|
|
|
2025-01-04 13:46:09 -08:00
|
|
|
// Webs returns an iterator over both background and foreground Web configurations.
|
|
|
|
func (v ServeConfigView) Webs() iter.Seq2[HostPort, WebServerConfigView] {
|
|
|
|
return func(yield func(HostPort, WebServerConfigView) bool) {
|
|
|
|
for k, v := range v.Web().All() {
|
|
|
|
if !yield(k, v) {
|
2025-01-04 11:50:48 -08:00
|
|
|
return
|
|
|
|
}
|
2023-09-05 13:51:52 -04:00
|
|
|
}
|
2025-01-04 13:46:09 -08:00
|
|
|
for _, conf := range v.Foreground().All() {
|
|
|
|
for k, v := range conf.Web().All() {
|
|
|
|
if !yield(k, v) {
|
|
|
|
return
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
2025-01-20 12:02:53 -05:00
|
|
|
for _, service := range v.Services().All() {
|
|
|
|
for k, v := range service.Web().All() {
|
|
|
|
if !yield(k, v) {
|
|
|
|
return
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
// FindServiceTCP return the TCPPortHandlerView for the given service name and port.
|
2025-01-21 17:07:34 -05:00
|
|
|
func (v ServeConfigView) FindServiceTCP(svcName tailcfg.ServiceName, port uint16) (res TCPPortHandlerView, ok bool) {
|
2025-01-20 12:02:53 -05:00
|
|
|
svcCfg, ok := v.Services().GetOk(svcName)
|
|
|
|
if !ok {
|
|
|
|
return res, ok
|
2025-01-04 11:50:48 -08:00
|
|
|
}
|
2025-01-20 12:02:53 -05:00
|
|
|
return svcCfg.TCP().GetOk(port)
|
|
|
|
}
|
|
|
|
|
2025-01-21 17:07:34 -05:00
|
|
|
func (v ServeConfigView) FindServiceWeb(svcName tailcfg.ServiceName, hp HostPort) (res WebServerConfigView, ok bool) {
|
2025-01-22 09:24:49 -05:00
|
|
|
if svcCfg, ok := v.Services().GetOk(svcName); ok {
|
|
|
|
if res, ok := svcCfg.Web().GetOk(hp); ok {
|
2025-01-20 12:02:53 -05:00
|
|
|
return res, ok
|
|
|
|
}
|
|
|
|
}
|
|
|
|
return res, ok
|
2023-09-05 13:51:52 -04:00
|
|
|
}
|
|
|
|
|
|
|
|
// FindTCP returns the first TCP that matches with the given port. It
|
|
|
|
// prefers a foreground match first followed by a background search if none
|
|
|
|
// existed.
|
|
|
|
func (v ServeConfigView) FindTCP(port uint16) (res TCPPortHandlerView, ok bool) {
|
2025-01-04 11:50:48 -08:00
|
|
|
for _, conf := range v.Foreground().All() {
|
|
|
|
if res, ok := conf.TCP().GetOk(port); ok {
|
|
|
|
return res, ok
|
|
|
|
}
|
2023-09-05 13:51:52 -04:00
|
|
|
}
|
|
|
|
return v.TCP().GetOk(port)
|
|
|
|
}
|
|
|
|
|
|
|
|
// FindWeb returns the first Web that matches with the given HostPort. It
|
|
|
|
// prefers a foreground match first followed by a background search if none
|
|
|
|
// existed.
|
|
|
|
func (v ServeConfigView) FindWeb(hp HostPort) (res WebServerConfigView, ok bool) {
|
2025-01-04 11:50:48 -08:00
|
|
|
for _, conf := range v.Foreground().All() {
|
|
|
|
if res, ok := conf.Web().GetOk(hp); ok {
|
|
|
|
return res, ok
|
|
|
|
}
|
2023-09-05 13:51:52 -04:00
|
|
|
}
|
|
|
|
return v.Web().GetOk(hp)
|
|
|
|
}
|
|
|
|
|
|
|
|
// HasAllowFunnel returns whether this config has at least one AllowFunnel
|
|
|
|
// set in the background or foreground configs.
|
|
|
|
func (v ServeConfigView) HasAllowFunnel() bool {
|
2025-01-04 11:50:48 -08:00
|
|
|
if v.AllowFunnel().Len() > 0 {
|
|
|
|
return true
|
|
|
|
}
|
|
|
|
for _, conf := range v.Foreground().All() {
|
|
|
|
if conf.AllowFunnel().Len() > 0 {
|
|
|
|
return true
|
|
|
|
}
|
|
|
|
}
|
|
|
|
return false
|
2023-09-05 13:51:52 -04:00
|
|
|
}
|
|
|
|
|
2024-05-29 14:11:00 -07:00
|
|
|
// FindFunnel reports whether target exists in either the background AllowFunnel
|
2023-09-05 13:51:52 -04:00
|
|
|
// or any of the foreground configs.
|
|
|
|
func (v ServeConfigView) HasFunnelForTarget(target HostPort) bool {
|
|
|
|
if v.AllowFunnel().Get(target) {
|
|
|
|
return true
|
|
|
|
}
|
2025-01-04 11:50:48 -08:00
|
|
|
for _, conf := range v.Foreground().All() {
|
|
|
|
if conf.AllowFunnel().Get(target) {
|
|
|
|
return true
|
2023-09-05 13:51:52 -04:00
|
|
|
}
|
2025-01-04 11:50:48 -08:00
|
|
|
}
|
|
|
|
return false
|
2023-09-05 13:51:52 -04:00
|
|
|
}
|
2025-01-06 11:27:11 -05:00
|
|
|
|
2025-01-20 12:02:53 -05:00
|
|
|
// CheckValidServicesConfig reports whether the ServeConfig has
|
|
|
|
// invalid service configurations.
|
|
|
|
func (sc *ServeConfig) CheckValidServicesConfig() error {
|
|
|
|
for svcName, service := range sc.Services {
|
|
|
|
if err := service.checkValidConfig(); err != nil {
|
|
|
|
return fmt.Errorf("invalid service configuration for %q: %w", svcName, err)
|
|
|
|
}
|
|
|
|
}
|
|
|
|
return nil
|
|
|
|
}
|
|
|
|
|
2025-01-06 11:27:11 -05:00
|
|
|
// ServicePortRange returns the list of tailcfg.ProtoPortRange that represents
|
|
|
|
// the proto/ports pairs that are being served by the service.
|
|
|
|
//
|
|
|
|
// Right now Tun mode is the only thing supports UDP, otherwise serve only supports TCP.
|
|
|
|
func (v ServiceConfigView) ServicePortRange() []tailcfg.ProtoPortRange {
|
|
|
|
if v.Tun() {
|
|
|
|
// If the service is in Tun mode, means service accept TCP/UDP on all ports.
|
|
|
|
return []tailcfg.ProtoPortRange{{Ports: tailcfg.PortRangeAny}}
|
|
|
|
}
|
|
|
|
tcp := int(ipproto.TCP)
|
|
|
|
|
|
|
|
// Deduplicate the ports.
|
|
|
|
servePorts := make(set.Set[uint16])
|
|
|
|
for port := range v.TCP().All() {
|
|
|
|
if port > 0 {
|
|
|
|
servePorts.Add(uint16(port))
|
|
|
|
}
|
|
|
|
}
|
|
|
|
dedupedServePorts := servePorts.Slice()
|
|
|
|
slices.Sort(dedupedServePorts)
|
|
|
|
|
|
|
|
var ranges []tailcfg.ProtoPortRange
|
|
|
|
for _, p := range dedupedServePorts {
|
|
|
|
if n := len(ranges); n > 0 && p == ranges[n-1].Ports.Last+1 {
|
|
|
|
ranges[n-1].Ports.Last = p
|
|
|
|
continue
|
|
|
|
}
|
|
|
|
ranges = append(ranges, tailcfg.ProtoPortRange{
|
|
|
|
Proto: tcp,
|
|
|
|
Ports: tailcfg.PortRange{
|
|
|
|
First: p,
|
|
|
|
Last: p,
|
|
|
|
},
|
|
|
|
})
|
|
|
|
}
|
|
|
|
return ranges
|
|
|
|
}
|
2025-01-20 12:02:53 -05:00
|
|
|
|
|
|
|
// ErrServiceConfigHasBothTCPAndTun signals that a service
|
|
|
|
// in Tun mode cannot also has TCP or Web handlers set.
|
|
|
|
var ErrServiceConfigHasBothTCPAndTun = errors.New("the VIP Service configuration can not set TUN at the same time as TCP or Web")
|
|
|
|
|
|
|
|
// checkValidConfig checks if the service configuration is valid.
|
|
|
|
// Currently, the only invalid configuration is when the service is in Tun mode
|
|
|
|
// and has TCP or Web handlers.
|
|
|
|
func (v *ServiceConfig) checkValidConfig() error {
|
|
|
|
if v.Tun && (len(v.TCP) > 0 || len(v.Web) > 0) {
|
|
|
|
return ErrServiceConfigHasBothTCPAndTun
|
|
|
|
}
|
|
|
|
return nil
|
|
|
|
}
|