SSH via HTTP¶
SSH is a hugely powerful tool for communicating with and manipulating remote machines, and as a result many companies fear it and try to block it. As such, many corporate firewalls block port 22, the port naturally used by SSH. However, few corporations can afford to block ports 80 or 443, the ports designated for http traffic.
It is possible to work around these firewalls by configuring SSH to listen on either port 80 or 443. However, this approach is only suitable if you are not already using, or planning to use, port 80 or 443 to serve your websites. There is, however, another option. If you have are running an Apache webserver, you can configure it to act as an HTTP or HTTPS proxy and use it to forward SSH traffic that comes in on ports 80 and 443 to your SSH server. To do so, you will need to configure Apache to act as a proxy, and you will need to use proxytunnel when running your SSH client to make it work with the Apache proxy.
The first step is to configure Apache to act as an HTTP and HTTPS proxy. To do so on a recent Fedora system, you should create a file and place it in /etc/httpd/conf.d. The name of the file is somewhat arbitrary, but it should end in .conf. Also, the files in this directory are processed in alphabetic order, and so you may want to choose a name earlier in the alphabetic sort order if there is a chance another file may interfere. Neglecting this, assume that the file name chosen is 10-proxy.conf.
This file is suitable for use on an Apache version 2.4 or later server. It explicitly prevents proxying to any other destination than localhost port 22:
<VirtualHost _default_:80> ProxyRequests on ProxyVia block AllowCONNECT 22 <Proxy *> # Deny all proxying by default ... Require all denied </Proxy> <Proxy 127.0.0.1> # Now allow proxying through localhost only Require all granted </Proxy> </VirtualHost> <IfModule mod_ssl.c> <VirtualHost _default_:443> # enable ssl SSLEngine on # proxytunnel ProxyRequests On AllowConnect 22 <Proxy *> # Deny all proxying by default ... Require all denied </Proxy> <Proxy 127.0.0.1> # Now allow proxying by localhost only Require all granted </Proxy> </VirtualHost> </IfModule>
This file configures a proxy for both port 80 and 443. You can remove the appropriate section if you only want one port to act as a proxy.
You also need to assure that Apache loads the appropriate modules: proxy, proxy_connect. proxy_http. That is done in /etc/httpd/conf.module.d. For me, this was preconfigured. I had the following lines in the file 00-proxy.conf:
LoadModule proxy_module modules/mod_proxy.so LoadModule proxy_connect_module modules/mod_proxy_connect.so LoadModule proxy_http_module modules/mod_proxy_http.so
You activate the proxy by running:
sudo systemctl reload httpd
sudo apachectl graceful
On Fedora, you can install proxytunnel with:
sudo yum install proxytunnel
Testing the Proxy¶
You can use proxytunnel to test your Apache setup. Simply run the following:
proxytunnel -p myserver.com:80 -d 127.0.0.1:22 -v
proxytunnel -E -p myserver.com:443 -d 127.0.0.1:22 -v
It should respond by saying that the tunnel was established. If you choose any other destination (IP address or port) it should fail.
Configuring Your OpenSSH Client¶
Add an entry to your SSH config file (~/.ssh/config) for your host that looks like the following:
host home80 HostName myserver.com ProxyCommand proxytunnel -q -p myserver.com:80 -d 127.0.0.1:22 Port 80 host home443 HostName myserver.com ProxyCommand proxytunnel -q -E -p myserver.com:443 -d 127.0.0.1:22 Port 443
Be sure to add the -E flag on proxytunnel when connecting to port 443 to turn on SSL encryption.
If SELinux is running, it will likely stop Apache from connecting to SSH. If your proxy is not working, you can determine if SELinux is the problem by temporarily disabling SELinux with:
sudo setenforce permissive
If the proxy starts working, you have discovered the problem. Generally this is because SELinux nominally blocks httpd from accessing the local network, which prevents it from accessing the SSH daemon. You can circumvent this problem using:
sudo setsebool -P httpd_can_network_connect 1
The -P makes the solution persistent across reboots.
You should reactivate SELinux using:
sudo setenforce enforcing