Blocking SSH?

Posted in Technology by Thomas Themel on June 23, 2009.

In the past, I haven’t given much thought to the problem of Internet censorship – lame attempts like the Chinese firewall and Germany’s censorship lists were always easily defeatable by anyone with a server outside their jurisdiction (or even a 37 second YouTube video, in the latter case). Apparently, the current Iranian censorship seems to be more serious in that they actually responded to this by (at least partially) blocking SSH traffic. This, now, annoys me. I need SSH to read my mail (and have unfetterd access to whatever parts of the public internets I want).

How does one get past this crap? My best guess would be that the usual HTTPS dodge still works – blocking HTTPS to “world” is going to break so many legitimate applications that you might as well just shut down your entire Internets, so “SSL to port 443″ is a pretty safe bet as a carrier protocol. Two issues arise:

  1. If you have just a single IP address, wasting your port 443 for a rarely-needed redirect is a bit of a pity
  2. The censors might discover that you’re not actually running HTTPS on this port and block it as well.

A simple solution relies on the lucky accident that the initial step of the SSH protocol calls for the client to wait for a server message, while the initial step of the HTTP protocol is for the server to wait for a client message. Thus, it’s rather trivial to write a simple redirector that initially sits there like an HTTPS server. When it receives a request (or anything, really), it forwards to the HTTP server. If this phase times out, it forwards to the SSH server, which will immediately send its server prompt. This means that it is totally transparent to HTTPS traffic and just slightly annoying (well, depending on your delay) on connect for SSH sessions. A proof of concept is here.

Of course, that still leaves the censors with the options of

  1. Detecting it by waiting for the session timeout.
  2. Figuring out what goes on from traffic flow.

Now, number 1 is not much of a technical problem, but I’d still think it hard to find a couple of hidden SSH servers amongst the millions of actual HTTPS out there. Bonus points for doing this on something where the legitimate HTTPS is also popular enough to cause problems when blocked. Number 2 is a threat for me, but it’s less bad if you just want to tunnel your web surfing through it, since it will arguably show quite similar traffic flow behaviour to the actual (direct) HTTPS.

(Inspired by this AskMetafilter thread)

5 Comments

  1. pv2b replied:

    Neat hack, but it’s trivial to block and detect.

    $ nc example.com 22
    SSH-2.0-OpenSSH_5.1p1 Debian-3ubuntu1

    All you need to do is to look for TCP sessions that start with the server sending this “SSH-2″ string. If you’re not worried about custom SSH servers splitting up this initial connection string into multiple packets you can even block SSH without requiring any kind of stateful packet filtering at all – just don’t let through any TCP packets containing the string in question. From the point of view the application, it’ll just seem like the TCP connection has stalled.

    No. A better solution would be to run a HTTPS server which also happens to act like a proxy (allowing CONNECT or something like that) or even running IP over HTTPS requests. I wouldn’t be surprised if a proxy like squid might even be configurable to do this out of the box. Blocking stuff like that is a lot harder for repressive governments, because the encryption is set up *before* the actual request is sent. Sure, the government could do what some corporate firewalls do to inspect encrypted traffic – and basically perform a man-in-the-middle attack on the SSL encryption, but that is easilly detectable (suddenly your application won’t recognise the certificate as coming from a trusted issuer – unless the government has gotten to your trusted certificate list on your machine), and it would require much more expensive filtering equipment.

    June 23rd, 2009 at 19:51:40. Permalink.

  2. Thomas Themel replied:

    Don’t forget that this is running over SSL, so the content of the connection is not readable to the firewall in between.

    Yes, allowing the world to use your HTTPS server as a proxy might be better as a dissident support tool, but I’m not really aiming at furthering any revolutions, it’s just that I want to read my email wherever I happen to connect to the net.

    June 23rd, 2009 at 20:10:04. Permalink.

  3. Andreas Fuchs replied:

    One thing you could try is run an OpenVPN server that listens on 443: The setup procedure looks almost the same as any https one, but threat #2 still applies. Also, you have to run an openvpn client which is slightly more of a hassle to setup if you’re on the road somewhere.

    OTOH, it allows me to use any mail client I want (even gui-based ones) even in the most horrifically firewalled corporate setups. There are tradeoffs, always (-:

    June 23rd, 2009 at 21:53:41. Permalink.

  4. pv2b replied:

    @Andreas Fuchs,

    Running an openvpn server defeats the stealth purpose of having the server “respond” like a regular https server when queried by governmen authorities. (I.e. serve up a regular web page.)

    June 24th, 2009 at 8:11:51. Permalink.

  5. Thomas Themel replied:

    Well, the basic trick seems to work on OpenVPN just as well – at least with –proto tcp-client, it seems to wait for a server hello, so you can multiplex-by-timeout just like SSH does.

    For added greatness, I’d like to have a request parser added that determines what the client wants from the connection request in client-initiated protocols, so that one can have multiple client-initiated protocols on one port, as well.

    June 24th, 2009 at 17:08:02. Permalink.

Leave a Reply

HTML allowed, please keep it safe and clean!

Trackback URI