Thursday, November 29, 2012

Remote access to your Raspberry Pi with ssl/ssh multiplexer

One big advantage of Raspberry Pi is its low power consumption. I can power on it 7x24 and remote it at anytime (of course, assumed your router is also on). SSH from internet to your Pi is simple, by just forwarding port 22 or making the Pi is the default DMZ. However, some places only allows you to visit port 80 or 443, or you have to connect to the internal via a proxy server, which also blocks every ports but 80/443.

Since port 443 is an exception, why don't we set the SSH service to listen to it? Just modify /etc/ssh/sshd_config and add a line "Port 80" or "Port 443". It does work, but wait, what about if the Pi also serves as a Web Server with SSL enabled? If you choose 443 to serve SSH, then you can't have your web server to use SSL at 443. So how to solve this situation? Here is one of the possible approach.

First, install the ssl/ssh multiplexer. It is one of the must installed package in Pi for me.

# apt-get install sslh

The idea of sslh is simple: examine the header of the connect, then divert it to different services. For the case of Pi, you probably have:
One loopback interface (lo)
One Ethernet interface (eth0)
and optionally a wireless interface (iw0)
If you configure port forwarding of port 443 on router, the traffic flow will be "Internet -> Router -> eth0:443". Therefore, the sslh should listen to the IP of eth0 at port 443. Now check the config of sshd and apache/lighttpd/ngnix. The idea is to:
sshd to listen to port 22 at any interfaces
the web server should listen to 443 of loopback interface

So the flow of ssh to the Pi from internet at 443 will be "Internet -> Router -> eth0:443 -> sslh:443 -> eth0:22"
and the flow of SSL connection: "Internet -> Router -> eth0:443 -> sslh:443 -> loopback:443"

Now the port 443 can serve two purposes!

And here is the config files to be modified:
 vi /etc/default/sslh

 
# Default options for sslh initscript
# sourced by /etc/init.d/sslh

# Disabled by default, to force yourself
# to read the configuration:
# - /usr/share/doc/sslh/README.Debian (quick start)
# - /usr/share/doc/sslh/README, at "Configuration" section
# - sslh(8) via "man sslh" for more configuration details.
# Once configuration ready, you *must* set RUN to yes here
# and try to start sslh (standalone mode only)

RUN=yes

# binary to use: forked (sslh) or single-thread (sslh-select) version
DAEMON=/usr/sbin/sslh
DAEMON_OPTS="--user sslh --listen :443 --ssh
:22 --ssl 127.0.0.1:443 --pidfile /var/run/sslh/sslh.pid"

Start by /etc/init.d/sslh start or reboot the Pi will make it effective. In fact, sslh can also divert more services such as openvpn and tinc. Please see the man page of sslh for more details.

Ref: http://www.rutschle.net/tech/sslh

4 comments:

David_K said...

Fantastic article! Can't wait to get it to work... I have followed your instructions. However, I'm getting an error message when trying to start the sslh service:
No address associated with hostname `' failed!

My Pi is running Raspbian wheezy and it's sitting on a static IP behind a router, configured to forward ports 443 and 22 to the Pi.

I have googled for this error and I can't find anyone with the same problem as me, hope you're able to point out in what direction I have to search for a solution.

Best Regards,
David K
Sweden

David_K said...
This comment has been removed by the author.
David_K said...

Found it :-)

I had to set the local IP address in the listener:
  --listen local ip address to my pi:443

Also added loopback IP to the ssh forward
  --ssh 127.0.0.1:22

Best Regards,
David K
Sweden

君子 said...

sorry for the late reply. yes, by specifying which interfaces are listening is better