.. index::
single: ssh
single: ssh via http
.. _ssh_via_http:
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.
Apache Configuration
--------------------
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::
ProxyRequests on
ProxyVia block
AllowCONNECT 22
# Deny all proxying by default ...
Require all denied
# Now allow proxying through localhost only
Require all granted
# enable ssl
SSLEngine on
# proxytunnel
ProxyRequests On
AllowConnect 22
# Deny all proxying by default ...
Require all denied
# Now allow proxying by localhost only
Require all granted
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
or::
sudo apachectl graceful
Installing ProxyTunnel
----------------------
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
and::
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.
SELinux
-------
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