home

How To Create a Remote SSH Gateway to a Local OpenBSD Server

Hosting a server on your local network can provide many advantages, such as access to the physical hardware and easy interaction with other devices on the network. However, by default you will not be able to access it from outside that network.

I recently set up a OpenBSD server on a Thinkpad T60, and I have multiple users connecting to it for development as well as recreational use (I have installed a few CLI games for fun). It is hosted on my university's network, so users can connect to it locally from anywhere on campus. I also wanted to be able to access it remotely as well through the internet. To achieve this, I set up a reverse SSH tunnel on the Thinkpad using autossh, and I have it running as a daemon now.

In order to do this, first you must first have a server connected to the internet (I am using a Vultr VPS instance running Debian 11). It is fairly straightforward from there.

Step 1: Modify the remote server's sshd configuration

Add the following lines to your sshd config (on my machine it is in /etc/ssh/sshd_config:

AllowTcpForwarding yes
GatewayPorts yes

Step 2: Add a user on the remote server for tunnelling

Now, it is necessary to add a user on the remote server for the local one to connect to, and generate a SSH key for the new user.

# add the user
useradd -m sshfwd

# generate a ssh key for the user
su sshfwd
ssh-keygen

Afterwards, copy the public key in your local machine (it should be in ~/.ssh/id_rsa.pub) to your remote server and add it to /home/sshfwd/.ssh/authorized_keys (you can just copy it to that file since it will not even exist for a new user).

Step 3: Open a port for the tunnel

I am using ufw as a firewall on my remote server, and I highly recommend it. On Debian using ufw, the following should open a port for your ssh tunnel. You can pick any unused port.

ufw allow PORT
service ufw restart

Step 4: Create autossh tunnel daemon on the local server

This is probably the most involved part. I wrote a one line script called sshtund, and put it in /usr/local/bin. autossh is not installed on OpenBSD 7.2 by default, so it is necessary to install it by running pkg_add autossh.

Here is the autossh command:

#!/bin/sh
autossh -M 0 -o "ExitOnForwardFailure yes" -o "ServerAliveInterval 30" \
	-o "ServerAliveCountMax 3" -o "TCPKeepAlive yes" -N -v \
	-R PORT:localhost:22 sshfwd@REMOTE_IP &

autossh ensures that the tunnel doesn't go down, as it will attempt to reconnect if the connection is lost.

Step 5: Create and start the daemon

Create a rc file for the tunnel on the local machine at /etc/rc.d/sshtund:

#!/bin/ksh

daemon="/usr/local/bin/sshtund"

. /etc/rc.d/rc.subr

pexp="sshtund: ${daemon}${daemon_flags:+ ${daemon_flags}} \[listener\].*"

rc_configtest() {
        ${daemon} ${daemon_flags} -t
}

rc_cmd $1

Then run rcctl start sshtund to start the tunnel. You should now be able to connect to your local server anywhere via ssh -p PORT user@REMOTE_IP, using the username on your local server.