summaryrefslogtreecommitdiffhomepage
path: root/ssh/tailssh/tailssh.go
AgeCommit message (Collapse)AuthorFilesLines
2025-06-03ssh/tailssh: display more useful error messages when authentication failsPercy Wegmann1-20/+39
Also add a trailing newline to error banners so that SSH client messages don't print on the same line. Updates tailscale/corp#29138 Signed-off-by: Percy Wegmann <percy@tailscale.com>
2025-05-22ssh/tailssh: exclude Android from Linux build tagsBrad Fitzpatrick1-1/+1
As noted in #16048, the ./ssh/tailssh package failed to build on Android, because GOOS=android also matches the "linux" build tag. Exclude Android like iOS is excluded from macOS (darwin). This now works: $ GOOS=android go install ./ipn/ipnlocal ./ssh/tailssh The original PR at #16048 is also fine, but this stops the problem earlier. Updates #16048 Change-Id: Ie4a6f6966a012e510c9cb11dd0d1fa88c48fac37 Signed-off-by: Brad Fitzpatrick <bradfitz@tailscale.com>
2025-04-02ssh/tailssh: add Plan 9 support for Tailscale SSHBrad Fitzpatrick1-2/+2
Updates #5794 Change-Id: I7b05cd29ec02085cb503bbcd0beb61bf455002ac Signed-off-by: Brad Fitzpatrick <bradfitz@tailscale.com>
2025-02-13ssh/tailssh: accept passwords and public keysPercy Wegmann1-26/+72
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-01-31ssh,tempfork/gliderlabs/ssh: replace ↵Percy Wegmann1-184/+126
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 Wegmann1-126/+184
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 Wegmann1-184/+126
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>
2024-12-12ssh/tailssh: remove unused public key supportBrad Fitzpatrick1-251/+26
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 Lytvynov1-4/+9
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-09-30ssh: Add logic to set accepted environment variables in SSH session (#13559)Mario Minardi1-21/+23
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-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-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-07-29cmd/k8s-operator,k8s-operator/sessionrecording,sessionrecording,ssh/tailssh: ↵Irbe Krumina1-57/+3
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 Krumina1-125/+1
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-18proxymap, various: distinguish between different protocolsAndrew Dunham1-2/+2
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-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-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 Fitzpatrick1-1/+21
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-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-21types/netmap, all: make NetworkMap.SelfNode a tailcfg.NodeViewBrad Fitzpatrick1-1/+1
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 Fitzpatrick1-9/+9
Updates #8948 Signed-off-by: Brad Fitzpatrick <bradfitz@tailscale.com>
2023-06-21ssh/tailssh: fix double race condition with non-pty command (#8405)Joe Tsai1-18/+40
There are two race conditions in output handling. The first race condition is due to a misuse of exec.Cmd.StdoutPipe. The documentation explicitly forbids concurrent use of StdoutPipe with exec.Cmd.Wait (see golang/go#60908) because Wait will close both sides of the pipe once the process ends without any guarantees that all data has been read from the pipe. To fix this, we allocate the os.Pipes ourselves and manage cleanup ourselves when the process has ended. The second race condition is because sshSession.run waits upon exec.Cmd to finish and then immediately proceeds to call ss.Exit, which will close all output streams going to the SSH client. This may interrupt any asynchronous io.Copy still copying data. To fix this, we close the write-side of the os.Pipes after the process has finished (and before calling ss.Exit) and synchronously wait for the io.Copy routines to finish. Fixes #7601 Signed-off-by: Joe Tsai <joetsai@digital-static.net> Co-authored-by: Maisem Ali <maisem@tailscale.com>
2023-06-09ssh/tailssh: add support for remote/reverse port forwardingMaisem Ali1-3/+20
This basically allows running services on the SSH client and reaching them from the SSH server during the session. Updates #6575 Signed-off-by: Maisem Ali <maisem@tailscale.com>
2023-05-22ssh/tailssh: add ssh session recording failed event typeCharlotte Brandhorst-Satzkorn1-2/+11
This change introduces a SSHSessionRecordingFailed event type that is used when a session recording fails to start or fails during a session, and the on failure indicates that it should fail open. Updates tailscale/corp#9967 Signed-off-by: Charlotte Brandhorst-Satzkorn <charlotte@tailscale.com>
2023-05-18ssh/tailssh: close tty on session closeMaisem Ali1-2/+13
We were only closing on side of the pty/tty pair. Close the other side too. Thanks to @fritterhoff for reporting and debugging the issue! Fixes #8119 Signed-off-by: Maisem Ali <maisem@tailscale.com>
2023-05-08ssh/tailssh: support LDAP users for Tailscale SSHBrad Fitzpatrick1-14/+3
Fixes #4945 Change-Id: Ie013cb47684cb87928a44f92c66352310bfe53f1 Signed-off-by: Brad Fitzpatrick <bradfitz@tailscale.com>
2023-05-05ssh/tailssh,tailcfg: add connID to ssheventnotifyrequest and castheaderCharlotte Brandhorst-Satzkorn1-13/+16
This change adds a ConnectionID field to both SSHEventNotifyRequest and CastHeader that identifies the ID of a connection to the SSH server. Updates tailscale/corp#9967 Signed-off-by: Charlotte Brandhorst-Satzkorn <charlotte@tailscale.com>
2023-05-05ssh/tailssh: send ssh event notifications on recording failuresCharlotte Brandhorst-Satzkorn1-10/+86
This change sends an SSHEventNotificationRequest over noise when a SSH session is set to fail closed and the session is unable to start because a recorder is not available or a session is terminated because connection to the recorder is ended. Each of these scenarios have their own event type. Updates tailscale/corp#9967 Signed-off-by: Charlotte Brandhorst-Satzkorn <charlotte@tailscale.com>
2023-05-03ssh/tailssh: restore support for recording locallyMaisem Ali1-32/+64
We removed it earlier in 916aa782af5d43ccfa92f6245201796df212fb8a, but we still want to support it for some time longer. Updates tailscale/corp#9967 Signed-off-by: Maisem Ali <maisem@tailscale.com>
2023-05-01ssh/tailssh: improve debug logging around revoked sessionsTom DNetto1-0/+11
Updates https://github.com/tailscale/corp/issues/10943 Signed-off-by: Tom DNetto <tom@tailscale.com>
2023-04-25ssh/tailssh: also handle recording upload failure during writesMaisem Ali1-15/+30
Previously we would error out when the recording server disappeared after the in memory buffer filled up for the io.Copy. This makes it so that we handle failing open correctly in that path. Updates tailscale/corp#9967 Signed-off-by: Maisem Ali <maisem@tailscale.com>
2023-04-22ssh/tailssh: handle dialing multiple recorders and failing openMaisem Ali1-64/+143
This adds support to try dialing out to multiple recorders each with a 5s timeout and an overall 30s timeout. It also starts respecting the actions `OnRecordingFailure` field if set, if it is not set it fails open. Updates tailscale/corp#9967 Signed-off-by: Maisem Ali <maisem@tailscale.com>
2023-04-17various: add golangci-lint, fix issues (#7905)Andrew Dunham1-2/+2
This adds an initial and intentionally minimal configuration for golang-ci, fixes the issues reported, and adds a GitHub Action to check new pull requests against this linter configuration. Signed-off-by: Andrew Dunham <andrew@du.nham.ca> Change-Id: I8f38fbc315836a19a094d0d3e986758b9313f163
2023-04-04ssh/tailssh: make Tailscale SSH work on gokrazyBrad Fitzpatrick1-0/+11
Signed-off-by: Brad Fitzpatrick <bradfitz@tailscale.com>
2023-03-28ssh/tailssh: fix race in errors returned when starting recorderMaisem Ali1-2/+13
There were two code paths that could fail depending on how fast the recorder responses. This fixes that by returning the correct error from both paths. Fixes #7707 Signed-off-by: Maisem Ali <maisem@tailscale.com>
2023-03-25ssh/tailssh: add tests for recording failureMaisem Ali1-3/+25
Updates tailscale/corp#9967 Signed-off-by: Maisem Ali <maisem@tailscale.com>
2023-03-23ssh/tailssh: handle session recording when running in userspace modeMaisem Ali1-3/+26
Previously it would dial out using the http.DefaultClient, however that doesn't work when tailscaled is running in userspace mode (e.g. when testing). Updates tailscale/corp#9967 Signed-off-by: Maisem Ali <maisem@tailscale.com>
2023-03-23ssh/tailssh: enable recording of non-pty sessionsMaisem Ali1-4/+1
Updates tailscale/corp#9967 Signed-off-by: Maisem Ali <maisem@tailscale.com>
2023-03-23ssh/tailssh: add docs to CastHeader fieldsMaisem Ali1-18/+51
Updates tailscale/corp#9967 Signed-off-by: Maisem Ali <maisem@tailscale.com>
2023-03-23ssh/tailssh: use background context for uploading recordingsMaisem Ali1-1/+6
Otherwise we see errors like ``` ssh-session(sess-20230322T005655-5562985593): recording: error sending recording to <addr>:80: Post "http://<addr>:80/record": context canceled ``` The ss.ctx is closed when the session closes, but we don't want to break the upload at that time. Instead we want to wait for the session to close the writer when it finishes, which it is already doing. Updates tailscale/corp#9967 Signed-off-by: Maisem Ali <maisem@tailscale.com>
2023-03-21ssh/tailssh: allow recorders to be configured on the first or final actionMaisem Ali1-4/+16
Currently we only send down recorders in first action, allow the final action to replace them but not to drop them. Updates tailscale/corp#9967 Signed-off-by: Maisem Ali <maisem@tailscale.com>
2023-03-21ssh/tailssh: add more metadata to recording headerMaisem Ali1-7/+18
Updates tailscale/corp#9967 Signed-off-by: Maisem Ali <maisem@tailscale.com>
2023-03-21ssh/tailssh: stream SSH recordings to configured recordersMaisem Ali1-31/+50
Updates tailscale/corp#9967 Signed-off-by: Maisem Ali <maisem@tailscale.com>
2023-03-09ssh/tailssh: use context.WithCancelCauseMaisem Ali1-12/+31
It was using a custom implmentation of the context.WithCancelCause, replace usage with stdlib. Signed-off-by: Maisem Ali <maisem@tailscale.com>
2023-01-27all: update copyright and license headersWill Norris1-3/+2
This updates all source files to use a new standard header for copyright and license declaration. Notably, copyright no longer includes a date, and we now use the standard SPDX-License-Identifier header. This commit was done almost entirely mechanically with perl, and then some minimal manual fixes. Updates #6865 Signed-off-by: Will Norris <will@tailscale.com>
2023-01-09ssh/tailssh: add OpenBSD support for Tailscale SSHBrad Fitzpatrick1-1/+1
And bump go.mod for https://github.com/u-root/u-root/pull/2593 Change-Id: I36ec94c5b2b76d671cb739f1e9a1a43ca1d9d1b1 Signed-off-by: Brad Fitzpatrick <bradfitz@tailscale.com>