<!DOCTYPE html>
Automatic Firefox ssh
Proxy 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.
Abstract
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.
Context
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 ssh
was: 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 evily2k@102.2.115.73
# 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 evily2k@102.2.115.73
My Mistake
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 evily2k@102.2.115.73
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 evily2k@102.2.115.73:12345
# STEP 2
firefox -P -no-remote
# STEP 3
ssh -p 12345 -o ControlPath=/tmp/socks.%n.%p.%r -O exit evily2k@102.2.115.73
When I ran this script I was provided this error:
Control socket connect(/tmp/socks.102.2.115.73: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 evily2k@102.2.115.73:12345
—should have read:
ssh -p 12345 -M -o ControlPath=/tmp/socks.%n.%p.%r -f -N -D 8123 -C evily2k@102.2.115.73
The Correction
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 evily2k@102.2.115.73
# 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 evily2k@102.2.115.73
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:
- Substitute
102.2.115.73
for your remote home computer's public IP address. - Substitute
evily2k
for the user name of the remote home computer runningssh
(note: I am assuming you already know how to usessh
to establish a remote connection; I refer to this guide to remind me how to set up GnuPG to work withssh
on a new Debian instalation). - Substitute
firefox
for/home/evily2k/Downloads/firefox/firefox
(depending on where you extracted the Firefoxtar.bz2
file and location of thefirefox
executable file). - Create and configure a Firefox profile to use SOCKS5 in "Connection Settings" at
127.0.0.1
and port8123
and delete all other profiles. - Substitute
-p 12345
according to your remote home computer's router port forwarding settings (ex: route external port 12345 traffic to your home computer's static IP address of192.168.0.4
at port 22).
How I found the mistake
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.102.2.115.73: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.%a
, ControlPath=/tmp/socks.%n.%p.%r.%b
, 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 a
alone).
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.
Summary
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.
This work is licensed under a Creative Commons Attribution-ShareAlike 4.0 International License.