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:

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:

  1. a working script

  2. 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.


🅭🅯🄯4.0
This work is licensed under a Creative Commons Attribution-ShareAlike 4.0 International License.