From time to time I have to expose ports of machine that doesn't have publicly accessible address/interface. Since I don't have public static IP in my homelab it helps me to forward http/s ports via cheap VPS that I delegate domains to.

It is wise to run service under dedicated and unprivileged user so lets create one

useradd autossh -g nogroup -s /bin/false -m /etc/autossh autossh

We will use SSH key to connect to remote machine

sudo -u autossh ssh-keygen -t ed25519 -C autossh

Next let's define host that we will be forwarding ports to (or from)

Host    homelab-vps
        HostName        10.10.10.10
        User            root
/etc/autossh/.ssh/config

Now lets test connection. Additionally our machine will be added to known_hosts

sudo -u autossh ssh homelab-vps

Before closing connection we have to modify /etc/ssh/sshd_config on machine we will be forwarding ports to by adding "GatewayPorts yes".

Systemd unit will allow us to start tunnel automatically with operating system

cat > /etc/systemd/system/[email protected] << EOF
[Unit]
Description=Keeps an ssh tunnel to %I open
After=network-online.target ssh.service

[Service]
User=autossh
# no monitoring
Environment="AUTOSSH_PORT=0"
# Disable gatetime behaviour
Environment="AUTOSSH_GATETIME=0"
# Enable logging
Environment="AUTOSSH_DEBUG=1"
Environment="AUTOSSH_LOGFILE=/var/log/autossh/%i.log"
EnvironmentFile=/etc/autossh/%i.conf
RestartSec=3
Restart=always

# -NT Just open the connection and do nothing (not interactive, no tty alloc)
# use /usr/bin/ssh instead of autossh is good as well
ExecStart=/usr/bin/autossh -NT -o "ExitOnForwardFailure=yes" $SSH_OPTIONS ${TARGET_HOST} $FORWARDS
TimeoutStopSec=10

[Install]
WantedBy=multi-user.target
EOF

For each connection we should create config file

cat > /etc/autossh/homelab-vps.conf << EOF
TARGET_HOST=homelab-vps
FORWARDS=-R 80:localhost:80 -R 443:localhost:443
SSH_OPTIONS=-o "ServerAliveInterval=10" -o "ServerAliveCountMax=3"
AUTOSSH_PORT=0
AUTOSSH_GATETIME=0
EOF

Finally, to activate tunnel:

systemctl enable autossh@homelab-vps
systemctl start autossh@homelab-vps

We can of course forward ports in different direction - from remote to local machine.

This time we have to modify ssh server config on machine that will be used to forward ports. One thing to note: privileged ports (1-1023) can only be forwarded by root, in this scenario we will use dynamic port

cat >> /etc/ssh/sshd_config << EOF
Match User autossh
    PasswordAuthentication no
    GatewayPorts yes
EOF

cat >> /etc/autossh/.ssh/config << EOF
Host    mariadb
        HostName        10.1.1.50
        User            root
EOF

Config in such scenario may look like this (in case of mysql or mariadb there's a reason not to use localhost - all connection will be seen as coming from it by dbms)

cat >> /etc/autossh/mariadb.config << EOF
TARGET_HOST=mariadb
FORWARDS=-L 0.0.0.0:3306:10.1.1.50:3306
SSH_OPTIONS=-o "ServerAliveInterval=10" -o "ServerAliveCountMax=3"
AUTOSSH_PORT=0
AUTOSSH_GATETIME=0
EOF