I wrote this little utility in early 2014 to scratch an itch for myself (I’ll explain below) but never really thought much about it after that. Shortly afterward I found myself working on a project that needed exactly the same functionality, so I decided to open source it and put it up on GitHub.
From the README:
[SSHTunnels is a] pair of programs to babysit both ends of an SSH tunnel. The client side can be roaming from network to network and/or on an unreliable link and it will do its best to keep the tunnel up as often as possible for as long as possible. The server side will promptly clean up stale connections to free up ports in preparation for an incoming client connection.
This will make more sense if I explain the personal itch I was trying to scratch when I was writing SSHTunnels: Specifically, I wanted to initiate a network connections to my Jailbroken iPhone even when I was roaming on and off of various Wifi and 4G networks.
Since I would never know my iPhone’s IP address, I wouldn’t be able to ping it directly. And even if I did, there would be no guarantee that the network route between me and it would be favorable to support initiating a new connection in that direction.
So what if the iPhone was constantly holding open a tunnel whenever it was awake?
Thus, SSHTunnels was born.
Let’s do a quick high-level run through. Clone the repository:
git clone firstname.lastname@example.org:alexmarkley/SSHTunnels.git
From within the checked-out directory, invoke the build process like so:
gmake -f Makefile.Linux WITHSYSLOG=true clean all
If you get any errors about expat, you need your distro’s expat-devel package or equivalent. If you are missing pkg-config, gmake, gcc, or anything similarly low-level, you may need to check your distro’s release notes for how to install a working development environment.
With a successful build, you will probably want to install the binaries:
sudo gmake -f Makefile.Linux install
The two programs we care about are SSHTunnels (you want this on the client end) and UpTokenReceiver (you want this on the server.)
For a fun and effective demo of the power of SSHTunnels, use a configuration file like the following:
<?xml version="1.0" encoding="utf-8"?> <SSHTunnels LogOutput="stderr" SleepTimer="5"> <Tunnel UpTokenEnabled="true"> <ProgramArgument v="/usr/bin/ssh" /> <ProgramArgument v="-R" /><ProgramArgument v="22201:localhost:22" /> <ProgramArgument v="myserver.example.com" /> <ProgramArgument v="UpTokenReceiver" /> </Tunnel> </SSHTunnels>
Place the config file in /usr/local/etc/SSHTunnels_config.xml on your laptop, then launch SSHTunnels.
You should see output like this:
[alex@fedberry SSHTunnels]$ SSHTunnels SSHTunnels: Info: XML Config Parser: Parsed <Tunnel> declaration with 5 <ProgramArgument> tag(s) and 0 <ProgramEnvironment> tag(s). SSHTunnels: Info: Tunnel 1: Creating tunnel object... SSHTunnels: Info: Tunnel 1: Launching child process: /usr/bin/ssh -R 22201:localhost:22 myserver.example.com UpTokenReceiver SSHTunnels: Info: Tunnel 1: Child process launched with PID 4171 SSHTunnels: Info: Tunnel 1: STDERR: UpTokenReceiver: Info: Received Header Version 1. Uptoken Interval is 15. SSHTunnels: Info: Tunnel 1: STDERR: UpTokenReceiver: Info: Header parsing finished. Listening for UpTokens...
So far so good! SSHTunnels has parsed the XML file, launched ssh with the reverse port binding flag, and successfully established contact with the UpTokenReceiver on the server.
Now try logging in to your laptop from your server:
[alex@mylaptop ~]$ ssh email@example.com firstname.lastname@example.org's password: Last login: Thu May 12 19:42:38 2016 from somehost [alex@myserver ~]$ ssh -p 22201 alex@localhost alex@localhost's password: Last login: Thu May 12 19:45:13 2016 from somehost [alex@mylaptop ~]$ whoami alex [alex@mylaptop ~]$
Yup! You can log right into your laptop from your server via the SSH tunnel.
Note that the real magic here is the amazing tunneling features built in to the OpenSSH client/server project — SSHTunnels didn’t really provide anything here that didn’t come out of the box, except the ability to monitor and manage tunnels automatically under the assumption that network conditions are going to be exceptionally hostile.
…Now, as it turns out “exceptionally hostile” is exactly what network conditions turn out to be in your average industrial Internet of Things deployment. My project included a mixture of serial ports, integration with legacy hardware, and a wide variety of last-mile network configurations, all of which are configured according to different security requirements and differing schools of thought. In short, when dealing with industrial IoT, some of the comfortable assumptions one tends to accumulate about how things “should just work” on the Internet get kicked right to the curb.
Clearly I’m not recommending that you forward all of your IoT traffic over SSH. That would be silly. There are plenty of more suitable protocols for that. But if (and when) you need SSH for advanced troubleshooting, as in our case, you may find SSHTunnels helpful.
I hope you do. 🙂