sshProxy Script, Lesson Learned
Created by Steven Baltakatei Sandoval on 002019-08-16T05:06:42Z under a CC BY-SA 4.0 license and last updated on 2019-08-16T08:22:33Z.
I mistakenly thought I encountered a bug in
ssh while testing bash scripts to automatically fire up an instance of Firefox that sends its traffic through a remote proxy. I mistakenly thought this imaginary bug had to do with how
ssh performs variable substitution in its
ControlPath parameter. However, the real bug was in my script.
To be more verbose, I thought I encountered a bug in OpenSSH while constructing a bash script to automatically launch Firefox under a SOCKS5 proxy for the purpose of being able to make edits to Wikipedia from my home's internet connection despite using a VPN while travelling abroad. Wikipedia blacklists ranges of ISP addresses which also happen to include my VPN provider. According to
$ ssh -V, my version of
OpenSSH_7.9p1 Debian-10, OpenSSL 1.1.1c 28 May 2019. I found a useful bash script in this Reddit post by user /u/anthropoid. It is a useful script that would be useful to many people:
#!/bin/bash # STEP 1: Start an SSH master connection (-M) # in the background (-f) # without running a remote command (-N) ssh -M -o ControlPath=/tmp/socks.%n.%p.%r -f -N -D 8123 -C firstname.lastname@example.org # STEP 2: Launch Firefox in the foreground firefox -P -no-remote # STEP 3: When user is done with Firefox, send an "exit" command to the master connection ssh -o ControlPath=/tmp/socks.%n.%p.%r -O exit email@example.com
However, I needed to modify two lines in this script. I needed to supply a
-p <port number> flag to both the "STEP 1" and "STEP 3" commands in order to accomodate my home router's configuration. I had configured my home router's port forwarding settings to send inbound traffic it received on a specific port (ex: port "12345") to a specific IP address within my home's local network. This IP address was an IP address I had told my router to always assign to my primary home computer. I had to supply this
-p 12345 flag whenever I needed to remotely log into my home computer via GnuPG and SSH. For example, I might use the following
ssh command to log in.
$ ssh -p 12345 firstname.lastname@example.org
So, I modified the two lines and added the
-p flag. Below is the bash script (with comments removed for clarity).
#!/bin/bash # STEP 1 ssh -p 12345 -M -o ControlPath=/tmp/socks.%n.%p.%r -f -N -D 8123 -C email@example.com:12345 # STEP 2 firefox -P -no-remote # STEP 3 ssh -p 12345 -o ControlPath=/tmp/socks.%n.%p.%r -O exit firstname.lastname@example.org
When I ran this script I was provided this error:
Control socket connect(/tmp/socks.188.8.131.52:12345.12345.evily2k): No such file or directory
This is because I made a mistake in modifying STEP 1. This line:
ssh -p 12345 -M -o ControlPath=/tmp/socks.%n.%p.%r -f -N -D 8123 -C email@example.com:12345
—should have read:
ssh -p 12345 -M -o ControlPath=/tmp/socks.%n.%p.%r -f -N -D 8123 -C firstname.lastname@example.org
Now that I discovered my mistake, a working bash script allowing me to
ssh home through my port forwarding router is:
#!/bin/bash # STEP 1: Start an SSH master connection (-M) # in the background (-f) # without running a remote command (-N) ssh -p 12345 -M -o ControlPath=/tmp/socks.%n.%p.%r -f -N -D 8123 -C email@example.com # STEP 2: Launch Firefox in the foreground firefox -P -no-remote # STEP 3: When user is done with Firefox, send an "exit" command to the master connection ssh -p 12345 -o ControlPath=/tmp/socks.%n.%p.%r -O exit firstname.lastname@example.org
This script works. Feel free to skip the rest of this document if all you need is a working script. To customize it for your purposes, you might do the following:
184.108.40.206for your remote home computer's public IP address.
evily2kfor the user name of the remote home computer running
ssh(note: I am assuming you already know how to use
sshto establish a remote connection; I refer to this guide to remind me how to set up GnuPG to work with
sshon a new Debian instalation).
/home/evily2k/Downloads/firefox/firefox(depending on where you extracted the Firefox
tar.bz2file and location of the
8123and delete all other profiles.
-p 12345according to your remote home computer's router port forwarding settings (ex: route external port 12345 traffic to your home computer's static IP address of
192.168.0.4at port 22).
If you really want more details on this particular story, continue reading. I started my troubleshooting process by attempting to understand the error message that included the phrase "No such file or directory". At first, it appeared to me that there was a problem with how
ssh performed variable substitution in the
ControlPath parameter I supplied it. I had supplied
ControlPath=/tmp/socks.%n.%p.%r in both
ssh commands for STEP 1 and STEP 2 and yet the error message indicated that
ssh could not find the temporary file at
/tmp/socks.220.127.116.11:12345.12345.evily2k that it required in order to successfully perform the
exit command in STEP 3. I tried changing the percent variables in
ControlPath=/tmp/socks.%n.%p.%r to things like
ControlPath=/tmp/socks.%n.%p.%r.%c, and so forth in order to see how the error messages changed. I learned that
%C produces what looks like a hash but most letters are blank. There are no multi-letter substitutions (ex:
%aa only substitutes the
%a part, leaving the second
In any case, I rewrote the script from scratch with a different
ControlPath and ended up coincidentally writing the script without the superfluous
:12345. I then mistakenly thought that it was the
ControlPath change I made that allowed the script to work and, therefore, there was a problem with OpenSSH. I had a script that opened an
ssh proxy, started up Firefox, and then closed the
ssh connection when I closed Firefox. I stopped my troubleshooting and left somewhat satisfied that I had:
a working script
a potential bug in OpenSSH
I didn't discover the "bug" was caused entirely by my own mistake until after I spent a day doing other activities unrelated to this particular problem. After time passed, I decided to write up this "bug" in a blog post since I thought other people might also encounter this problem and I wanted to help them out. In order to make sure the information I provided was useful, I tested a few assumptions such as "The script as I have written it in this blog post draft actually reproduces the exact problem I am describing". I had clear memories of seeing the bug but when I made the change (adding
-p 12345) that I thought would cause the bug to appear the script worked flawlessly. The script I tested for this blog post was copy-pasted from the reddit post so if my assumption was correct, the script should have reproduced the bug. The bug was not reproduced. The bug was not reproduced because in applying my customizations to the original script I only applied the specific change I needed to which was adding
-p 12345. I didn't add the
:12345. It was at that point that I realized the root cause of the failure was myself. I compared the blog draft script with the script I had actually run and found the extra
:12345 where it should not have been. The root cause of my problem in getting the script to initially work was my failure to identify the extra
:12345 at the end of the STEP 1 command.
I had mistakenly included
:12345 because I am a novice programmer and my method of learning unfortuantely involves playing with commands to see what works and what causes problems. Using
ssh in this new context (using it as a SOCKS5 proxy) meant I was adding and taking away parameters to see what broke. The
:12345 was one of those experimental parameters that I had forgotten about. My strategy is usually to repeat such command formatting experiments until I find a command that works incrementally better than the previous failure. I use search engines to look up error messages I receive in order to find stories of people in similar situations as me. Writing up my thoughts in this blog post is another way in which I perform these experiments. When composing this document I am forced to create my own story which requires discarding irrelevant details, identifying relevant details, and then integrating the most important details of my troubleshooting experience into a story whose assumptions I can test. In this case my experimental learning strategy succeeded in producing a useful script even if it did do so in a meandering way.
I made a mistake in customizing a bash script to automatically start up
ssh as a SOCKS5 proxy and start up Firefox to use this proxy. I initially thought this mistake might have been caused by a bug in OpenSSH itself but I eventually found that it was due to my inexperience with formatting
ssh commands. I made this blog post to show a working bash script with the customization for my particular context (I need an
-p 12345 flag because I have to
ssh through a port forwarding router) for others to benefit as well as to explain one wild goose chase I ended up having to running before my understanding of
ssh strengthened to be able to see my formatting error.
Note: I am not user
evily2k. I preserved this user name in script examples to match the Reddit post from which my customized script originates.