Due to a very restrictive firewall at the CHPC, I need to run a VPN to get access to things like email, Jabber and SSH. This however degrades my web browsing experience, since that gets tunnelled as well. I therefore wanted a setup where only ports which are blocked get tunnelled through the VPN, while everything else goes out normally.
The routing part was fairly straightforward, which consists of an iptables
rule to mark certain packets, and an alternate routing table for these marked
packets. I first created a name for the new table by adding the following to
I then added a default route to the new table specifying the IP address of the VPN server and the VPN interface, and a rule to use this table for packets marked by iptables.
The following iptables rule will mark packets destined to the listed port
numbers. Note that this is for packets originating from the firewall host — if
you want this to apply to packets forwarded for other hosts it must be in the
The actual routing worked, but packets were being sent with the wrong source IP. I therefore needed to NAT packets going out on the VPN interface (the IP address is the local IP of the VPN connection).
I could then see packets going out on the VPN interface with the correct source
IP as well as the replies, but it still wasn't working. I eventually discovered
I discovered that OpenVPN supports connections through an HTTP proxy server. This makes it possible to establish a VPN from a completely firewalled network where the only external access is through a proxy server1. It takes advantage of the fact that SSL connections are simply tunnelled through the server and aren't interfered with like unencrypted connections.
The server setup is almost identical to a normal configuration, except that the tunnel must use TCP instead of UDP (since the proxy server will establish a TCP connection). Since most proxy servers only allow SSL connections to certain ports, you will also need to change the port number that the server listens on. The best is 443 since that is used for HTTPS, but if the server is also running a web server on port 443, then 563 is probably the next best choice. This port is assigned to NNTPS, and is allowed by the default Squid configuration. The following two lines enable TCP connections and change the port number.
The client configuration is also very similar. It simply needs to enable TCP connections, set the correct port number, and specify the proxy server.
OpenVPN can also authenticate to the proxy server using either Basic or NTLM authentication. To enable this add "