SSH over HTTPS
trofi.github.io
trofi.github.io
> Ubiquitous presence of HTTPS allows you to pass your data through very restrictive middle boxes!
This is, in fact, why all — or nearly all — proprietary VPN protocols (so-called "SSL VPNs") implement a mode that initiates a tunnel via HTTPS, at least as a fallback if not as the primary mode of operation: precisely in order to have a mode of operation that works with almost any connection to the global Internet.
I'm one of the main developers of https://gitlab.com/openconnect/openconnect, which implements many such protocols, and wrote https://github.com/dlenski/what-vpn, which sniffs or identifies even more flavors of TLS-based VPN servers.
Well there you go. We went down to 1 port, then down to one protocol, now we'll soon be down to 1 company (akamai/CF/etc).
AND the client can run in javascript (or wasm these days)
And nobody will let companies turn that off, because that would mean ad networks would lose out. Which means none of the free services on the internet would work over such a connection, which means companies would either have to pay to implement their own services or do without those services. Both are inconceivable to managers, so ...
Sort of a redo of the pirate radio ethos of the 60s.
had exactly this feature. They provided ssh access via port 80.
OP is describing something different:- different port (443, not 80)
- different protocol used on that port (https, not ssh)
In the old days, only the port number mattered. Today, DPI means the protocol matters as well.
Edit: I tested that time ago:
https://news.ycombinator.com/item?id=38753897
And to save roundtrips: I believe it must be possible to analyze encrypted traffic to find out which protocol is used. But I doubt that the hospital admins are so motivated or sophisticated.
An SSH server and client do not use SSL/TLS to set up the connection. They use the SSH protocol.
As soon as you connect to an SSH server, the server sends an identification string. The identification string always starts with:
SSH-
It's trivial to detect.In the old days, corporate firewall rules were based solely on port numbers. So you could connect to an outside SSH server running on port 80, even if port 22 was blocked. Nowadays, an SSH server running on any port (80, 443, or any other) can easily be detected and blocked.
I ask because if it works, the principle is the same: using a commonly used protocol to circumvent limitations. It used to be easier to do then, it's more involved now.
In other words: is it possible to tunnel anything through https?
No it's not. The earlier method used only a commonly used port, and did not require the use of a commonly used protocol.
https://www.shodan.io/search/facet?query=ssh&facet=port https://www.shodan.io/search/facet.png?query=ssh&facet=port
Port 80 is a lot less common though.
At least several years ago when I first set up my SOCKS proxy and was using wifi quite a bit I never found one that did anything more than check the port, although I have heard they exist and could be more common now (and of course it doesn't matter how common they are if one is in your way).
Later, I was working on making an archive of Windows .iso files, and since I had some free time, I was downloading them on my laptop and then uploading them to my server with scp. As it turns out, using dozens of gigabytes, in both upload and download, on a port besides 80 and 443, is enough to finally get your traffic inspected, so around lunchtime IT finally blocked port 22. But you know what they didn't block? Every other port! So I just moved SSH to port 443 in my port forwarding and carried on as normal.
A long time later, sometime during sophomore year IIRC, the school's IT noticed me SSH-ing over port 443 and put an end to that. They set up some basic traffic analysis to block SSH on ports 80 and 443. But you know what they didn't block? Every other port!
Eventually they just ended up blocking my server at the IP level (the IP of my domain), but of course, but you know what they didnt block? Literally every other IP!
I could get around it by just ProxyJump-ing with a VPS, but being an early college high school student, after sophomore year I rarely go to the high school, so it's not really worth the effort. But next time I do go, I'll do it, just to prove I can.
If they finally block SSH on all ports, then I can just set up SSH over HTTPS on the VPS, of course. There's still more they can do, of course, but I'll come back after I graduate and see what I can do on their guest wifi.
Anyways, thanks, Birdville Independent School District IT team, it's been quite fun, though it really would be nice if you'd unblock my site so that I can provide the services the district won't (computers (VMs) actually useful for tech students).
At Adaptive [1], we are building a data security infrastructure. In one of our products, we do SSH and various other protocols over HTTP3. It allows users to connect to databases, servers, and other resources over an outbound port. Similar to Ngrok and others but can be self-hosted You can access it in a passwordless manner or with temporary credentials, with maker-checker protection.
However, CONNECT wasn't good enough for me. I did ssh over websocket to bust through a corp proxy (it inspected https connections with a custom CA).
I modified socat to serve my ssh server over websocket through apache. I also used it on the client end with openssh's ProxyCommand. I keep meaning to upload that patch, but there are other options around (websocat, for example).
Nice standalone implementation and write up though.
1. you're behind an HTTP proxy, and
2. the HTTP proxy support the CONNECT method
Around 20 years ago I did a short contract which had #1 but not #2. Thankfully, there's a tool for this, too. Of course it requires some set up on the server side:
This is because HTTP2 is great at exploiting a TCP connection to transmit and receive multiple data structures concurrently - multiplexing.
There may not be a reason to use HTTP3 however, as QUIC already provides multiplexing.
I expect that in the future most communications will be over encrypted HTTP2 and QUIC simply because middlebox creators can not resist to discriminate. It may even be necessary to serve some random (perhaps AI generated) HTTP2/HTTP3 content to mitigate active probing[2].
[1] <https://grpc.io>
[2] <https://blog.torproject.org/learning-more-about-gfws-active-...>
Whether it's HTTP 1, 2 or 3, it doesn't really make a difference. The evolutions of that protocol are themselves somewhat dubious, and designed to exploit things you wouldn't need in an RPC setting -- they're really designed for the open Internet, not a local service.
HTTP/3 is over QUIC
Only half joking. I would love to have ssh equivalent identity management baked into a browser. I got all excited when first reading about hobo, which is a proposal for public key http auth. only to find out that not only did a server implementation not exist(i could work around this) but no client(browser) implementation exists(sort of, there is a javascript implementation, but that is not what I wanted.
https://techcommunity.microsoft.com/t5/iis-support-blog/clie...
I don't know enough about this to know if it meets your need but I've used them to authenticate to servers in college.
However, macOS has its own framework for doing https calls, which most macOS applications use. It takes the place of OpenSSL/LibreSSL (etc) as used on Linux.
That framework does things differently, which turns out to make life difficult:
* It seems to require the certificate for your custom certificate authority to be in the macOS keychain.
So instead of having a custom CA that can be used by just your one application when doing https calls to your own remote server... you have to install your (root) CA certificate "system wide". From rough memory, that's a potential security problem as allows your custom CA to generate certs for any domain that macOS would now accept.
* It seems to also impose it's own arbitrary standards on certificates.
It looks like anything with an expiration date of more than a year is automatically rejected.
Which for certificates embedded in applications that aren't released at least once per year (eg ours at sqlitebrowser.org) just outright kills the whole fucking thing regardless of anything else we could do.
There's no real workaround for the kind of idiocy that requires applications more than a year old not being allowed to work. :( :( :(
---
That's my rough memory of this stuff anyway, it's been quite a while since I last looked at it. Hopefully the above isn't too far off base. :)
The moment you have a certificate loaded into your browser, every single tracker will see the availability of client side certificates as a means to do fingerprinting. Either you configure your browser to expose your identity to every website who asks, or you get popups for every other website asking you to pick a certificate.
Web browser could probably fix this, but client certificates are uncommon enough that I doubt they care anymore. Like HTTP basic auth (and its lack of password manager integration), it seems like this feature only remains for compatibility reasons.
Like usual, middleboxes also tend to fuck up client certificate based authentication because they can't effectively MitM those connections (they don't have the key material you're using, and while they can try to fake a website's TLS certificate in intranets, they can't fake your credentials to remote servers).
It's real unfortunate. They're still used, though; some Kubernetes networking tools automatically provision client certs to authenticate API clients within the cluster (as well as protect the traffic from snooping).
I use client certificates since they are required in my line of business and had the impression that they are only presented when asked for by the website, only I explicitly allow it.
Other than the sites that I know require them, I have never been asked to choose a certificate when browsing random websites (windows 11).
Maybe the situation changed, or ad blockers have become better in the mean time, but last time I used them in Firefox, I was bombarded by client certificate requests browsing around the web.
The problem I have with the UX is that the certificate selection screen is a modal dialog that any URL seems to be able to bring up, and I found this abused in the wild. This, combined what made with the countless requests, made me move away from using them.
Another issue I struggled with was that every now and then I'd pick the wrong certificate and I couldn't for the life of me figure out how to correct this without restarting my browser and losing all my work. Switching between accounts for cert based auth was plain impossible.
Lastly there was the entirely unhelpful error state you can end up with when using client certs. Vague HTTPS errors that come down to "oh no something went wrong try reloading I guess" and weird side effect when certificates expired (from browsers sending old certificates to servers accepting expired certificates). The errors occur in the TLS layer, so you end up with authentication errors thst seemingly end up being handled as connection issues.
If you say these issues have been resolved, I should probably give mTLS another go.
The UI can be clunky, especially if you set up the certificates to be stored in TPM, since then windows sometimes pops up the dialog in a way that’s easy to miss. Other than that Ive no complaints. Good luck!
ssh -D “*:8080” host
This fires up a SOCKS proxy on port 8080. I use it all the time within Firefox. Legendary OG VPN.It’s handy for nefarious use cases, but I also use it to access rmq dashboards on non-public networks in AWS.
We had actual VPNs (that would also be blocked) long before OpenSSH included -D as an option.
I remember having to do multiples of -L in order to be able to successfully download a file over FTP through an SSH tunnel. Fun times. -D made life so much easier once that arrived.
Hopefully also SFTP? Security was nice, but the real win was running like a normal application on a single port.
SSH3: SSHv2 using HTTP/3 and QUIC
“ Probes for HTTP, TLS/SSL (including SNI and ALPN), SSH, OpenVPN, tinc, XMPP, SOCKS5, are implemented, and any other protocol that can be tested using a regular expression, can be recognised. A typical use case is to allow serving several services on port 443 (e.g. to connect to SSH from inside a corporate firewall, which almost never block port 443) while still serving HTTPS on that port.”
Edit: I should just have looked up the wikipedia example https://en.wikipedia.org/wiki/HTTP_tunnel
It didn't really matter what the protocol was, the client and server just see each other. IIRC it was also possible to connect a browser with https to a tunneled http server or viceversa.
You can do valid HTTP & SSH on the same port: https://media.ccc.de/v/bornhack2023-56142-sexy-ssh-hacks#t=4... (Without detecting which client connects, it works just like the "valid PNG and ZIP polyglot" trick)
- it means you can't also serve HTTP on those ports (so you'd need a dedicated IP address for SSH), and
- as @charcircuit wrote, it won't resist deep packet inspection.
(But if DPI is a problem and you have a spare IP address, you could just use SSH over TLS without needing the HTTP CONNECT stuff and Apache.)
Last time I was going to be somewhere when SSH as blocked but HTTPS was very open, and I couldn't rely on phone network connectivity, I stood up an instance of shellinabox¹ in case I needed to do remote admin while there.
This has the disadvantage of not allowing direct SSH access so I couldn't directly run scripts from local, use SFTP, or tunnel other stuff (like rsync) over SSH, but it's big plus was being able to use it from any machine.
Security could be a big issue with the shellinabox method. To mitigate this it ran in is own VM and the only thing I allowed it to do was SSH to a specific host to authenticate with a huge password (typed manually or via usb auto-typer on other machines, via keepass on my own), and then from that host I could SSH elsewhere. There was also some security-via-obscurity with the URL it was available on. Tunneling SSH would definitely have been more secure (allowing key based auth from my machines for a start) but I wanted that option to connect from machines (that were very locked down) other than my own. I took it back down as soon as the need had passed as it didn't feel 100% safe, bit it served a purpose.
--
If simply connecting over a certain port was the answer I could have setup SSH on port 433 and been done without even that. Though I'm happy to be told I missed something obvious, in case I have the same need again in future.
Also just thinking about the SSH connection forgets the "want it to work on any machine" extra requirement I had. Being able to run an SSH client directly _at all_ was a concern.
Then I learned about, Ligolo-ng [1] which is a game-changer. I highly recommend checking it out. It is most applicable to a penetration test. It uses TLS so I'm not sure it could be used to address the issue mentioned in the article.
It is probably trivial for people here to get a domain and then point it to the IP, but still, this seems a minor limitation.
https://pkg.go.dev/github.com/HimbeerserverDE/httpssh
> httpssh listens for HTTP(S) and SSH connections on the same port and forwards the traffic to the corresponding service.
frontend https
bind *:443
mode tcp
tcp-request inspect-delay 2s
use_backend https_loopback if { req.ssl_ver gt 0 }
default_backend ssh
Another option is to use TLS SNI (Server Name Indication) like a virtualhost-style ssh server (https://www.haproxy.com/blog/route-ssh-connections-with-hapr...). You can use the 'openssl' command in your ProxyCommand which is pretty readily available.- Can open a shell from any device with a browser, no ssh required;
- Works even if home network is behind CGNAT.
Disadvantages:
- A middleman;
- Other people can open a shell if my Cloudflare auth is fully compromised (requires compromising a high security email inbox).
I remember in the past how I lost couple of hours trying to understand why I can't reach a remote instance via RDP, only to finally figure it was the port blocking on the office firewall.
I spent quite a while trying to convince the local sysadmin that this doesn't make any sense. His only explanation was "security" without any actual explanation of what is he securing us from.
It is a pain when you need to download material from your hardware suppliers' web sites.
I can't imagine those South Americans being able to access anything without clearing twenty Cloudflare CAPTCHAs (I don't think Cloudflare operates in China), but then again, I think they'll just blame Cloudflare for sabotaging their perfectly safe 100% legit web traffic.
This type of blocking wouldn't be necessary if these companies actually did something with the abuse reports they receive, but I guess blocking SSH and telnet is an easy way to stop the flood of reports coming in if you don't care about your customers.
After a few decades of having your software’s ass handed to it though, is it so unreasonable to stop asking “why not” and instead start asking “why the fuck should we?”
Always nice to see these kind of „missiues“ ;)
Anyconnect VPN looks like HTTPS traffic and is very difficult to block, even with DPI.
Worth looking into if you need this commonly. :)
that is.. can i only route some the.server/go-to-ssh/ endpoint to ssh, and all other stuff stays and is accessible as is?
I assume that a firewall exists that blocks ssh over 443 while allowing HTTPS, but have not encountered that yet.