diff options
| author | rtk0c <[email protected]> | 2025-10-12 22:31:51 -0700 |
|---|---|---|
| committer | rtk0c <[email protected]> | 2025-10-12 22:31:51 -0700 |
| commit | 552bcdc848c8a272fc834f8ab9560f203037bbf7 (patch) | |
| tree | a432bec318c4a1d2a890e2262fee78dd34d9ddab | |
| parent | 387e4eb5f31fcb8f9ae570b73a01634de672243e (diff) | |
Hand rolled ngrok on protonvpn: sshd section initial draft
| -rw-r--r-- | content/blog/hand-rolled-ngrok-over-protonvpn.md | 97 |
1 files changed, 97 insertions, 0 deletions
diff --git a/content/blog/hand-rolled-ngrok-over-protonvpn.md b/content/blog/hand-rolled-ngrok-over-protonvpn.md new file mode 100644 index 0000000..55168bd --- /dev/null +++ b/content/blog/hand-rolled-ngrok-over-protonvpn.md @@ -0,0 +1,97 @@ +--- +title: "I paid for the whole vpn, so I'm damn well going to use the whole vpn" +tags: ["sysadmin"] +categories: ["Life of a sysadmin"] +draft: true +--- + +_Or: hand roll a ngrok with protonvpn port forwarding, for shits and giggles_ + +# Dumbness: port forward `sshd` + +Our general plan is this: +Bring up a wireguard tunnel to protonvpn as usual. +Bring up sshd as usual. +Port forward some public port to `10.2.0.2:22`, with `natpmpc(1)`. + +The first two steps are just the standard issue procedure, I won't go over it here. I'll assume the wireguard config is placed at `/etc/wireguard/protonvpn.conf`, so bringing it up is simply `wg-quick up protonvpn`. +Also remember to harden `sshd`, like disable password login and setup fail2ban. Otherwise you'll have a pretty bad day... + +First, the port forwarding logic. +It's a simple bash script `/usr/local/bin/protonvpn-update-port-mapping`, adapted from [here](https://github.com/giu176/ProtonVPN-auto-NATPMP/blob/main/natpmpc_script.sh). + +```bash +#!/bin/bash + +TMPFILE=/tmp/natpmpc_output + +# We can assume the exit node IP doesn't change +ip=$(curl -s --interface=protonvpn -4 icanhazip.com) +echo "$ip" > "$RUNTIME_DIRECTORY/public-ip" +ip6=$(curl -s --interface=protonvpn -6 icanhazip.com) +echo "$ip6" > "$RUNTIME_DIRECTORY/public-ip6" + +while true; do + natpmpc -a 1 22 udp 60 -g 10.2.0.1 > /dev/null \ + && natpmpc -a 1 22 tcp 60 -g 10.2.0.1 > $TMPFILE \ + || { + echo -e "ERROR with natpmpc command \a" + break + } + + port=$(grep 'TCP' $TMPFILE | grep -o 'Mapped public port [0-9]*' | awk '{print $4}') + rm $TMPFILE + + echo "$port" > "$RUNTIME_DIRECTORY/public-port" + + sleep 45 +done +``` + +In the script provided in [protonvpn docs](https://protonvpn.com/support/port-forwarding-manual-setup), natpmpc is called with privateport = 0, which means use the same port as the public port, allocated by the gateway. +Changing it to 22 makes it so that the gateway still chooses whatever it wants, but the privateport is always mapped to 22, on which sshd is listening. + +You'll notice we map UDP on line 12, in addition to TCP on line 13. +Indeed it's not necessary for sshd, but I'm going to reference this same script in the wireguard section below, which does need UDP. + +Second, a systemd service `/etc/systemd/system/protonvpn-natpmp.service`. +Note `[email protected]` is a template provided in the most linux distros just runs wg-quick on the pprovided config. +And setting `RuntimeDirectory` will create the `$RUNTIME_DIRECTORY` env var used by the script above. + +```ini +[Unit] +Description=ProtonVPN NAT-PMP port forwarding update + +[Service] +Type=exec +ExecStart=/usr/local/bin/protonvpn-update-port-mapping + +RuntimeDirectory=protonvpn-natpmp + +# Harden, because why not +ProtectSystem=strict +PrivateTmp=true +ProtectHome=true +PrivateDevices=true +ProtectKernelTunables=true +ProtectControlGroups=true + +[Install] +WantedBy=multi-user.target +``` + +Reload to pick up the new unit files. +Enable and immediately start both services: + +``` +# systemctl daemon-reload +# systemctl enable --now [email protected] protonvpn-natpmp.service +``` + +Read the public address under `/run/protonvpn`, now you should be able to ssh, from anywhere on the internet, to this machine. + +# Sillinessw: port forward wireguard + +TODO |
