[HN Gopher] Making an SSH client the hard way ___________________________________________________________________ Making an SSH client the hard way Author : darthShadow Score : 138 points Date : 2022-10-27 17:13 UTC (5 hours ago) (HTM) web link (tailscale.com) (TXT) w3m dump (tailscale.com) | heliophobicdude wrote: | Hi Mihai! Great work! I would love to see where this goes! | | Forgive my ignorance but is there any sort of native client | besides the browser running in the background to help with | websocket to tcp? Or a tunnel to a cloud service to help there? | mihaip wrote: | No native client is running. The browser makes a WebSocket | connection to our relay server, and we run the WireGuard tunnel | over that. | Spivak wrote: | > To make this possible, we ported the following to WebAssembly: | the Tailscale client, WireGuard(r), a complete userspace network | stack (from gVisor), and an SSH client. | | I love that they were clearly inspired by fly.io. Warms my heart | that a random blog post with a good idea can spread like this. | bradfitz wrote: | Which blog post are you referring to? | | But yes, we love Fly and use them (and they use us) and we | share a slack channel between our two companies for casual | banter. | vngzs wrote: | This is really cool and fun, but is this a safe way to run SSH | clients? | | If, say, the adblock Chrome extension you're using gets bought by | a malware operator and backdoored[0], now it also has SSH and VPN | access. | | [0]: https://www.wired.co.uk/article/fake-chrome-extensions- | malwa... | Scaevolus wrote: | If you have an actively malwared extension, there's probably an | easier way to exploit any given target-- the simplest being | recording passwords. | | There's not really a "safe" website when the browser is | malicious. | gunapologist99 wrote: | This is turning a remote server into a previously "safe | website" and expanding the threat model to include remote web | browser attacks. | dgentry wrote: | The Tailscale VPN client, the same one which runs on other | devices, is compiled to WASM. It handles all of the key | exchanges to connect to the tailnet. The SSH session is running | as a WASM Tailscale client. | | The browser, opening connections from within the browser | engine, doesn't have the keys for SSH or VPN access. | shp0ngle wrote: | It doesn't have the keys, but it can inject any javascript | and do whatever the user can do. | Spivak wrote: | To me it seems they've taken all precautions they can | reasonably take -- "what if the user installs a keylogger" | isn't fixable by anyone. | gunapologist99 wrote: | "Installing a keylogger" is a _vast_ oversimplification, | even if it is outside of their threat model. | | Installing almost anything in your browser is usually a | matter of a couple of clicks. | Asmod4n wrote: | And then the addon intercepts the loading of the Wasm code, | injects it's own payload into it and has access to the keys. | lxgr wrote: | What keys? I think the implementation does not use regular | SSH keys for SSH authentication, but rather something | custom (I believe traffic to port 22 on each SSH enabled | client is intercepted and the daemon handles authentication | itself). | vngzs wrote: | Sounds like about "as good as this gets" if you happen to | want to do this in browsers. Good job. | ikiris wrote: | citation needed | dekhn wrote: | Most of the products from tailscale just seem to be "look at the | inner platforms we can build that replace the outer platforms". | | Having an SSH client in your browser join your VPN violates all | the principles of modern computing. | [deleted] | xaduha wrote: | From the article | | > Web-based SSH clients aren't new. Nearly every VPS and cloud | provider already lets you connect to your VMs from the web -- | so how is this different? | | This is clearly isn't for everyone, but if you need or already | use something like that, then I think this has a chance to be | more secure than some other options. | dekhn wrote: | I really liked Chrome SSH extension but now I've returned to | using the ssh command line client on all three platforms. | | The issue is wiring up the browser-hosted application with a | custom network inside the browser. It's a truly interesting | but highly disruptive concept and I'm curious how it will | play out. Perhaps in the future every program will statically | compile its own TCP stack and talk over RAW sockets, but... | that's sort of throwing away everything BSD and Linux and | Windows achieved over the last few decades in terms of OS | abstractions. | bradfitz wrote: | > Having an SSH client in your browser join your VPN violates | all the principles of modern computing. | | I think that's a compliment? You're welcome? :) | convolvatron wrote: | absolutely. the lines weren't bad, but they were off in | places and now they are set in stone for no good reason. | | edit: _especially_ when it comes to security | dekhn wrote: | It's not a compliment. Or rather, within my understanding of | how things should be architected, it's not. I certainly | wouldn't claim that my own beliefs about network architecture | should trump others, and I work in a different domain from | most of the people with your use case. Whether the disruptive | work you're doing is good for the world in the long run is | still a very open question in my mind. | | I used to think that everything in the world should move to | the browser (in my case, that would be high performance | molecular graphics and microscope control) and ChromeOS was | the logical extension. Web Assembly to handle the existing | C++ codebases, a collection of standard web tech to handle | the user interface. Big fan of SSH extension because it meant | that machines that only ran a browser could be useful command | line programming terminals. But didn't like that SSH | extension was written in a dead-end container technology | (NaCl) and the CHrome folks sort of messed up multiple ways | for the extension to integrate better. | | But after working with web tech for enough time I came to | conclude that putting things in the browser like this is an | antipattern, in particular increasing the surface complexity | of the software space while not actually replacing existing | systems (openssh continues to exist, OS-level VPNs continue | to exist, even after you port the VPN and client to web | assembly and run it in a browser). | | In my mental model, it makes more sense to put the browser in | a VM and then wire the VM's networking to a VPN handled by | the OS, rather than putting what is more or less a | significant fraction of a virtual machine manager's | capabilities into the browser. If you're going to do that, | why not go whole-hog and add a VM to chrome so that it can | run linux with a full networking stack and then host an SSH | client inside that? So you can run linux in your chrome in | your linux. | | My compliment is: I am impressed at how well you parlayed | several technical projects into a thought leadership | position, but we have fundamentally different architectural | principles and work in different domains. Your work disrupts | mine, but mine doesn't disrupt yours. My enterprise actually | disallows me from visiting your company's website on my work | computer because users installing their own VPNs is | considered a security risk (fwiw, I bought into BeyondCorp, | which eschews VPNs, a long time ago, and would prefer my | enterprise eliminate VPNs, as they don't really protect our | users). | qbasic_forever wrote: | How does a VM or sandboxing help anything? The whole point | of wireguard is to get the (shitty) OS VPN out of the | picture entirely. | | Give me a stream of bytes and let the whole world see it | for all I care--wireguard will build a secure private | network entirely on that stream of bytes. It could be | totally public coffee shop wifi with zero encryption | (basically yelling your passwords and secrets out in the | open) and yet wireguard will make it secure and private for | me. | | So in this case who cares if its a websocket to the browser | vs a 'proper' (bloated, shitty) OS VPN. Give me a stream of | bytes and I'll build my own secure and trusted network on | it thank you very much. | dekhn wrote: | The VM encapsulates the OS component for networking and | networking virtualization. In my experience, the | virtualized software stack in the VM host is very | reliable and predictable, and all the existing OS tools I | need as a sysadmin (like tshark, ip, and other commands) | all work just fine for debugging. | | I understand the desire for moving more TCP logic to | applications but, given my experience with network | technology, I would predict that ten years from now, | people will hate the experience of having to update 30 | apps to get 1 fix to TCP performance that would have just | been a kernel upgrade. IE, like everything that happened | with the web and inner platforms, it's more work, doesn't | replace the existing system, and just makes the admin's | life harder for the ostensible purpose of being more | convenient for the developer on their own machine. | 0xbadcafebee wrote: | SSH in the web browser is actually the best practice today. | Here are some examples of why SSH in your browser actually | _compliments_ modern computing: | | - An SSO-authenticated web interface, integrated with a | host agent on your instances, means you don't have to | manage SSH keys. | | - If you just need a disposable CLI that inherits | permissions from your SSO-authenticated user role, you can | do that from a disposable box in a web interface after | authenticating via the web interface. Google Cloud Shell is | a good example. | | - Cloud-native development is easier if developers can just | start working on a unified environment, without having to | set up & maintain a local environment. Utilizing the web | browser avoids the need to consider separate tools and | separate methods of network connection. | | - SSH'ing to "private" instances is impossible without | going through a bastion or VPN. The bastion then becomes a | single point of attack, and is hard to maintain and secure. | Similarly the VPN is an additional attack vector, | maintenance headache, and requires client-side software, | configuration, troubleshooting. Instead of deploying a | bunch of bastions or setting up a VPN, if you can use the | backend control plane through an SSO-authenticated API | gateway, along with a backend proxy to internal networks, | you can avoid bastions altogether. This is the best | practice for Zero-Trust. Google Cloud IAP Proxy is a good | example. | | The implementation of it, with | WebAssembly/WebSockets/WireGuard/DERP, may be lamentable | for several reasons. But it probably (I assume?) solves | problems that other SSH Web Interfaces didn't. I hate that | the web browser has monopolized computing interfaces :) But | in this case it seems to solve many problems. | dekhn wrote: | I'm fine with ssh in a browser. I used Chrome SSH | Extension for many years to connect to a VM running tmux. | And I use RDP if I truly need a remote desktop. However, | it (browser SSH) not a replacement for, it's an | augmentation of, the OS-level ssh client. | | Turning this around. Let's take the idea of using WASM to | put a full environment in the user's browser. This is a | logical idea, after all- WASM exists to make it possible | to write applications in Not-Javascript and deploy them | in a browser. IE, don't stop with SSH: you should have a | web server, a shell, multiprocessing, scripting | languages, everything necessary to host VSCode server and | a self-hosted compilation toolchain in a browser. Full | linux user space in a browser, enough to compile ChromeOS | and boot into a browser running linux | | What have you achieved? A very expensive (in terms of | porting cost, CPU usage, and deployment size) inner | platform that does what an OS does already. But it's | inside the browser, with a patched version of code | (because WASM always trails native apps), with each sub- | application maybe linking in its own TCP stack. So it | will always trail innovations in desktops, since it's not | a full replacement for the existing system. So it makes | the world more complicated and exposes more surface areas | for security management. | asdfasdfasdfass wrote: | EvanAnderson wrote: | Talking about inner platforms (and in case there's one | person left who hasn't seen it): | https://www.destroyallsoftware.com/talks/the-birth-and- | death... | dekhn wrote: | https://en.wikipedia.org/wiki/Inner-platform_effect | | """The inner-platform effect is the tendency of software | architects to create a system so customizable as to | become a replica, and often a poor replica, of the | software development platform they are using. This is | generally inefficient and such systems are often | considered to be examples of an anti-pattern.""" | | Like I said elsewhere, I'm not completely opposed to the | idea of the browser as a complete and fully functional | application container for an inner platform. And I want | to encourage creative people to try new technologies, | especially WASM to explore the idea of "how much can we | move to the browser". However, I see the container as the | mediator of the network, not the application. | apenwarr wrote: | (I'm a tailscale cofounder) I think of Tailscale more like | a set of tools that lets you do any architecture you want. | Nobody has to use Tailscale ssh console, but if you believe | in the future of wasm -> apps -> web console -> ssh, now | you can have it. | | On the other hand, if you believe in the future of OS | private network connectivity -> console -> ssh, then you | had that already with native Tailscale and Tailscale ssh. | | If you believe in OS private network connectivity -> | browser -> javascript console -> ssh, then you can do that | too, by installing tailscale in the native OS and then the | browser can use it. | | I actually agree with you, I'm very suspicious about a | world where we just move everything into the web browser. | But on the other hand, sometimes it's really handy to have | that option. | dekhn wrote: | Hi Avery. I think we may have chatted when I worked at | Google (you can figure out my username pretty easily). | | To be honest I can't evaluate your product at work- to | determine whether it helps our users and whether the idea | of moving more of the network stack into the application | makes sense- because my corporation (a large | multinational pharma) disallows us from visiting the | entire tailscale website because you sell a VPN | product(!) which isn't our standard one. I'd love to | change that policy but I'd still want to move to a | BeyondCorp world (https w/ auth), not put a VPN in my | browser. Or make Tailscale our standard VPN. | | I see the point of "it's really handy". That's how we got | Javascript which is a cost we now all have to pay. | apenwarr wrote: | "https with auth" is fine and good, and obviously the | world has been heading in this direction. But I secretly | suspect this is because 90%+ of developers nowadays don't | know how to hack on any layer below http. | | Tailscale is not a typical VPN; it's just a system that | attempts to provide beyondcorp-like behaviour at a lower | level of the stack, so that you don't have to rewrite all | your apps (ssh in this case!) to use https, and don't | have to have open ports in your firewall, and don't have | to run everything through the cloud if you don't want. | | As in my post above, there's more than one way to do it. | You can also build traditional-beyondcorp-over-https on | top of a Tailscale network, so you get all the improved | network connectivity and also all the benefits of a | "pure" beyondcorp architecture. | easton wrote: | Could the Tailscale client be packaged as an extension so I can | visit sites on my Tailnet without having to install a client? | Sometimes I want to visit a "internal" site without having to | install the client, if I'm using a temporary box for something. | I'm not sure how much more work would have to be done, might have | to dig into the open source pieces of this. | capdeck wrote: | Putting my vote in for this feature as well... Also, why not | compile VNC into WASM and get full remote desktop experience | for graphical apps. It seems that hard work has already been | done! | bradfitz wrote: | > Also, why not compile VNC into WASM and get full remote | desktop experience for graphical apps. It seems that hard | work has already been done! | | Yup. :) | | In fact, that's mentioned in the original public bug: | https://github.com/tailscale/tailscale/issues/3157 | Scarbutt wrote: | But can it run emacs? | xena wrote: | Yes | gunapologist99 wrote: | This significantly increases the threat model for your remote | servers to include all sorts of remote attacks through the web, | including: * garden-variety web attacks (i.e., | XSS, CRSF, etc) * attacks that might become viable | against the browser (for example, Mobile Safari has a history of | vulnerabilities) * various attacks against the backend | web server (API attacks) * attacks against the WASM | layer * CDN injections * Tailscale's | backend (various types of injections, timing attacks, or deeper | attacks on Tailscale's infrastructure like the nightmares of | HeartBleed, Shellshock, Meltdown, etc) | | That's probably a very incomplete list. | | Realistically, this essentially (actually, literally) _opens a | remote root shell into your entire infrastructure through a web | page_ , with apparently nothing more than matching an IP address | pair (https://news.ycombinator.com/item?id=33361837) to | authenticate. | | What could go wrong? | amluto wrote: | I can't shake the feeling that Tailscale's SSH authentication | mechanism is at the wrong layer of the stack. It appears to work | by looking at the (source, dest) IP address pair and mapping that | to a Tailscale identity. But this may mean that any user or | anyone who can initiate TCP connections from an authenticated | user's IP can authenticate to the destination over Tailscale SSH. | | If Tailscale's client was a userspace construct bound to a | specific user SSH program, maybe fine. But Tailscale's client is | a regular VPN client. What happens if you connect to the | Tailscale VPN, open a malicious but sandboxed app of some sort, | and that app connects to the target on TCP port 22. | | For all that it's a seriously unfinished product, Cloudflare's | SSH offering seems better thought out. Perhaps Tailscale should | find a way to issue a short-lived certificate and use that in | addition? | | (It looks like regular sshd could _almost_ be convinced to handle | this. If the SSH_CONNECTION environment variable were passed to | the AuthorizedPrincipalsCommand helper or if the source and | destination were available as '%' tokens, then | AuthorizedPrincipalsCommand could do the Tailscale tuple lookup | and use it as a second factor in addition to a short-lived | certificate (or regular SSH key or whatever). I bet openssh would | accept a patch for this.) | [deleted] | matthewaveryusa wrote: | A step-up prompt or notification wouldn't be a bad idea to | approve ssh connections before they are established -- This is | the same issue with ssh agents. I think there's an ACL setting | in tailscale where you check ssh connections with a re-auth. | it's time-based with a minimum of 1 minute though. | fisian wrote: | I agree. | | I feel like there should be a lightweight way to use SSH | certificates, so you could use it independently or on top of | Tailscale. Like a server (CA), client and daemon on your | machines that should be reachable via SSH that handles short | lived certs and authentication of clients. But I'm not aware of | anything like that. | | I have used Teleport before but it seemed not that great for | machines not publicly reachable, because then all the traffic | goes through a proxy. | pquerna wrote: | This is how Okta's Advanced Server Access works: | https://www.okta.com/products/advanced-server-access/ | amluto wrote: | Smallstep and cloudflared do this. Sadly, both of them seem | to use essentially identical client-side hacks. Smallstep is | a small company that I wouldn't trust with the keys to the | kingdom, and Cloudflare seems to treat their SSH product as | something thrown over the fence with nothing resembling | support. | | Gravitational's Teleport seems pretty good, but it's | heavyweight and doesn't have any pricing appropriate for | small businesses. | aleph- wrote: | I'm mildly curious what client side hacks you're talking | about? | mihaip wrote: | Tailscale SSH's check mode | (https://tailscale.com/kb/1193/tailscale-ssh/#configure- | tails...) is meant to address the issue of "rogue process | starts an SSH connection". For truly sensitive applications, | you can set the check period to be "1s" to always require it. | amluto wrote: | Hmm. If the problem is that Tailscale SSH doesn't strongly | associate the person authenticating with the connection being | authenticated, asking the person to reauthenticate seems like | a pretty weak solution. | skybrian wrote: | In the old days, people said you shouldn't write crypto in | JavaScript because it was somehow insecure. Have those concerns | gone away with WebAssembly and https everywhere? | rany_ wrote: | I don't think the argument was ever that "JavaScript was | insecure." It was that the websites hosting it may be | compromised or may change the script at any time without any | indication (or the FBI forcing a site to backdoor the JS for | some investigation) | kevin_thibedeau wrote: | It will never go away because you can't guarantee constant time | algorithms will be implemented as such when transformed by a | JIT. | lxgr wrote: | If machine code can issue the necessary hints to the hardware | to skip all time-variant optimizations, why couldn't the same | work for a WASM runtime? | easrng wrote: | Now that HTTPS is everywhere and crypto.getRandomValues | provides a secure RNG I think most of the concerns are | mitigated. | lxgr wrote: | Maybe for Javascript, the language. | | Definitely not for browsers as the execution environment, at | least browsers running extensions. | e12e wrote: | I think the consensus is still that you can't write side- | channel/timing proof crypto in (most) Javascript (runtimes) - | but that with webcrypto(?) most runtimes will provide the | secure crypto primitives you need in order to do (secure) | crypto with Javascript? | chatmasta wrote: | Cool feature! I was just looking at boringtun last night and | wondering if it could compile to WASM, to get a virtualized | network interface in the browser. | | Did you experiment with the new WebTransport API [0] at all? It's | only supported in Chromium browsers, but seems promising for this | kind of use case. | | [0] https://chromestatus.com/feature/4854144902889472 | PaulWaldman wrote: | > To make this possible, we ported the following to WebAssembly: | the Tailscale client, WireGuard(r), a complete userspace network | stack (from gVisor), and an SSH client. | | Would it be possible to bundle the same into a portable | application allowing you to use Tailscale without installing it? | My understanding is that currently if you can't install Tailscale | on a client you need to use Subnet Router. | https://tailscale.com/kb/1109/devices-without-tailscale/ | lxgr wrote: | You'd have to redirect all network usage (i.e. the sockets API | or your platform's equivalent) through the custom stack, which | is possible if you can rebuild the source or by using something | like LD_PRELOAD for binaries, but can get very tricky in the | general case. | | There's an utility called SSHuttle that does something similar | for SSH instead of Tailscale/Wireguard: It redirects all | sockets usage to go through an SSH connection, to allow usage | of SSH port forwarding without explicit SOCKS support on the | app's side. ___________________________________________________________________ (page generated 2022-10-27 23:00 UTC)