11

In an answer to What is the difference between SSL, TLS, and HTTPS, it's said that HTTPS is HTTP over SSL/TLS. That is, an SSL/TLS connection is established first, and then normal HTTP data is exchanged over the SSL/TLS connection.

So, if I use stunnel to create an SSL tunnel, and then pass HTTP traffic through it, would it be the same as using HTTPS normally?

Then, if a proxy/firewall sees only an SSL/TLS connection with encrypted traffic, how could it know the traffic isn't HTTP?

In theory, I think that if the proxy/firewall can't notice the difference, one should be able to tunnel SSH traffic through an SSL/TLS connection (created with stunnel) instead of HTTP. However, in practice, I have seen this not work - the proxy/firewall appears able to detect that it is not HTTPS traffic.

I think this is why Proxytunnel is used, but I don't understand what Proxytunnel does differently to avoid detection. Does it just create fake HTTP headers?

How is the firewall able to detect the difference between HTTP and SSH, when they are both tunneled through SSL/TLS?

Simon Woodside
  • 265
  • 3
  • 10
emi
  • 111
  • 1
  • 3

2 Answers2

13

TL;DR - I think your problem is not related to SSL at all, but you are trying to use a proxy server without the proxy headers.

So, if I use stunnel to create an SSL tunnel, and then pass HTTP traffic through it, would it be the same as using HTTPS normally?

Yes. We use http over stunnel at work to talk to an https-server. That's a workaround for a bug in the Java https client that is not able to talk to an ISS https-server in some situations.

Then, if a proxy/firewall sees only an SSL/TLS connection with encrypted traffic, how could it know the traffic isn't HTTP?

A normal proxy/firewall is not able to tell what is inside.

There are decrypting https-proxies. In order for them to work, they need to trick the client into accepting their own public key instead of the public key of the real server. In https the public key is part of a certificate which contains information about the server name. The certificates are usually signed by CAs, which the browsers know as trustworthy.

The proxy server needs to fake the server certificate in order to get the client to use his own public key. A normal client will display a warning about the invalid certificate. But the proxy can sign the faked certificates with its own CA. And the administrator can install the CA as trusted on the clients.

In theory, I think that if the proxy/firewall can't notice the difference, one should be able to tunnel SSH traffic through an SSL/TLS connection (created with stunnel) instead of HTTP.

The common way to tunnel SSH out even works without the SSL layer on non decrypting https-proxies.

However, in practice, I have seen this not work - the proxy/firewall appears able to detect that it is not HTTPS traffic.

Either you are doing something wrong, or your are behind a decrypting https as explained above.

I think this is why Proxytunnel is used, but I don't understand what Proxytunnel does differently to avoid detection. Does it just create fake HTTP headers?

You have to distinguish between a firewall and a proxy here: If there is just a network firewall you can connect to the target ip-address on port 443 normally. But if there is a proxy, you need to connect to the ip-address and port of the proxy and then tell it to connect to the target using the http protocol. The command is: CONNECT target:port HTTP/1.1 <cr><lf>

In most cases https-proxy-servers allow connecting to any ip-address but only to port 443. After sending the connect-string, you get a http response header. On a normal https proxy any further information, is forwarded as is into any direction. So you can speak any protocol you want. Using ssh natively from here on works.

In theory a firewall or dumb proxy may prevent this native tunneling by detecting non SSL-traffic. But this is very uncommon. Only a https decrypting proxy will be able prevent this kind of tunnel effectively.

Hendrik Brummermann
  • 27,118
  • 6
  • 79
  • 121
1

If you do HTTP to the server port of an stunnel instance:

client <--- TCP ---> stunnel <--- TCP ---> server
                             <--- TLS --->
       <------------- HTTP -------------->

it will be almost exactly like using HTTPS, but not fully because the client still sees itself as using HTTP over TCP. For example, a browser will not display "Secure" in the URL bar, and Javascript code running in the browser could refuse to do things if it things the connection is not HTTPS.

For the rest of your question, you need to figure out exactly what's going on with the "firewall" or "proxy" that you're using; there are a number of different techniques it may be using to handle the connection that will allow or prevent certain techniques when you use it.

1. Direct TCP Connection

If you're making a TCP connection that terminates at the remote host (diagram above), even if it's modified in some way (e.g., addresses changed via NAT), and you set up a TLS connection on that TCP connection, intermediate routers will not be able to see any of the traffic beyond the amount of it, the IP addresses and TCP ports, and the fact that it's TLS. An IP level firewall might be configured to disallow connections to ports other than 443 or drop connections to 443 if it sees that they're not TLS. It might even connect to the port itself first to see if the server appears to be running HTTP/TLS on that port.

2. HTTP Proxy CONNECT

If you're going though an HTTP proxy using the CONNECT verb, as Proxytunnel does, there are two TCP connections involved but you do one TLS connection over them:

client <---- TCP 1 ----> proxy <---- TCP 2 ----> server
                        CONNECT
      <------------------ TLS ---------------->

You are still negotiating TLS with the real server at the other end, and the situation is pretty much the same as #1 above. You don't need to do TLS over the TCP connections, actually; you could simply CONNECT server.mydom.com:22 and start talking SSH over that connection if the proxy doesn't reject that request. Some people have SSH servers listening on port 443 for exactly this purpose. If the proxy is sophisticated enough to check the protocol in use, though, it may disconnect you if it see you didn't do a standard TLS setup, even though once TLS is up it can't see exactly what's going on in that connection.

3. MITM

Some organizations do man-in-the-middle attacks on HTTPS connections (sometimes more politely called "SSL interception"). When you attempt to connect to the remote server, via either a direct TCP connection or a proxy as in either of the cases above, a network device pretends that it's the remote server.

client <---- TCP 1 ----> MITM <---- TCP 2 ----> server
       <---- TLS 1 ---->      <---- TLS 2 ---->
       <---------------- HTTP ---------------->

Your web browser than attempts the TLS setup, checking the certificate, and will validate it not because it's the real cert but because the device generated a cert with signed by a private CA (certificate authority) and the IT department has also modified cert list in the browser or OS to trust that CA. (You can often tell this is happening by trying the same connection with another program that uses a different cert list without that cert, such as Firefox if you download it independently.) You have a secure connection to the MITM device, but it's decrypting everything and re-encrypting it for another, separate secure connection to the server when it forwards data.

In this case, though you think you're talking to the remote server, you're actually talking securely only to the proxy which has full access to all data on the connection and can see and modify it as it wishes.

cjs
  • 339
  • 1
  • 6