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, November 2024
Hi all! This month I’ve spent a lot of time triaging Sway and wlroots issues following the Sway 1.10 release. There are a few regressions, some of which are already fixed (thanks to all contributors for sending patches!). Kenny has added support for software-…
via emersion November 22, 2024Dismissed!
Dismissing gives me a quick little lift. “That guy is an idiot!” “That place sucks!” There. Now I feel superior. Now I don’t have to think about it. I don’t even need first-hand experience. I can just echo any complaint I’ve heard. I’ve done this with restaurants…
via Derek Sivers blog November 18, 2024Generated by openring