mirror of
https://github.com/tailscale/tailscale.git
synced 2025-08-23 11:27:29 +00:00
wgengine/netstack: add an SSH server experiment
Disabled by default. To use, run tailscaled with: TS_SSH_ALLOW_LOGIN=you@bar.com And enable with: $ TAILSCALE_USE_WIP_CODE=true tailscale up --ssh=true Then ssh [any-user]@[your-tailscale-ip] for a root bash shell. (both the "root" and "bash" part are temporary) Updates #3802 Change-Id: I268f8c3c95c8eed5f3231d712a5dc89615a406f0 Signed-off-by: Brad Fitzpatrick <bradfitz@tailscale.com>
This commit is contained in:

committed by
Brad Fitzpatrick

parent
41fd4eab5c
commit
f3c0023add
@@ -24,6 +24,7 @@ import (
|
||||
qrcode "github.com/skip2/go-qrcode"
|
||||
"inet.af/netaddr"
|
||||
"tailscale.com/client/tailscale"
|
||||
"tailscale.com/envknob"
|
||||
"tailscale.com/ipn"
|
||||
"tailscale.com/ipn/ipnstate"
|
||||
"tailscale.com/safesocket"
|
||||
@@ -81,6 +82,8 @@ func acceptRouteDefault(goos string) bool {
|
||||
|
||||
var upFlagSet = newUpFlagSet(effectiveGOOS(), &upArgs)
|
||||
|
||||
func inTest() bool { return flag.Lookup("test.v") != nil }
|
||||
|
||||
func newUpFlagSet(goos string, upArgs *upArgsT) *flag.FlagSet {
|
||||
upf := newFlagSet("up")
|
||||
|
||||
@@ -96,6 +99,9 @@ func newUpFlagSet(goos string, upArgs *upArgsT) *flag.FlagSet {
|
||||
upf.StringVar(&upArgs.exitNodeIP, "exit-node", "", "Tailscale exit node (IP or base name) for internet traffic, or empty string to not use an exit node")
|
||||
upf.BoolVar(&upArgs.exitNodeAllowLANAccess, "exit-node-allow-lan-access", false, "Allow direct access to the local network when routing traffic via an exit node")
|
||||
upf.BoolVar(&upArgs.shieldsUp, "shields-up", false, "don't allow incoming connections")
|
||||
if envknob.UseWIPCode() || inTest() {
|
||||
upf.BoolVar(&upArgs.runSSH, "ssh", false, "run an SSH server, permitting access per tailnet admin's declared policy")
|
||||
}
|
||||
upf.StringVar(&upArgs.advertiseTags, "advertise-tags", "", "comma-separated ACL tags to request; each must start with \"tag:\" (e.g. \"tag:eng,tag:montreal,tag:ssh\")")
|
||||
upf.StringVar(&upArgs.authKeyOrFile, "authkey", "", `node authorization key; if it begins with "file:", then it's a path to a file containing the authkey`)
|
||||
upf.StringVar(&upArgs.hostname, "hostname", "", "hostname to use instead of the one provided by the OS")
|
||||
@@ -131,6 +137,7 @@ type upArgsT struct {
|
||||
exitNodeIP string
|
||||
exitNodeAllowLANAccess bool
|
||||
shieldsUp bool
|
||||
runSSH bool
|
||||
forceReauth bool
|
||||
forceDaemon bool
|
||||
advertiseRoutes string
|
||||
@@ -352,6 +359,7 @@ func prefsFromUpArgs(upArgs upArgsT, warnf logger.Logf, st *ipnstate.Status, goo
|
||||
prefs.CorpDNS = upArgs.acceptDNS
|
||||
prefs.AllowSingleHosts = upArgs.singleRoutes
|
||||
prefs.ShieldsUp = upArgs.shieldsUp
|
||||
prefs.RunSSH = upArgs.runSSH
|
||||
prefs.AdvertiseRoutes = routes
|
||||
prefs.AdvertiseTags = tags
|
||||
prefs.Hostname = upArgs.hostname
|
||||
@@ -712,6 +720,7 @@ func init() {
|
||||
addPrefFlagMapping("exit-node-allow-lan-access", "ExitNodeAllowLANAccess")
|
||||
addPrefFlagMapping("unattended", "ForceDaemon")
|
||||
addPrefFlagMapping("operator", "OperatorUser")
|
||||
addPrefFlagMapping("ssh", "RunSSH")
|
||||
}
|
||||
|
||||
func addPrefFlagMapping(flagName string, prefNames ...string) {
|
||||
@@ -902,6 +911,8 @@ func prefsToFlags(env upCheckEnv, prefs *ipn.Prefs) (flagVal map[string]interfac
|
||||
switch f.Name {
|
||||
default:
|
||||
panic(fmt.Sprintf("unhandled flag %q", f.Name))
|
||||
case "ssh":
|
||||
set(prefs.RunSSH)
|
||||
case "login-server":
|
||||
set(prefs.ControlURL)
|
||||
case "accept-routes":
|
||||
|
@@ -3,6 +3,7 @@ tailscale.com/cmd/tailscaled dependencies: (generated by github.com/tailscale/de
|
||||
W 💣 github.com/alexbrainman/sspi from github.com/alexbrainman/sspi/internal/common+
|
||||
W github.com/alexbrainman/sspi/internal/common from github.com/alexbrainman/sspi/negotiate
|
||||
W 💣 github.com/alexbrainman/sspi/negotiate from tailscale.com/net/tshttpproxy
|
||||
L github.com/anmitsu/go-shlex from github.com/gliderlabs/ssh
|
||||
L github.com/aws/aws-sdk-go-v2 from github.com/aws/aws-sdk-go-v2/internal/ini
|
||||
L github.com/aws/aws-sdk-go-v2/aws from github.com/aws/aws-sdk-go-v2/aws/middleware+
|
||||
L github.com/aws/aws-sdk-go-v2/aws/arn from tailscale.com/ipn/store/aws
|
||||
@@ -60,6 +61,8 @@ tailscale.com/cmd/tailscaled dependencies: (generated by github.com/tailscale/de
|
||||
L github.com/aws/smithy-go/transport/http/internal/io from github.com/aws/smithy-go/transport/http
|
||||
L github.com/aws/smithy-go/waiter from github.com/aws/aws-sdk-go-v2/service/ssm
|
||||
L github.com/coreos/go-iptables/iptables from tailscale.com/wgengine/router
|
||||
L 💣 github.com/creack/pty from tailscale.com/wgengine/netstack
|
||||
L github.com/gliderlabs/ssh from tailscale.com/wgengine/netstack
|
||||
W 💣 github.com/go-ole/go-ole from github.com/go-ole/go-ole/oleutil+
|
||||
W 💣 github.com/go-ole/go-ole/oleutil from tailscale.com/wgengine/winnet
|
||||
L 💣 github.com/godbus/dbus/v5 from tailscale.com/net/dns
|
||||
@@ -256,7 +259,7 @@ tailscale.com/cmd/tailscaled dependencies: (generated by github.com/tailscale/de
|
||||
tailscale.com/wgengine/filter from tailscale.com/control/controlclient+
|
||||
tailscale.com/wgengine/magicsock from tailscale.com/wgengine+
|
||||
tailscale.com/wgengine/monitor from tailscale.com/cmd/tailscaled+
|
||||
tailscale.com/wgengine/netstack from tailscale.com/cmd/tailscaled
|
||||
💣 tailscale.com/wgengine/netstack from tailscale.com/cmd/tailscaled
|
||||
tailscale.com/wgengine/router from tailscale.com/cmd/tailscaled+
|
||||
tailscale.com/wgengine/wgcfg from tailscale.com/ipn/ipnlocal+
|
||||
tailscale.com/wgengine/wgcfg/nmcfg from tailscale.com/ipn/ipnlocal
|
||||
@@ -265,16 +268,19 @@ tailscale.com/cmd/tailscaled dependencies: (generated by github.com/tailscale/de
|
||||
golang.org/x/crypto/acme from tailscale.com/ipn/localapi
|
||||
golang.org/x/crypto/blake2b from golang.org/x/crypto/nacl/box
|
||||
golang.org/x/crypto/blake2s from golang.zx2c4.com/wireguard/device
|
||||
golang.org/x/crypto/chacha20 from golang.org/x/crypto/chacha20poly1305
|
||||
L golang.org/x/crypto/blowfish from golang.org/x/crypto/ssh/internal/bcrypt_pbkdf
|
||||
golang.org/x/crypto/chacha20 from golang.org/x/crypto/chacha20poly1305+
|
||||
golang.org/x/crypto/chacha20poly1305 from crypto/tls+
|
||||
golang.org/x/crypto/cryptobyte from crypto/ecdsa+
|
||||
golang.org/x/crypto/cryptobyte/asn1 from crypto/ecdsa+
|
||||
golang.org/x/crypto/curve25519 from crypto/tls+
|
||||
L golang.org/x/crypto/ed25519 from golang.org/x/crypto/ssh
|
||||
golang.org/x/crypto/hkdf from crypto/tls
|
||||
golang.org/x/crypto/nacl/box from tailscale.com/types/key
|
||||
golang.org/x/crypto/nacl/secretbox from golang.org/x/crypto/nacl/box
|
||||
golang.org/x/crypto/poly1305 from golang.org/x/crypto/chacha20poly1305+
|
||||
golang.org/x/crypto/salsa20/salsa from golang.org/x/crypto/nacl/box+
|
||||
L golang.org/x/crypto/ssh from github.com/gliderlabs/ssh+
|
||||
golang.org/x/net/bpf from github.com/mdlayher/netlink+
|
||||
golang.org/x/net/dns/dnsmessage from net+
|
||||
golang.org/x/net/http/httpguts from net/http+
|
||||
@@ -312,14 +318,14 @@ tailscale.com/cmd/tailscaled dependencies: (generated by github.com/tailscale/de
|
||||
crypto/aes from crypto/ecdsa+
|
||||
crypto/cipher from crypto/aes+
|
||||
crypto/des from crypto/tls+
|
||||
crypto/dsa from crypto/x509
|
||||
crypto/dsa from crypto/x509+
|
||||
crypto/ecdsa from crypto/tls+
|
||||
crypto/ed25519 from crypto/tls+
|
||||
crypto/elliptic from crypto/ecdsa+
|
||||
crypto/hmac from crypto/tls+
|
||||
crypto/md5 from crypto/tls+
|
||||
crypto/rand from crypto/ed25519+
|
||||
crypto/rc4 from crypto/tls
|
||||
crypto/rc4 from crypto/tls+
|
||||
crypto/rsa from crypto/tls+
|
||||
crypto/sha1 from crypto/tls+
|
||||
crypto/sha256 from crypto/tls+
|
||||
|
@@ -329,9 +329,6 @@ func run() error {
|
||||
}
|
||||
ns.ProcessLocalIPs = useNetstack
|
||||
ns.ProcessSubnets = useNetstack || wrapNetstack
|
||||
if err := ns.Start(); err != nil {
|
||||
return fmt.Errorf("failed to start netstack: %w", err)
|
||||
}
|
||||
|
||||
if useNetstack {
|
||||
dialer.UseNetstackForIP = func(ip netaddr.IP) bool {
|
||||
@@ -342,7 +339,6 @@ func run() error {
|
||||
return ns.DialContextTCP(ctx, dst)
|
||||
}
|
||||
}
|
||||
|
||||
if socksListener != nil || httpProxyListener != nil {
|
||||
if httpProxyListener != nil {
|
||||
hs := &http.Server{Handler: httpProxyHandler(dialer.UserDial)}
|
||||
@@ -392,6 +388,10 @@ func run() error {
|
||||
if err != nil {
|
||||
return fmt.Errorf("ipnserver.New: %w", err)
|
||||
}
|
||||
ns.SetLocalBackend(srv.LocalBackend())
|
||||
if err := ns.Start(); err != nil {
|
||||
log.Fatalf("failed to start netstack: %v", err)
|
||||
}
|
||||
|
||||
if debugMux != nil {
|
||||
debugMux.HandleFunc("/debug/ipn", srv.ServeHTMLStatus)
|
||||
|
Reference in New Issue
Block a user