ipn: [serve] warn that foreground funnel won't work if shields are up (#14685)
Some checks are pending
checklocks / checklocks (push) Waiting to run
CodeQL / Analyze (go) (push) Waiting to run
Dockerfile build / deploy (push) Waiting to run
CI / race-root-integration (1/4) (push) Waiting to run
CI / race-root-integration (2/4) (push) Waiting to run
CI / race-root-integration (3/4) (push) Waiting to run
CI / race-root-integration (4/4) (push) Waiting to run
CI / test (-coverprofile=/tmp/coverage.out, amd64) (push) Waiting to run
CI / test (-race, amd64, 1/3) (push) Waiting to run
CI / test (-race, amd64, 2/3) (push) Waiting to run
CI / test (-race, amd64, 3/3) (push) Waiting to run
CI / test (386) (push) Waiting to run
CI / windows (push) Waiting to run
CI / privileged (push) Waiting to run
CI / vm (push) Waiting to run
CI / race-build (push) Waiting to run
CI / cross (386, linux) (push) Waiting to run
CI / cross (amd64, darwin) (push) Waiting to run
CI / cross (amd64, freebsd) (push) Waiting to run
CI / cross (amd64, openbsd) (push) Waiting to run
CI / cross (amd64, windows) (push) Waiting to run
CI / cross (arm, 5, linux) (push) Waiting to run
CI / cross (arm, 7, linux) (push) Waiting to run
CI / cross (arm64, darwin) (push) Waiting to run
CI / cross (arm64, linux) (push) Waiting to run
CI / cross (arm64, windows) (push) Waiting to run
CI / cross (loong64, linux) (push) Waiting to run
CI / ios (push) Waiting to run
CI / crossmin (amd64, illumos) (push) Waiting to run
CI / crossmin (amd64, plan9) (push) Waiting to run
CI / crossmin (amd64, solaris) (push) Waiting to run
CI / crossmin (ppc64, aix) (push) Waiting to run
CI / android (push) Waiting to run
CI / wasm (push) Waiting to run
CI / tailscale_go (push) Waiting to run
CI / fuzz (push) Waiting to run
CI / depaware (push) Waiting to run
CI / go_generate (push) Waiting to run
CI / go_mod_tidy (push) Waiting to run
CI / licenses (push) Waiting to run
CI / staticcheck (386, windows) (push) Waiting to run
CI / staticcheck (amd64, darwin) (push) Waiting to run
CI / staticcheck (amd64, linux) (push) Waiting to run
CI / staticcheck (amd64, windows) (push) Waiting to run
CI / notify_slack (push) Blocked by required conditions
CI / check_mergeability (push) Blocked by required conditions
Some checks are pending
checklocks / checklocks (push) Waiting to run
CodeQL / Analyze (go) (push) Waiting to run
Dockerfile build / deploy (push) Waiting to run
CI / race-root-integration (1/4) (push) Waiting to run
CI / race-root-integration (2/4) (push) Waiting to run
CI / race-root-integration (3/4) (push) Waiting to run
CI / race-root-integration (4/4) (push) Waiting to run
CI / test (-coverprofile=/tmp/coverage.out, amd64) (push) Waiting to run
CI / test (-race, amd64, 1/3) (push) Waiting to run
CI / test (-race, amd64, 2/3) (push) Waiting to run
CI / test (-race, amd64, 3/3) (push) Waiting to run
CI / test (386) (push) Waiting to run
CI / windows (push) Waiting to run
CI / privileged (push) Waiting to run
CI / vm (push) Waiting to run
CI / race-build (push) Waiting to run
CI / cross (386, linux) (push) Waiting to run
CI / cross (amd64, darwin) (push) Waiting to run
CI / cross (amd64, freebsd) (push) Waiting to run
CI / cross (amd64, openbsd) (push) Waiting to run
CI / cross (amd64, windows) (push) Waiting to run
CI / cross (arm, 5, linux) (push) Waiting to run
CI / cross (arm, 7, linux) (push) Waiting to run
CI / cross (arm64, darwin) (push) Waiting to run
CI / cross (arm64, linux) (push) Waiting to run
CI / cross (arm64, windows) (push) Waiting to run
CI / cross (loong64, linux) (push) Waiting to run
CI / ios (push) Waiting to run
CI / crossmin (amd64, illumos) (push) Waiting to run
CI / crossmin (amd64, plan9) (push) Waiting to run
CI / crossmin (amd64, solaris) (push) Waiting to run
CI / crossmin (ppc64, aix) (push) Waiting to run
CI / android (push) Waiting to run
CI / wasm (push) Waiting to run
CI / tailscale_go (push) Waiting to run
CI / fuzz (push) Waiting to run
CI / depaware (push) Waiting to run
CI / go_generate (push) Waiting to run
CI / go_mod_tidy (push) Waiting to run
CI / licenses (push) Waiting to run
CI / staticcheck (386, windows) (push) Waiting to run
CI / staticcheck (amd64, darwin) (push) Waiting to run
CI / staticcheck (amd64, linux) (push) Waiting to run
CI / staticcheck (amd64, windows) (push) Waiting to run
CI / notify_slack (push) Blocked by required conditions
CI / check_mergeability (push) Blocked by required conditions
We throw error early with a warning if users attempt to enable background funnel for a node that does not allow incoming connections (shields up), but if it done in foreground mode, we just silently fail (the funnel command succeeds, but the connections are not allowed). This change makes sure that we also error early in foreground mode. Updates tailscale/tailscale#11049 Signed-off-by: Irbe Krumina <irbe@tailscale.com>
This commit is contained in:
parent
c79b736a85
commit
6c30840cac
20
ipn/serve.go
20
ipn/serve.go
@ -63,12 +63,12 @@ type ServeConfig struct {
|
|||||||
// traffic is allowed, from trusted ingress peers.
|
// traffic is allowed, from trusted ingress peers.
|
||||||
AllowFunnel map[HostPort]bool `json:",omitempty"`
|
AllowFunnel map[HostPort]bool `json:",omitempty"`
|
||||||
|
|
||||||
// Foreground is a map of an IPN Bus session ID to an alternate foreground
|
// Foreground is a map of an IPN Bus session ID to an alternate foreground serve config that's valid for the
|
||||||
// serve config that's valid for the life of that WatchIPNBus session ID.
|
// life of that WatchIPNBus session ID. This allows the config to specify ephemeral configs that are used
|
||||||
// This. This allows the config to specify ephemeral configs that are
|
// in the CLI's foreground mode to ensure ungraceful shutdowns of either the client or the LocalBackend does not
|
||||||
// used in the CLI's foreground mode to ensure ungraceful shutdowns
|
// expose ports that users are not aware of. In practice this contains any serve config set via 'tailscale
|
||||||
// of either the client or the LocalBackend does not expose ports
|
// serve' command run without the '--bg' flag. ServeConfig contained by Foreground is not expected itself to contain
|
||||||
// that users are not aware of.
|
// another Foreground block.
|
||||||
Foreground map[string]*ServeConfig `json:",omitempty"`
|
Foreground map[string]*ServeConfig `json:",omitempty"`
|
||||||
|
|
||||||
// ETag is the checksum of the serve config that's populated
|
// ETag is the checksum of the serve config that's populated
|
||||||
@ -389,8 +389,7 @@ func (sc *ServeConfig) RemoveTCPForwarding(port uint16) {
|
|||||||
// View version of ServeConfig.IsFunnelOn.
|
// View version of ServeConfig.IsFunnelOn.
|
||||||
func (v ServeConfigView) IsFunnelOn() bool { return v.ж.IsFunnelOn() }
|
func (v ServeConfigView) IsFunnelOn() bool { return v.ж.IsFunnelOn() }
|
||||||
|
|
||||||
// IsFunnelOn reports whether if ServeConfig is currently allowing funnel
|
// IsFunnelOn reports whether any funnel endpoint is currently enabled for this node.
|
||||||
// traffic for any host:port.
|
|
||||||
func (sc *ServeConfig) IsFunnelOn() bool {
|
func (sc *ServeConfig) IsFunnelOn() bool {
|
||||||
if sc == nil {
|
if sc == nil {
|
||||||
return false
|
return false
|
||||||
@ -400,6 +399,11 @@ func (sc *ServeConfig) IsFunnelOn() bool {
|
|||||||
return true
|
return true
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
for _, conf := range sc.Foreground {
|
||||||
|
if conf.IsFunnelOn() {
|
||||||
|
return true
|
||||||
|
}
|
||||||
|
}
|
||||||
return false
|
return false
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -182,3 +182,88 @@ func TestExpandProxyTargetDev(t *testing.T) {
|
|||||||
})
|
})
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func TestIsFunnelOn(t *testing.T) {
|
||||||
|
tests := []struct {
|
||||||
|
name string
|
||||||
|
sc *ServeConfig
|
||||||
|
want bool
|
||||||
|
}{
|
||||||
|
{
|
||||||
|
name: "nil_config",
|
||||||
|
},
|
||||||
|
{
|
||||||
|
name: "empty_config",
|
||||||
|
sc: &ServeConfig{},
|
||||||
|
},
|
||||||
|
{
|
||||||
|
name: "funnel_enabled_in_background",
|
||||||
|
sc: &ServeConfig{
|
||||||
|
AllowFunnel: map[HostPort]bool{
|
||||||
|
"tailnet.xyz:443": true,
|
||||||
|
},
|
||||||
|
},
|
||||||
|
want: true,
|
||||||
|
},
|
||||||
|
{
|
||||||
|
name: "funnel_disabled_in_background",
|
||||||
|
sc: &ServeConfig{
|
||||||
|
AllowFunnel: map[HostPort]bool{
|
||||||
|
"tailnet.xyz:443": false,
|
||||||
|
},
|
||||||
|
},
|
||||||
|
},
|
||||||
|
{
|
||||||
|
name: "funnel_enabled_in_foreground",
|
||||||
|
sc: &ServeConfig{
|
||||||
|
Foreground: map[string]*ServeConfig{
|
||||||
|
"abc123": {
|
||||||
|
AllowFunnel: map[HostPort]bool{
|
||||||
|
"tailnet.xyz:443": true,
|
||||||
|
},
|
||||||
|
},
|
||||||
|
},
|
||||||
|
},
|
||||||
|
want: true,
|
||||||
|
},
|
||||||
|
{
|
||||||
|
name: "funnel_disabled_in_both",
|
||||||
|
sc: &ServeConfig{
|
||||||
|
AllowFunnel: map[HostPort]bool{
|
||||||
|
"tailnet.xyz:443": false,
|
||||||
|
},
|
||||||
|
Foreground: map[string]*ServeConfig{
|
||||||
|
"abc123": {
|
||||||
|
AllowFunnel: map[HostPort]bool{
|
||||||
|
"tailnet.xyz:8443": false,
|
||||||
|
},
|
||||||
|
},
|
||||||
|
},
|
||||||
|
},
|
||||||
|
},
|
||||||
|
{
|
||||||
|
name: "funnel_enabled_in_both",
|
||||||
|
sc: &ServeConfig{
|
||||||
|
AllowFunnel: map[HostPort]bool{
|
||||||
|
"tailnet.xyz:443": true,
|
||||||
|
},
|
||||||
|
Foreground: map[string]*ServeConfig{
|
||||||
|
"abc123": {
|
||||||
|
AllowFunnel: map[HostPort]bool{
|
||||||
|
"tailnet.xyz:8443": true,
|
||||||
|
},
|
||||||
|
},
|
||||||
|
},
|
||||||
|
},
|
||||||
|
want: true,
|
||||||
|
},
|
||||||
|
}
|
||||||
|
|
||||||
|
for _, tt := range tests {
|
||||||
|
t.Run(tt.name, func(t *testing.T) {
|
||||||
|
if got := tt.sc.IsFunnelOn(); got != tt.want {
|
||||||
|
t.Errorf("ServeConfig.IsFunnelOn() = %v, want %v", got, tt.want)
|
||||||
|
}
|
||||||
|
})
|
||||||
|
}
|
||||||
|
}
|
||||||
|
Loading…
Reference in New Issue
Block a user