The stunnel utility written by Michał Trojnara allows, if I understand correctly, to "wrap" non-SSL protocols (such as ssh) in an SSL connection.

For example, imagine that all network ports on a network are blocked except the ports 80 and 443 for HTTP and HTTPS traffic respectively. Deep packet inspection is also used to ensure that both the ports are only used for HTTP(S) and nothing else, so you can't just run an SSH server on port 443 and expect it to be able to connect through this firewall.

Now, stunnel can be used in this case by running an stunnel listener on port 443 of the server (bound to internal port 22) and using the stunnel client to connect to port 443 of the server, in fact connecting to its SSH daemon. The firewall has no idea that this happens because

  1. The connection is encrypted and integrity-checked by design, so the firewall does not know what data is being exchanged - HTTP or not.
  2. Because it is an SSL connection and is running over 443, the server cannot make the distinction between an HTTPS server and say, ssh.

My question is - what would be a way to actually detect the usage of stunnel and block it? Let's assume that methods of analysis such as looking at patterns of data (hmm, a lot of data exchange is unusual over an HTTPS connection, so this SSL tunnel must be used for something else) are unavailable. We also cannot install software or certs onto user's devices.

Is there really any practical way to stop this, considering that keeping HTTPS working is crucial?

  • 3
    Try to solve this problem as a policy issue, not technical issue. If you are in charge of any organization network, apply and tell all employees that all connections are logged and stunnel is forbidden.
    – ThoriumBR
    Commented Jun 26, 2018 at 16:05

3 Answers 3


Since you exclude SSL interception (i.e. no certs can be installed) and also exclude any kind of traffic pattern analysis there is not much left. What could be tried is analyzing the TLS handshake itself:

  • TLS stacks and also applications using TLS often leave a usable fingerprint in the ClientHello, i.e. which protocol version, which ciphers are offered in which order, which extensions are used and which order etc. Nothing new and lots of information can be found about this. Of course, a client could in theory replicate another clients ClientHello perfectly to hide itself.
  • Similar passive analysis could be done for the server side. But the variety of server configurations which are reflected in the TLS stack is much larger than on the client side, so this is probably not as effective as analyzing the ClientHello.

To make it clear: this is just heuristics. It can cause false positives and it can fail to detect stunnel instances. This is especially true in complex networks with a variety of different clients and only few time to manually analyze if a specific uncommon fingerprint should be allowed in general, to a specific target or should be blocked.

  • It's worth pointing out to anyone reading this that this approach has a large downside of generating many false positives. stunnel uses openSSL to implement TLS, which is quite popular, and used by Apache for instance. Commented Jun 27, 2018 at 15:19
  • @SteveSether: When analyzing the ClientHello only the TLS implementation of the client and not the server matters. IE/Edge, Firefox and Chrome all use different TLS implementations (SChannel, NSS, BoringSSL). And while BoringSSL is a fork of OpenSSL the particular configuration within Chrome makes the fingerprint very likely different to stunnel (which uses OpenSSL). Commented Jun 27, 2018 at 15:44
  • I'd be surprised if some client tool on any large network isn't using openSSL for legitimate business purposes. wget uses openSSL for instance. Commented Jun 27, 2018 at 16:59
  • @SteveSether: it depends on the environment. And even different clients using OpenSSL can show different fingerprints since they offer different ciphers, cipher order, extensions ... . Anyway, of course there can be false positives and of course it is possible to bypass this detection by perfectly emulate a client. But is is probably the most you can get if SSL interception or traffic pattern analysis is not an option. I've made it more clear in my answer that this is just a heuristics which might fail depending on the environment. Commented Jun 27, 2018 at 17:28

No interception, no way.

This is a problem to be solved with policy, not technology. You cannot stop users with tech, or infrastructure, or configuration. The only safe way is policy. If you employ a hard rule on webshells, stunnel and remote access, and really enforce it, your users will be less inclined to poke holes on the wall.

But if you want the more frustrating path, there's some bad news: you cannot do that without interception. No matter what kind of passive inspection you employ, users will avoid it.

Connecting to the site to see if there's a website will not work. Using sslh is possible to use the same port for HTTPS, SSH, OpenVPN, XMPP and plain HTTP, all at the same time.

Another option is corkscrew. It will tunnel SSH over your HTTPS proxy, transparently. If you do not intercept the connection and inspect it, your firewall will not detect anything.

Even if you analyse and block other protocols, a resourceful user can use AjaxTerm or Shell in a Box, exfiltrating data even if you try to block SSH.


You could have software that makes its own connection to each observed host, port, and SNI, and perhaps other parameters like TLS-version and ciphersuites if you think someone might be sneaking information in those, and see if it responds to a request like a normal HTTPS server. If it doesn't respond with HTTP format over the SSL/TLS connection, you could assume it's stunnel'ed SSH or something else dubious like torrent and blacklist it. Perhaps with expiration after a defined period, in case it's a dynamic IP and gets reassigned.

However, instead of SSH(TCP)-over-SSL/TLS (stunnel) someone could use software that does SSH(TCP)-over-HTTPS i.e. SSH(TCP)-over-HTTP-over-SSL/TLS. That will be essentially impossible to detect simply by trying an arbitrary HTTPS request, since the HTTP tunnel could use any manner of authentication or obfuscation that you don't know because of the SSL/TLS. In that case probably your only option is to manually investigate the desired servers and whitelist those you judge safe (and stable); unless you can limit it pretty strictly -- maybe wikipedia, linkedin, a few local banks and restaurants, and Stack (of course) -- you'll probably need several full-time employees for each employee you want monitored -- and then you'll need a way to monitor the monitors.

Alternatively, a cheap approximation is to just RST any connection that lasts more than say 30 seconds (edit) between data transmissions. Although HTTPS clients (especially browsers) will tend to keep idle connections open a while to save the cost of reconnecting, the HTTP protocol (and thus also HTTPS) is defined and (almost universally) implemented to work just fine if it has to remake the transport connection frequently(edit) for any or even every request. In contrast most things done over SSH depend on keeping the same connection -- but not all, so a sufficiently determined cheater could get around this also.

  • 2
    It won't work. If the user installs sslh, you will connect to the server via HTTPS, and it will show you a webpage. User connects via stunnel and access its SSH behind.
    – ThoriumBR
    Commented Jun 27, 2018 at 12:09
  • "the HTTP protocol (and thus also HTTPS) is defined and (almost universally) implemented to work just fine if it has to remake the transport connection frequently" I want to download a large file via HTTP/HTTPS. Your description seems to imply that breaking the transport is recoverable and the response will continue when connection is re-established. It won't. It will be a highly frustrating experience.
    – spender
    Commented Sep 8, 2018 at 0:54
  • @spender: sorry I wasn't clear; I meant each HTTP[S] request can be separate, with state in cookies or explicit parameters (if at all), whereas a series of commands/operations over SSH usually need implicit state. I didn't mean transport breaks within one request. Although for downloading if server supports Range->206 you can indeed resume and that can be a good thing. Commented Sep 8, 2018 at 4:20

You must log in to answer this question.

Not the answer you're looking for? Browse other questions tagged .