VPN through HTTPS Proxy with SSH
If you are in a situation where you are locked in a network which has all ports closed to the outside, but there is a HTTP(S) proxy available, then you're lucky and can create a VPN easily using some nice tricks.
You need to have access to a SSH daemon which can be configured to listen on port 443. And you need root rights for everything described here.
To configure a SSH daemon to listen on port 443, just add
Port 443 to the configuration file
/etc/ssh/sshd_config (this directive can be there multiple times).
Furthermore you need to enable some sort of routing and masquerading on the SSH server. Here is a simple example:
sysctl net.ipv4.ip_forward=1 iptables -P FORWARD ACCEPT iptables -t nat -A POSTROUTING -o eth0 -j MASQUERADE
A little tool (besides the SSH client) is needed on the client: corkscrew.
corkscrew is a simple tool to tunnel TCP connections through an HTTP proxy supporting the CONNECT method.
It reads stdin and writes to std- out during the connection, just like netcat. It can be used for instance to connect to an SSH server running on a remote 443 port through a strict HTTPS proxy.
Connecting SSH through a HTTP proxy
The proxy needs to accept the
HTTP CONNECT method, most proxies are supporting this. Connecting to the remote SSH server is done using the
Here is an example SSH client configuration (replace
Host myremotehost.mydomain.tld ProxyCommand corkscrew PROXYIP PROXYPORT %h %p Port 443
This opens a SSH connection to your remote host through the HTTP proxy. If your HTTP proxy does deep SSL inspection (breaking the SSL encryption), then we must use another tool (see later in this blog post). To add proxy authentication, add one more parameter after
%p pointing to a file which contains the auth parameters in the form
Now that we have an SSH connection, we can do many nice things (SSH rocks!).
Variant 1: PPP over SSH
Creating a simple point-to-point link can be done using the ancient PPP protocol. The advantage of this variant is that the PPP tool takes care of doing the link configuration. Just start
pppd on your local using the following syntax (hint: pppd must be installed on the local and remote machine):
pppd updetach noauth silent nodeflate pty "ssh -F PATHTOSSHCONFIGFILE myremotehost.mydomain.tld /usr/sbin/pppd nodetach notty noauth" ipparam vpn 10.0.8.2:10.0.8.1
You now have a point-to-point link over which you can route your networks (see later).
Variant 2: SSH layer 3 tunnel
If you don't like PPP (like me), there is an even easier way to create a point-to-point link: OpenSSH is able to create a tunnel by itself! Have I already mentioned that I really like SSH? =)
The remote SSH server must have the option
PermitTunnel yes configured. Here is a complete example of a SSH client configuration (including corkscrew):
Host myremotehost.mydomain.tld ProxyCommand corkscrew PROXYIP PROXYPORT %h %p Port 443 PermitLocalCommand yes LocalCommand /usr/bin/sudo ifconfig tun0 10.0.8.2 pointopoint 10.0.8.1 netmask 255.255.255.0 ServerAliveInterval 60 Tunnel yes TunnelDevice 0:0 RequestTTY no
Call SSH with this command (as root or with sudo):
ssh -f myremotehost.mydomain.tld 'ifconfig tun0 10.0.8.1 pointopoint 10.0.8.2 netmask 255.255.255.0'
Now you have a point-to-point link
tun0 which can be used f.e. for routing.
As we now have a point-to-point link up and running, the next step is to route everything over this link. Example:
ip route add IPOFMYREMOTEHOST via ORIGINALDEFAULTGW ip route replace default via 10.0.8.1
Note: The host route is very important!
Other ways to break out
If corkscrew is not working because the HTTP proxy does not allow
HTTP CONNECT or is doing some nasty HTTPS deep inspection, there are some other ways (untested by me atm), f.e. the nice httptunnel.
Of course we could also do some OpenVPN tunneling or use other VPN tools which are able to somehow bypass the firewall through the proxy, but I've chosen this approach because SSH is installed on probably every linux machine.
Another nice addition to this toolset would be to multiplex the SSL connection on the remote host, so you could run a HTTPS server, SSH server, OpenVPN server and other SSL enabled daemons on the same port. F.e. sslh is able to do protocol demultiplexing.