Close the public door

SSH taken off the internet and kept on the tunnel only, checked from outside, proven to survive a reboot, with the way back in written down before you need it. The server's only open port is now WireGuard's, which answers nothing to anyone without a key.

intermediate~15 min hands-on
#wireguard#ssh#ufw#firewall#debian#ovh#security

Not validated end to end yet — be the first.Report a problem

Draft — not yet run end to end. This page was written but its author has not yet run it on a real machine. Commands may be wrong: read before you run, and tell us what breaks.

The gistOne door left, and it is mute
Your VPS
UDP TCP /tcp ✕
Your Macssh
The internet's botsscans
Firewall/udp
wg0
sshd: via wg0

From the internet, only ${WG_PORT}/udp is open, and it answers nobody without a key. SSH is reached at ${WG_SERVER_ADDR}:${SSH_PORT}, inside the tunnel. The KVM console is the way back in.

The tunnel works: SSH no longer needs to be on the internet. This page opens SSH on the tunnel interface, removes the public rule, checks from outside that the door is really closed, and reboots the server to prove everything comes back on its own. Before closing, it puts the way back in somewhere safe: the KVM console, and a copy of your keys.

Before you start

Check
$ssh  echo via-wireguard
Expected output
via-wireguard

Keep the way back in

After this page, two things open the server: your Mac (its WireGuard key and its SSH key), and the KVM console in the OVH control panel. Check the second one now, and make a copy of the first.

Then store in your password manager:

  • the SSH key (the private file, already encrypted by its passphrase);
  • the tunnel configuration, exported from the WireGuard app on the Mac (menu Tunnels or File → Export Tunnels to Zip…).

Take a snapshot

Open SSH on the tunnel only

In your ssh session, allow SSH on the wg0 interface, then remove the public rule:

Server·
$sudo ufw allow in on wg0 to any port proto tcp
$sudo ufw delete allow /tcp
$sudo ufw status verbose

ufw status must now show two rules (plus their (v6) twins): /udp ALLOW IN Anywhere and /tcp on wg0 ALLOW IN Anywhere.

Check from outside

From your Mac, try the public door: it must not answer. Then go back through the tunnel:

Mac
$nc -z -G 5 >/dev/null 2>&1 && echo "public door: STILL OPEN" || echo "public door: closed"
$ssh echo via-wireguard
Check
$nc -z -G 5   >/dev/null 2>&1 && echo open || echo closed
Expected output
closed

Remove the vps shortcut

ssh vps leads nowhere now. Remove its block from ~/.ssh/config, keeping a copy:

Mac
$cp ~/.ssh/config ~/.ssh/config.bak
$awk '/^Host[[:space:]]/ { skip = ($2 == "vps") } !skip' ~/.ssh/config.bak > ~/.ssh/config

Prove it survives a reboot

A setting that does not survive a reboot will lock you out one day, on the night of an automatic update. Reboot now, while you are watching:

Macwill ask you something
Sensitive command — reboots or powers off the machine. Review before running.
$ssh -t sudo systemctl reboot

Wait a minute, then:

Check
$ssh  systemctl is-active wg-quick@wg0
Expected output
active

If the tunnel breaks

Get in through the KVM console and reopen SSH while you repair

In the OVH control panel, open the KVM console, log in as with your password. Reopen the public door:

Server·
$sudo ufw allow /tcp

You can now get in from your Mac through the public address, with your key, and diagnose in comfort:

Mac
$ssh -p -i -o IdentitiesOnly=yes @

On the server, sudo systemctl status wg-quick@wg0, sudo wg show and journalctl -u wg-quick@wg0 almost always tell what is wrong. Once ssh is back, close again: sudo ufw delete allow ${SSH_PORT}/tcp.

If you lost the Mac

On the new computer, import the exported tunnel and the SSH key stored above: everything works again, nothing to change on the server. Then revoke the old Mac, since its WireGuard key still exists somewhere: generate a new pair in the app, replace PublicKey in the # mac block of /etc/wireguard/wg0.conf, sudo systemctl restart wg-quick@wg0, and remove the old SSH key from ~/.ssh/authorized_keys.

Without a copy of the keys, the KVM console remains: reopen the public door as above, then add the new SSH public key to ~/.ssh/authorized_keys. Typing it in the console is painful (and sensitive to the keyboard layout); OVH's rescue mode lets you edit the file from another system.

What is still visible

Seen from the internet, your server now answers ping, and nothing else. Port /udp is open, but mute to anyone without a key.

Done

WhatBeforeAfter this page
Ports open to the internet/tcp, /udp/udp only, mute without a key
SSHreachable from the whole internetthrough the tunnel only, ssh
After a rebootuntestedproven
Way back inKVM consoleKVM console, keys stored, step back in one command

The server is now private: only your devices get in. The rest of the series installs what should live there, listening only on .

Did everything work?

If you followed this page to the end on a real machine, say so. Your validation is dated and records your stack, so the next reader on the same path knows it still works.

This copy is read-only. To report that it works, or that it does not, open an issue

Only your stack choices are recorded, never your values. The pseudonym stays on this browser.