Reverse SSH connection
— 577 words — 3 min
Table of Contents
I have a raspberry pi which is running pihole and some other things and I want to be able to connect to it from wherever I am without exposing it directly to the internet. So, I thought I could make this possible with an SSH connection form my raspberry pi to my VPS and, at the same time, forwarding the SSH port. Then I can use my VPS as a jumphost by connecting to the VPS and then to the forwarded SSH port from pi.
Generating SSH key pairs🔗
First, let’s generate the needed key pairs for the vps and the raspberry pi. I
like to create folders in .ssh
to keep my keys sorted.
I use Curve 25519 for pubkey authentication.
Generate two keys. My directory structure looks like this
-- .ssh/
|- config
|- pihole/
|- id_ed25519
|- id_ed25519.pub
|- vps/
|- id_ed25519
|- id_ed25519.pub
with the following SSH config
Host vps
HostName VPS_IP
User USERNAME
Port PORT
IdentityFile ~/.ssh/vps/id_ed25519
Host pihole
HostName LOCAL_IP
user USERNAME
IdentityFile ~/.ssh/pihole/id_ed25519
Great, now I can connect to my vps with ssh vps
and to my raspberry pi with
ssh pihole
.
Raspberry Pi🔗
I want to make sure that my raspberry pi is always connecting to my vps, e.g. if SSH crashed or if I restarted my pi. I use a systemd service and SSH public key authentication to accomplish this.
Go to /etc/systemd/system/
and create a ssh-reverse.service
file with the
following content:
[Unit]
Description=Reverse SSH connection
After=network.target
[Service]
Type=simple
ExecStart=/usr/bin/ssh -vvv -g -N -T -o "ServerAliveInterval 10" -o "ExitOnForwardFailure yes" -R 22221:localhost:22 -l USERNAME -p PORT -i /home/USERNAME/.ssh/id_ed25519 VPS_IP
Restart=always
RestartSec=5s
[Install]
WantedBy=default.target
Replace USERNAME
, PORT
, VPS_IP
and the path to the IdentityFile
(-i
)
with your values.
A few important options (more info: man ssh_config
)
-R 22221:localhost:22
This forwards the SSH port on my pi (localhost:22
) to the port22221
on my vpsExitOnForwardFailure yes
If forwarding of the port fails, we want to exitServerAliveInterval 10
My pi sends a packet every 10 seconds to keep the connection alive
If this unit is not running, we try restarting the connection every 5 seconds. Make sure, that you already accepted the public key of your VPS on the raspberry pi by connecting to it manually. Otherwise the systemd unit will fail over and over again.
Then enable the service
SSH configuration🔗
Let’s write the SSH configuration to connect to the raspberry pi via the VPS.
The configuration for the connection to the VPS is already in place and, in my
case, it’s called vps
. So, if I do ssh vps
I will be connected to my VPS.
Great. Now let’s use the VPS as jump host.
Write a new Host configuration in ~/.ssh/config
. I called it pihole-remote
so that I can still connect to my raspberry pi via ssh pihole
in my LAN when
I’m home.
Host pihole-remote
ProxyJump vps
HostName localhost
user PI_USER
Port 22221
IdentityFile ~/.ssh/pihole/id_ed25519
LocalForward 8888 localhost:80
Now I can connect to my raspberry pi by using my VPS as a jump host. I’m also
fowarding localhost:80
to 8888
, so that I can access my pihole webinterface
in my browser whenever I am connected to my pi with SSH.
Articles from blogs I follow around the net
Status update, July 2024
Hi! This month wlroots 0.18.0 has been released! This new version includes a fair share of niceties: ICC profiles, GPU reset recovery, less black screens when plugging in a monitor on Intel, a whole bunch of new protocol implementations, and much more. Thanks…
via emersion July 16, 2024Whose CIDR is it anyway?
A look at CIDR block ownership from a RIR-, country-, and organization level. Originally presented at RIPE88.
via Signs of Triviality June 12, 2024How and why to make a /now page on your site
Background I used to wonder what my friend Benny Lewis was doing. He has a website and social media accounts, but neither gave an overview of what he’s doing now. Then I realized some people might wonder the same about me. So in 2015, I made a /now page on my…
via Derek Sivers blog May 18, 2024Generated by openring