summaryrefslogtreecommitdiffhomepage
path: root/ssh/tailssh
AgeCommit message (Collapse)AuthorFilesLines
2025-02-13ssh/tailssh: accept passwords and public keysPercy Wegmann4-107/+271
Some clients don't request 'none' authentication. Instead, they immediately supply a password or public key. This change allows them to do so, but ignores the supplied credentials and authenticates using Tailscale instead. Updates #14922 Signed-off-by: Percy Wegmann <percy@tailscale.com>
2025-02-11tempfork/sshtest/ssh: add fork of golang.org/x/crypto/ssh for testing onlyBrad Fitzpatrick1-0/+3
This fork golang.org/x/crypto/ssh (at upstream x/crypto git rev e47973b1c1) into tailscale.com/tempfork/sshtest/ssh so we can hack up the client in weird ways to simulate other SSH clients seen in the wild. Two changes were made to the files when they were copied from x/crypto: * internal/poly1305 imports were replaced by the non-internal version; no code changes otherwise. It didn't need the internal one. * all decode-with-passphrase funcs were deleted, to avoid using the internal package x/crypto/ssh/internal/bcrypt_pbkdf Then the tests passed. Updates #14969 Change-Id: Ibf1abebfe608c75fef4da0255314f65e54ce5077 Signed-off-by: Brad Fitzpatrick <bradfitz@tailscale.com>
2025-02-05ssh: don't use -l option for shells on OpenBSDPercy Wegmann1-2/+2
Shells on OpenBSD don't support the -l option. This means that when handling SSH in-process, we can't give the user a login shell, but this change at least allows connecting at all. Updates #13338 Signed-off-by: Percy Wegmann <percy@tailscale.com>
2025-02-05ssh: refactor OS names into constantsPercy Wegmann1-10/+17
Updates #13338 Signed-off-by: Percy Wegmann <percy@tailscale.com>
2025-02-05ssh: don't use -l option for shells on FreeBSDPercy Wegmann1-0/+4
Shells on FreeBSD don't support the -l option. This means that when handling SSH in-process, we can't give the user a login shell, but this change at least allows connecting at all. Updates #13338 Signed-off-by: Percy Wegmann <percy@tailscale.com>
2025-01-31ssh,tempfork/gliderlabs/ssh: replace ↵Percy Wegmann3-187/+130
github.com/tailscale/golang-x-crypto/ssh with golang.org/x/crypto/ssh The upstream crypto package now supports sending banners at any time during authentication, so the Tailscale fork of crypto/ssh is no longer necessary. github.com/tailscale/golang-x-crypto is still needed for some custom ACME autocert functionality. tempfork/gliderlabs is still necessary because of a few other customizations, mostly related to TTY handling. Originally implemented in 46fd4e58a27495263336b86ee961ee28d8c332b7, which was reverted in b60f6b849af1fae1cf343be98f7fb1714c9ea165 to keep the change out of v1.80. Updates #8593 Signed-off-by: Percy Wegmann <percy@tailscale.com>
2025-01-29Revert "ssh,tempfork/gliderlabs/ssh: replace ↵Percy Wegmann3-130/+187
github.com/tailscale/golang-x-crypto/ssh with golang.org/x/crypto/ssh" This reverts commit 46fd4e58a27495263336b86ee961ee28d8c332b7. We don't want to include this in 1.80 yet, but can add it back post 1.80. Updates #8593 Signed-off-by: Percy Wegmann <percy@tailscale.com>
2025-01-28ssh,tempfork/gliderlabs/ssh: replace ↵Percy Wegmann3-187/+130
github.com/tailscale/golang-x-crypto/ssh with golang.org/x/crypto/ssh The upstream crypto package now supports sending banners at any time during authentication, so the Tailscale fork of crypto/ssh is no longer necessary. github.com/tailscale/golang-x-crypto is still needed for some custom ACME autocert functionality. tempfork/gliderlabs is still necessary because of a few other customizations, mostly related to TTY handling. Updates #8593 Signed-off-by: Percy Wegmann <percy@tailscale.com>
2025-01-07all: fix golangci-lint errorsWill Norris1-4/+4
These erroneously blocked a recent PR, which I fixed by simply re-running CI. But we might as well fix them anyway. These are mostly `printf` to `print` and a couple of `!=` to `!Equal()` Updates #cleanup Signed-off-by: Will Norris <will@tailscale.com>
2024-12-12ssh/tailssh: remove unused public key supportBrad Fitzpatrick2-337/+28
When we first made Tailscale SSH, we assumed people would want public key support soon after. Turns out that hasn't been the case; people love the Tailscale identity authentication and check mode. In light of CVE-2024-45337, just remove all our public key code to not distract people, and to make the code smaller. We can always get it back from git if needed. Updates tailscale/corp#25131 Updates golang/go#70779 Co-authored-by: Percy Wegmann <percy@tailscale.com> Change-Id: I87a6e79c2215158766a81942227a18b247333c22 Signed-off-by: Brad Fitzpatrick <bradfitz@tailscale.com>
2024-11-18sessionrecording: implement v2 recording endpoint support (#14105)Andrew Lytvynov2-26/+48
The v2 endpoint supports HTTP/2 bidirectional streaming and acks for received bytes. This is used to detect when a recorder disappears to more quickly terminate the session. Updates https://github.com/tailscale/corp/issues/24023 Signed-off-by: Andrew Lytvynov <awly@tailscale.com>
2024-11-05types/result, util/lineiter: add package for a result type, use itBrad Fitzpatrick2-17/+14
This adds a new generic result type (motivated by golang/go#70084) to try it out, and uses it in the new lineutil package (replacing the old lineread package), changing that package to return iterators: sometimes over []byte (when the input is all in memory), but sometimes iterators over results of []byte, if errors might happen at runtime. Updates #12912 Updates golang/go#70084 Change-Id: Iacdc1070e661b5fb163907b1e8b07ac7d51d3f83 Signed-off-by: Brad Fitzpatrick <bradfitz@tailscale.com>
2024-10-11ssh/tailssh: calculate passthrough environment at latest possible stagePercy Wegmann1-15/+37
This allows passing through any environment variables that we set ourselves, for example DBUS_SESSION_BUS_ADDRESS. Updates #11175 Co-authored-by: Mario Minardi <mario@tailscale.com> Signed-off-by: Percy Wegmann <percy@tailscale.com>
2024-10-03ssh/tailssh: pass window size pixels in IoctlSetWinsize eventsBrad Fitzpatrick1-2/+4
Fixes #13669 Change-Id: Id44cfbb83183f1bbcbdc38c29238287b9d288707 Signed-off-by: Brad Fitzpatrick <bradfitz@tailscale.com>
2024-09-30ssh: Add logic to set accepted environment variables in SSH session (#13559)Mario Minardi6-55/+294
Add logic to set environment variables that match the SSH rule's `acceptEnv` settings in the SSH session's environment. Updates https://github.com/tailscale/corp/issues/22775 Signed-off-by: Mario Minardi <mario@tailscale.com>
2024-09-25ssh/tailssh: add logic for matching against AcceptEnv patterns (#13466)Mario Minardi2-0/+250
Add logic for parsing and matching against our planned format for AcceptEnv values. Namely, this supports direct matches against string values and matching where * and ? are treated as wildcard characters which match against an arbitrary number of characters and a single character respectively. Actually using this logic in non-test code will come in subsequent changes. Updates https://github.com/tailscale/corp/issues/22775 Signed-off-by: Mario Minardi <mario@tailscale.com>
2024-09-25util/usermetrics: make usermetrics non-globalKristoffer Dalby1-1/+1
this commit changes usermetrics to be non-global, this is a building block for correct metrics if a go process runs multiple tsnets or in tests. Updates #13420 Updates tailscale/corp#22075 Signed-off-by: Kristoffer Dalby <kristoffer@tailscale.com>
2024-09-11util/slicesx: add FirstElementEqual and LastElementEqualBrad Fitzpatrick1-1/+2
And update a few callers as examples of motivation. (there are a couple others, but these are the ones where it's prettier) Updates #cleanup Change-Id: Ic8c5cb7af0a59c6e790a599136b591ebe16d38eb Signed-off-by: Brad Fitzpatrick <bradfitz@tailscale.com>
2024-08-29ssh/tailssh: add ability to force V2 behavior using new feature flagPercy Wegmann1-1/+2
Introduces ssh-behavior-v2 node attribute to override ssh-behavior-v1. Updates #11854 Signed-off-by: Percy Wegmann <percy@tailscale.com>
2024-08-22all: fix new lint warnings from bumping staticcheckBrad Fitzpatrick1-0/+1
In prep for updating to new staticcheck required for Go 1.23. Updates #12912 Change-Id: If77892a023b79c6fa798f936fc80428fd4ce0673 Signed-off-by: Brad Fitzpatrick <bradfitz@tailscale.com>
2024-08-21ssh/tailssh: only chdir incubator process to user's homedir when necessary ↵Percy Wegmann4-16/+22
and possible Instead of changing the working directory before launching the incubator process, this now just changes the working directory after dropping privileges, at which point we're more likely to be able to enter the user's home directory since we're running as the user. For paths that use the 'login' or 'su -l' commands, those already take care of changing the working directory to the user's home directory. Fixes #13120 Signed-off-by: Percy Wegmann <percy@tailscale.com>
2024-08-21ssh/tailssh: fix SSH on busybox systemsPercy Wegmann3-36/+55
This involved the following: 1. Pass the su command path as first of args in call to unix.Exec to make sure that busybox sees the correct program name. Busybox is a single executable userspace that implements various core userspace commands in a single binary. You'll see it used via symlinking, so that for example /bin/su symlinks to /bin/busybox. Busybox knows that you're trying to execute /bin/su because argv[0] is '/bin/su'. When we called unix.Exec, we weren't including the program name for argv[0], which caused busybox to fail with 'applet not found', meaning that it didn't know which command it was supposed to run. 2. Tell su to whitelist the SSH_AUTH_SOCK environment variable in order to support ssh agent forwarding. 3. Run integration tests on alpine, which uses busybox. 4. Increment CurrentCapabilityVersion to allow turning on SSH V2 behavior from control. Fixes #12849 Signed-off-by: Percy Wegmann <percy@tailscale.com>
2024-07-29cmd/k8s-operator,k8s-operator/sessionrecording,sessionrecording,ssh/tailssh: ↵Irbe Krumina3-194/+5
refactor session recording functionality (#12945) cmd/k8s-operator,k8s-operator/sessionrecording,sessionrecording,ssh/tailssh: refactor session recording functionality Refactor SSH session recording functionality (mostly the bits related to Kubernetes API server proxy 'kubectl exec' session recording): - move the session recording bits used by both Tailscale SSH and the Kubernetes API server proxy into a shared sessionrecording package, to avoid having the operator to import ssh/tailssh - move the Kubernetes API server proxy session recording functionality into a k8s-operator/sessionrecording package, add some abstractions in preparation for adding support for a second streaming protocol (WebSockets) Updates tailscale/corp#19821 Signed-off-by: Irbe Krumina <irbe@tailscale.com>
2024-07-08cmd/k8s-operator,ssh/tailssh,tsnet: optionally record 'kubectl exec' ↵Irbe Krumina2-125/+137
sessions via Kubernetes operator's API server proxy (#12274) cmd/k8s-operator,ssh/tailssh,tsnet: optionally record kubectl exec sessions The Kubernetes operator's API server proxy, when it receives a request for 'kubectl exec' session now reads 'RecorderAddrs', 'EnforceRecorder' fields from tailcfg.KubernetesCapRule. If 'RecorderAddrs' is set to one or more addresses (of a tsrecorder instance(s)), it attempts to connect to those and sends the session contents to the recorder before forwarding the request to the kube API server. If connection cannot be established or fails midway, it is only allowed if 'EnforceRecorder' is not true (fail open). Updates tailscale/corp#19821 Signed-off-by: Irbe Krumina <irbe@tailscale.com> Co-authored-by: Maisem Ali <maisem@tailscale.com>
2024-06-20ssh/tailssh: fix integration test (#12562)Irbe Krumina1-1/+1
Updates#cleanup Signed-off-by: Irbe Krumina <irbe@tailscale.com>
2024-06-20ssh/tailssh: replace incubator process with su instead of running su as childPercy Wegmann3-49/+177
This allows the SSH_AUTH_SOCK environment variable to work inside of su and agent forwarding to succeed. Fixes #12467 Signed-off-by: Percy Wegmann <percy@tailscale.com>
2024-06-18proxymap, various: distinguish between different protocolsAndrew Dunham2-3/+7
Previously, we were registering TCP and UDP connections in the same map, which could result in erroneously removing a mapping if one of the two connections completes while the other one is still active. Add a "proto string" argument to these functions to avoid this. Additionally, take the "proto" argument in LocalAPI, and plumb that through from the CLI and add a new LocalClient method. Updates tailscale/corp#20600 Signed-off-by: Andrew Dunham <andrew@du.nham.ca> Change-Id: I35d5efaefdfbf4721e315b8ca123f0c8af9125fb
2024-06-12ssh/tailssh: check IsSELinuxEnforcing in tailscaled processPercy Wegmann2-16/+38
Checking in the incubator as this used to do fails because the getenforce command is not on the PATH. Updates #12442 Signed-off-by: Percy Wegmann <percy@tailscale.com>
2024-05-29ssh/tailssh: fall back to using su when no TTY available on LinuxPercy Wegmann5-246/+613
This allows pam authentication to run for ssh sessions, triggering automation like pam_mkhomedir. Updates #11854 Signed-off-by: Percy Wegmann <percy@tailscale.com>
2024-05-03ssh/tailssh: plumb health.Tracker in testBrad Fitzpatrick1-1/+1
In prep for it being required in more places. Updates #11874 Change-Id: Ib743205fc2a6c6ff3d2c4ed3a2b28cac79156539 Signed-off-by: Brad Fitzpatrick <bradfitz@tailscale.com>
2024-05-03ssh/tailssh: use ptr.To in testBrad Fitzpatrick1-3/+2
Updates #cleanup Change-Id: Ic98ba1b63c8205084b30f59f0ca343788edea5b0 Signed-off-by: Brad Fitzpatrick <bradfitz@tailscale.com>
2024-05-01ssh/tailssh: add integration testPercy Wegmann3-1/+430
Updates tailscale/corp#11854 Signed-off-by: Percy Wegmann <percy@tailscale.com>
2024-04-23ssh/tailssh: try fetching group IDs for user with the 'id' commandAndrew Dunham1-8/+2
Since the tailscaled binaries that we distribute are static and don't link cgo, we previously wouldn't fetch group IDs that are returned via NSS. Try shelling out to the 'id' command, similar to how we call 'getent', to detect such cases. Updates #11682 Signed-off-by: Andrew Dunham <andrew@du.nham.ca> Change-Id: I9bdc938bd76c71bc130d44a97cc2233064d64799
2024-04-22ipn/ipnlocal,ssh/tailssh: reject c2n /update if SSH conns are active (#11820)Andrew Lytvynov1-0/+7
Since we already track active SSH connections, it's not hard to proactively reject updates until those finish. We attempt to do the same on the control side, but the detection latency for new connections is in the minutes, which is not fast enough for common short sessions. Handle a `force=true` query parameter to override this behavior, so that control can still trigger an update on a server where some long-running abandoned SSH session is open. Updates https://github.com/tailscale/corp/issues/18556 Signed-off-by: Andrew Lytvynov <awly@tailscale.com>
2024-04-16all: use Go 1.22 range-over-intBrad Fitzpatrick1-1/+1
Updates #11058 Change-Id: I35e7ef9b90e83cac04ca93fd964ad00ed5b48430 Signed-off-by: Brad Fitzpatrick <bradfitz@tailscale.com>
2024-02-08all: use reflect.TypeFor now available in Go 1.22 (#11078)Joe Tsai1-1/+1
Updates #cleanup Signed-off-by: Joe Tsai <joetsai@digital-static.net>
2024-01-05ssh/tailssh: use a local error instead of gossh.ErrDenied (#10743)Andrew Lytvynov1-9/+13
ErrDenied was added in [our fork of x/crypto/ssh](https://github.com/golang/crypto/commit/acc6f8fe8d618cba34d44e89fdde304f98c576df) to short-circuit auth attempts once one fails. In the case of our callbacks, this error is returned when SSH policy check determines that a connection should not be allowed. Both `NoClientAuthCallback` and `PublicKeyHandler` check the policy and will fail anyway. The `fakePasswordHandler` returns true only if `NoClientAuthCallback` succeeds the policy check, so it checks it indirectly too. The difference here is that a client might attempt all 2-3 auth methods instead of just `none` but will fail to authenticate regardless. Updates #8593 Signed-off-by: Andrew Lytvynov <awly@tailscale.com>
2023-12-20all: cleanup unused code, part 1 (#10661)Andrew Lytvynov1-14/+12
Run `staticcheck` with `U1000` to find unused code. This cleans up about a half of it. I'll do the other half separately to keep PRs manageable. Updates #cleanup Signed-off-by: Andrew Lytvynov <awly@tailscale.com>
2023-11-17ssh/tailssh: use control server time instead of local timeOx Cart1-0/+3
This takes advantage of existing functionality in ipn/ipnlocal to adjust the local clock based on periodic time signals from the control server. This way, when checking things like SSHRule expirations, calculations are protected incorrectly set local clocks. Fixes tailscale/corp#15796 Signed-off-by: Percy Wegmann <percy@tailscale.com>
2023-11-09ssh/tailssh: add envknobs to force override forwarding, sftp, ptyBrad Fitzpatrick2-1/+27
Updates tailscale/corp#15735 Change-Id: Ib1303406be925c3231ce7e0950a173ad12626492 Signed-off-by: Brad Fitzpatrick <bradfitz@tailscale.com>
2023-11-09ssh/tailssh: fix sftp metric increment locationBrad Fitzpatrick1-2/+4
We were incrementing the sftp metric on regular sessions too, not just sftp. Updates #cleanup Change-Id: I63027a39cffb3e03397c6e4829b1620c10fa3130 Signed-off-by: Brad Fitzpatrick <bradfitz@tailscale.com>
2023-11-09ssh/tailssh,util: extract new osuser package from ssh code (#10170)Andrew Lytvynov1-86/+3
This package is a wrapper for os/user that handles non-cgo builds, gokrazy and user shells. Updates tailscale/corp#15405 Signed-off-by: Andrew Lytvynov <awly@tailscale.com>
2023-10-03util/httpm, all: add a test to make sure httpm is used consistentlyBrad Fitzpatrick1-1/+2
Updates #cleanup Change-Id: I7dbf8a02de22fc6b317ab5e29cc97792dd75352c Signed-off-by: Brad Fitzpatrick <bradfitz@tailscale.com>
2023-09-07ssh/tailssh: log when recording starts and finishes (#9294)Joe Tsai1-0/+2
Updates tailscale/corp#14579 Signed-off-by: Joe Tsai <joetsai@digital-static.net>
2023-08-23all: replace deprecated ioutil referencesMarwan Sulaiman1-2/+1
This PR removes calls to ioutil library and replaces them with their new locations in the io and os packages. Fixes #9034 Updates #5210 Signed-off-by: Marwan Sulaiman <marwan@tailscale.com>
2023-08-21types/netmap, all: make NetworkMap.SelfNode a tailcfg.NodeViewBrad Fitzpatrick2-3/+3
Updates #1909 Change-Id: I8c470cbc147129a652c1d58eac9b790691b87606 Signed-off-by: Brad Fitzpatrick <bradfitz@tailscale.com>
2023-08-18types/netmap, all: use read-only tailcfg.NodeView in NetworkMapBrad Fitzpatrick3-15/+15
Updates #8948 Signed-off-by: Brad Fitzpatrick <bradfitz@tailscale.com>
2023-08-17all: use Go 1.21 slices, maps instead of x/exp/{slices,maps}Brad Fitzpatrick2-2/+2
Updates #8419 Signed-off-by: Brad Fitzpatrick <bradfitz@tailscale.com>
2023-08-15ssh/tailssh: fix gokrazy SSH crashBrad Fitzpatrick1-6/+8
Stupid mistake in earlier refactor. Updates gokrazy/gokrazy#209 Signed-off-by: Brad Fitzpatrick <bradfitz@tailscale.com>
2023-07-21ssh: ignore io.EOF from sftp.Server.ServeJoe Tsai1-1/+6
If the connection provided to sftp.NewServer is closed, Serve returns the io.EOF error verbatim from io.Reader.Read. This is an odd error since this is an expected situation, so we manually ignore io.EOF. This is somewhat buggy since the sftp package itself incorrectly reports io.EOF in cases where it should actually be reporting io.ErrUnexpectedEOF. See https://github.com/pkg/sftp/pull/554 which patches Serve to return nil on clean closes and fixes buggy uses of io.ReadFull. Fixes #8592 Signed-off-by: Joe Tsai <joetsai@digital-static.net>