June 12, 2011, 9:53 a.m.
posted by unixgeek
Tunnel Connections Inside HTTP
Break through draconian firewalls by using httptunnel.
If you've ever been on the road and found yourself in a place where the only connectivity to the outside world is through an incredibly restrictive firewall, you probably know the pain of trying to do anything other than sending and receiving email or basic web browsing.
Here's where httptunnel (http://www.nocrew.org/software/httptunnel.html) comes to the rescue. httptunnel is a program that allows you to tunnel arbitrary connections through the HTTP protocol to a remote host. This is especially useful in situations like the one mentioned earlier, when web access is allowed but all other services are denied.
Of course, you could just use any kind of tunneling software and configure it to use port 80, but where will that leave you if the firewall is actually a web proxy? This is roughly the same as an application-layer firewall and will accept only valid HTTP requests. Fortunately, httptunnel can deal with these as well.
$ tar xfz httptunnel-3.3.tar.gz $ cd httptunnel-3.3 $ ./configure && make
Install it by running make install, which installs everything under /usr/local. If you want to install it somewhere else, you can use the standard --prefix= option to the configure script.
The httptunnel client program is called htc, and the server is hts. Like stunnel [Hack #100], httptunnel can be used to listen on a local TCP port for connections, forward the traffic that it receives on this port to a remote server, and then decrypt and forward the traffic to another port outside of the tunnel.
# hts -F localhost:22 80
Now, run a command like this on the client:
# htc -F 2222 colossus:80
In this case, colossus is the remote server and htc is listening on port 2222. You can use the standard port 22 if you aren't running a local sshd. If you're curious, you can verify that htc is now listening on port 2222 by using lsof:
# /usr/sbin/lsof -i | grep htc htc 2323 root 6u IPv4 0x02358a30 0t0 TCP *:2222 (LISTEN)
Now, try out the tunnel:
[[email protected] andrew]$ ssh -p 2222 localhost [email protected]'s password: [[email protected] andrew]$
You can also forward connections to machines other than the one on which you're running hts. Just replace the localhost in the hts command with the remote host to which you want to forward.
For instance, to forward the connection to example.com instead of colossus, run this command:
# hts -F example.com:22 80
If you're curious to see what an SSH connection tunneled through the HTTP protocol looks like, you can take a look at it with a packet sniffer. Here's the initial portion of the TCP stream that is sent to the httptunnel server by the client:
POST /index.html?crap=1071364879 HTTP/1.1 Host: example.com:80 Content-Length: 102400 Connection: close SSH-2.0-OpenSSH_3.6.1p1+CAN-2003-0693
If your tunnel needs to go through a web proxy, no additional configuration is needed as long as the proxy is transparent and does not require authentication. If the proxy is not transparent, you can specify it with the -P switch. Additionally, if you do need to authenticate with the proxy, you'll want to make use of the -A or --proxy-authorization options, which allow you to specify a username and password with which to authenticate.
Here's how to use these options:
# htc -P myproxy:8000 -A andrew:mypassword -F 22 colossus:80
If the port that the proxy listens on is the standard web proxy port (8080), you can just specify the proxy by using its IP address or hostname.