SSH tunneling as a VPN alternative

Jul 16 · 3 min read

It’s not uncommon that VPN connection to our client’s boxes either breaks mid testing or is blocked by some firewall or IDS. SSH tunneling can be used as a back up connection to already existing VPN connection or as a decent lightweight alternative.

Things we’ll need:

  1. AWS instance for pivoting
  2. Target box on the network we are ̶h̶a̶c̶k̶i̶n̶g̶ testing.

First, we need to set up the AWS instance to use as the initial jump box:

  1. Open port 8080 in the security rules
  2. Create new user: adduser revconnect (or whatever user name) and give the user sudo privileges: usermod -aG sudo revconnect
  3. sudo su revconnect
  4. Run ssh-keygen for that user. I’d recommend using non default name for the key to avoid conflicts.
  5. Make sure there is an authorized_keys file in revconnect/.ssh with your keys in it.
  6. Enable GatewayPorts: in /etc/ssh/sshd_configset GatewayPortsto yes

Next, create the script to be executed on the client’s box. The script will be password protected and served to the client at the end. All the client would need to do is to curl the script and pipe it to bash. Lets go:

  1. Create ~/www/
  2. In order to build the script we first need to set up a couple variables:

Get base64 of the public key:

PUBLIC_KEY_B64="$(cat /home/revconnect/.ssh/ | base64 -w 0)"

echo "PUBLIC_KEY_B64='${PUBLIC_KEY_B64}'"

Encrypt the keys:

cat /home/revconnect/.ssh/your_key | openssl enc -aes-256-cbc -in — -out your_key.enc

Get base64 of that:

B64_KEY="$(cat your_key.enc | base64 -w 0)";

echo "ENCRYPTED_KEY_B64='${B64_KEY}'"

Add the variables to the script:

You could totally do without encryption, but we are all about security here😏.

Next, check if .ssh folder exists and create it, if it doesn’t:

We then grab the encrypted key we created, decode it on the other end, and change permissions to 400 to protect it against accidental overwriting.

add it to the authorized_keys file

Next, we want to set up tunnel as systemd service. Inspiration for this part is taken from this gist I found:

Lastly, we reload the daemon and start the tunnel:

Cool, the script is done. Lets password protect the file:

cat /home/revconnect/.ssh/your_key | openssl enc-aes-256-cbc -in — -outyour_key.enc

and serve the script to the client: cd ~/www && python3 -m http.server 8080

Now we can ask our client to run the script, or you run it on the target box if you have access to it: curl “http://aws_ip:8080/” | bash

The script will prompt to enter the password you created for

Once the client (or you) ran the script and the tunnel is created, you can ssh into the AWS instance, then run ssh -p 2222 root@localhost

Done! If you get permission denied error, your keys probably don’t match. Try to use the same key consistently on your local machine, AWS instance and the target box.

Good luck!

Welcome to a place where words matter. On Medium, smart voices and original ideas take center stage - with no ads in sight. Watch
Follow all the topics you care about, and we’ll deliver the best stories for you to your homepage and inbox. Explore
Get unlimited access to the best stories on Medium — and support writers while you’re at it. Just $5/month. Upgrade