🌻Infrastructure And OperationsReverse-Tunnel

This is how I set up local machine behind a NAT to host an app for cyberia.

First I created a reversetunneler user on the capsul elliot.cyberia.club. I generated an SSH key pair for the reversetunneler, and then added the public key to the /home/reversetunneler/.ssh/authorized_keys file on elliot.

Next, I logged into elliot and aquired its SSH host public keys

root@elliot:~# ssh-keyscan elliot.cyberia.club 2>/dev/null

elliot.cyberia.club ssh-ed25519 AAAAC3NzaC1lZDI1NTE5AAAAIDFdXqpAH3HMIRiVL5SMoGo9TyuKxDHVqATxCTZ2/eQD
elliot.cyberia.club ssh-rsa AAAAB3NzaC1yc2EAAAADAQABAAABAQDLvnRuOZrs8fOspnfhLXvcHrC183+w6tegsBjn/oXu+8YmjecTFaC+cxNToanrRu3pAd2r9POnIFwHs/NePzANiw+EpV4ydmWde81O/lscOFFBBWuQW1hqkoBjcSEBqoola7PCnT57H54h/Eh01OBfPc9fq9SS1fQ6u0EhbhqQl8MXy0+E/m8Ev4hCiIR5LO+npxzXi1GW2Pj2ghEzYmpdTqkblVlG7Bte/XvuAWo8Liy4qCkr0KyLfoz6lm+OTBs+QN4MthEI0D1BOdGbM8suMFbUEPCFpbuhp6A1DuLEXF1LwAEYVzlTpcw5/wEjWcuTL7vm9pvHYkqm1ZigUtVf
elliot.cyberia.club ecdsa-sha2-nistp256 AAAAE2VjZHNhLXNoYTItbmlzdHAyNTYAAAAIbmlzdHAyNTYAAABBBHteD5qC7AHJ+LWF5/mQWhyC3DsPrlK5xaSl5vODZtqQyh2RtKvUFbs3KEUYxjssbdBVCbp3Yz6yROi4v0ElIAA=

And saved them to a file called known_hosts inside /opt/reversetunnel-to-elliot/ on the server that I want to expose on the internet. This way when the SSH client connects to elliot, it can have its own trustworthy record of elliots public keys, making the connection secure. But at the same time, this reverse tunnel SSH command can be isolated from your user's normal ~/.ssh/known_hosts file.

Next I also saved the generated ssh private and public keys to /opt/reversetunnel-to-elliot/ on the server that I want to expose on the internet.

Finally, I created this systemd service and then enabled it:

forest@beet:~$ cat /etc/systemd/system/reversetunnel-to-elliot.service
[Unit]
Description=ssh client reverse tunnel to elliot.cyberia.club in order to publish the btcpay server port
After=network.target

# files on beet/magnataur:
# this file /etc/systemd/system/reversetunnel-to-elliot.service
# /opt/reversetunnel-to-elliot/reversetunneler_ed25519
# /opt/reversetunnel-to-elliot/reversetunneler_ed25519.pub
# /opt/reversetunnel-to-elliot/known_hosts

# files on elliot:
# /home/reversetunneler/.ssh/authorized_keys

[Service]
ExecStart=/usr/bin/ssh -v -NT -i /opt/reversetunnel-to-elliot/reversetunneler_ed25519 -o UserKnownHostsFile=/opt/reversetunnel-to-elliot/known_hosts -o IdentitiesOnly=yes -o ServerAliveInterval=60 -o ExitOnForwardFailure=yes -R 127.0.0.1:3000:127.0.0.1:3000 reversetunneler@elliot.cyberia.club

# Restart every >2 seconds to avoid StartLimitInterval failure
RestartSec=5
Restart=always

[Install]
WantedBy=multi-user.target

Finally, I logged into elliot and edited the Caddy configuration file /etc/caddy/Caddyfile to add a stanza to route desired domain to the reverse tunneled port 3000.

btcpay.cyberia.club {
  reverse_proxy http://localhost:3000

  log {
    output file /var/log/caddy/access.log {
      roll_size 256kb
      roll_keep 2
      roll_keep_for 24h
    }
  }
}