Tunneling SSH over HTTP(S)
A lot of people asked why doing it like this if you can just make sshd listen on port 443. Well, that might work if your environment is not hardened like I have seen at several companies, but this setup has a few advantages.
- You can proxy to anywhere (see the Proxy directive in Apache) based on names
- You can proxy to any port you like (see the AllowCONNECT directive in Apache)
- It works even when there is a layer-7 protocol firewall
- If you enable proxytunnel ssl support, it is indistinguishable from real SSL traffic
- You can come up with nice hostnames like ‘downloads.yourdomain.com’ and ‘pictures.yourdomain.com’ and for normal users these will look like normal websites when visited.
- There are many possibilities for doing authentication further along the path
- You can do proxy-bouncing to the n-th degree to mask where you’re coming from or going to (however this requires more changes to proxytunnel, currently I only added support for one remote proxy)
- You do not have to dedicate an IP-address for sshd, you can still run an HTTPS site
- An internet connected Apache server (eg. with IP address 10.1.2.3)
- A FQDN that points to this IP address (eg. ssh.yourdomain.com)
- A virtual host configuration in Apache for this domain (eg. /etc/httpd/conf.d/ssh.yourdomain.com.conf)
- A configuration to adapt ssh to use the HTTP tunnel
Here is an example configuration file for Apache (/etc/httpd/conf.d/ssh.yourdomain.com.conf) that allows access from 2 dialup IP addresses (customer location) to machine1.yourdomain.com and machine2.yourdomain.com.
<VirtualHost 10.1.2.3> DocumentRoot /var/www/html Customlog ssh.yourdomain.com-access.log combined ErrorLog ssh.yourdomain.com-error.log HostnameLookups On ProxyRequests on AllowCONNECT 22 2022 ProxyVia on ### Deny everything by default <Proxy *> Order deny,allow Deny from all </proxy> # <Proxy 220.127.116.11> # <Proxy machine.yourdomain.com> # <ProxyMatch .*\.yourdomain\.com> <ProxyMatch (machine1|machine2)\.yourdomain\.com> Order deny,allow Deny from all ### External (customer) sites allowed to connect Allow from 194-78-234-211.dialup.skynet.be Allow from 114-149.241.81.adsl.skynet.be </ProxyMatch> </VirtualHost>
Download proxytunnel 1.6.0. It includes a patch I wrote to chain 2 HTTP proxies. (RPM packages)Then add something similar to this to you ~/.ssh/config file.
Host *.yourdomain.com *.otherdomain.net someserver.org DynamicForward 1080 ProxyCommand proxytunnel -v -p proxy.local.net:8080 -r ssh.yourdomain.com:443 -d %h:%p -H “User-Agent: Mozilla/4.0 (compatible; MSIE 6.0; Win32)\n” ServerAliveInterval 30
This will make SSH use the proxytunnel utility to tunnel SSH over HTTP(S). After that you can simply do:
[[email protected] ~]$ ssh machine1.yourdomain.com Connected to proxy.local.net:8080 Tunneling to ssh.yourdomain.com:443 (destination) Starting tunnel [email protected]’s password:
Download proxytunnel 1.6.0. (For Windows take the cygwin build) It includes the patch I wrote to chain 2 HTTP proxies. (RPM packages)Then to configure putty to use proxytunnel, you need a recent putty (newer than 0.58). Currently only the development release includes the required functionality.
Then go into the Connection > Proxy menu. Select the Local proxy type. And then provide as Telnet command, or local proxy command the following line:
proxytunnel -q -p proxy.local.net:8080 -r ssh.yourdomain.com:443 -d %host:%port -H “User-Agent: Mozilla/4.0 (compatible; MSIE 6.0; Win32)\n”
For Windows it helps to put the proxytunnel.exe in the same path as putty so that putty can find proxytunnel.exe more easily.For debugging you can replace the -q option with a -v option and use the command on the command-line. proxytunnel will print what it is doing and where it fails.
The above configuration allows you to forward SSH connections to multiple destinations (without the requirement to have SSH running on another port than 22).To simplify tunneling over SSH, you might want to create a ‘dynamic’ tunnel using the -D 1080 OpenSSH option. This allows you to socksify any TCP connection and direct it over the SSH tunnel dynamicly.
Most browers allow to socksify their own stack by simplying configuring a socks proxy. In this case you should point your browser to localhost:1080 to surf using the SSH tunnel.
proxytunnel has support for SSL tunneling by using the -e option. Unfortunately we discovered a bug in Apache that causes CONNECT (mod_proxy) to fail when SSL is being enabled. You can find more information in Apache’s bugzilla at:http://issues.apache.org/bugzilla/show_bug.cgi?id=29744
You can send problems or improvement requests to the proxytunnel mailinglist at:https://lists.sourceforge.net/lists/listinfo/proxytunnel-users
I’m interested in the following improvements to this scheme:
- Use SSL for forwarding requests
- Allow to chain more than 2 proxies
- Allow authentication on the second proxy (so that a fixed ACL is not required and you have much more flexibility)