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)
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