Damit SSH nur über WireGuard erreichbar ist, startest du die Schnittstelle wg0 mit wg-quick, weist jedem Client per AllowedIPs eine Adresse zu und beschränkst Port 22 auf dieses Netz: entweder mit ListenAddress in der sshd_config oder mit einer ufw-Regel, die TCP 22 nur annimmt, wenn es über wg0 ankommt. Von außen ist am Server dann nur der UDP-Port von WireGuard sichtbar.

Wie WireGuard die Angriffsfläche eines SSH-Servers verändert

OpenSSH lauscht standardmäßig auf TCP-Port 22 und, sofern nicht anders konfiguriert, auf allen Schnittstellen, einschließlich der öffentlichen. Mit WireGuard davor ist der einzige zum Internet offene Port der UDP-Port des Tunnels, und WireGuard antwortet nicht auf Pakete, die nicht mit einem bekannten Schlüssel signiert sind. Ein Scan sieht also nichts.

Das Setup in diesem Artikel verwendet 10.8.0.0/24: Der Server ist 10.8.0.1, das Smartphone oder der Laptop 10.8.0.2. SSH nimmt Verbindungen nur auf 10.8.0.1 oder nur von der Schnittstelle wg0 an. Es gibt zwei Wege dorthin, und sie lassen sich gut kombinieren: sshd mit ListenAddress an die Tunneladresse binden oder mit ufw nach Schnittstelle filtern.

WireGuard mit wg-quick und AllowedIPs für SSH konfigurieren

wg-quick liest /etc/wireguard/wg0.conf, erstellt die Schnittstelle, weist die Adresse zu und legt Routen für jeden in AllowedIPs aufgeführten Bereich an. Erzeuge zuerst die Schlüssel mit restriktiven Berechtigungen:

umask 077
wg genkey | tee server.key | wg pubkey > server.pub

Serverkonfiguration:

# /etc/wireguard/wg0.conf (server)
[Interface]
Address = 10.8.0.1/24
ListenPort = 51820
PrivateKey = <server private key>

[Peer]
# phone
PublicKey = <phone public key>
AllowedIPs = 10.8.0.2/32

Clientkonfiguration mit Split-Tunnel: Nur der Verkehr zu 10.8.0.1 läuft durch das VPN, alles andere nutzt die normale Verbindung.

[Interface]
Address = 10.8.0.2/32
PrivateKey = <phone private key>

[Peer]
PublicKey = <server public key>
Endpoint = server.example.com:51820
AllowedIPs = 10.8.0.1/32
PersistentKeepalive = 25

Auf dem Server wirkt AllowedIPs wie eine Zugriffsliste: Pakete dieses Peers werden nur mit der Quelladresse 10.8.0.2 angenommen. Auf dem Client legt es fest, welche Ziele durch den Tunnel geroutet werden; 0.0.0.0/0 würde alles hindurchschicken. Starten und dauerhaft aktivieren:

sudo wg-quick up wg0
sudo systemctl enable --now wg-quick@wg0
sudo wg show

Details zum Protokoll und zum Schlüsselaustausch findest du im offiziellen WireGuard-Quickstart.

SSH mit ListenAddress in der sshd_config auf wg0 beschränken

Die Direktive ListenAddress sorgt dafür, dass sshd seinen Socket nur auf der angegebenen Adresse öffnet; Port 22 verschwindet von der öffentlichen IP, sowohl für IPv4 als auch für IPv6.

# /etc/ssh/sshd_config
ListenAddress 10.8.0.1
PasswordAuthentication no

sudo sshd -t
sudo systemctl restart ssh   # sshd on other distributions

Der übliche Haken ist die Startreihenfolge: Startet sshd vor wg0, existiert die Adresse noch nicht, und sshd scheitert mit „Cannot assign requested address“. Abhilfe schafft ein systemd-Override (sudo systemctl edit ssh), das unter [Unit] [email protected] und [email protected] ergänzt. Bei Distributionen, die sshd über ssh.socket starten, kommt die Lauschadresse aus der Socket-Unit, nicht aus der sshd_config. Alle Optionen sind in der Manpage zu sshd_config dokumentiert.

SSH mit ufw auf wg0 beschränken: exakte Regeln pro Schnittstelle

Mit ufw lauscht sshd weiterhin überall, aber die Firewall lässt TCP 22 nur durch, wenn es über wg0 ankommt. Das hängt nicht von der Startreihenfolge ab und deckt auch Mosh ab, das die UDP-Ports 60000-61000 nutzt.

sudo ufw default deny incoming
sudo ufw default allow outgoing
sudo ufw allow 51820/udp
sudo ufw allow in on wg0 to any port 22 proto tcp
sudo ufw allow in on wg0 to any port 60000:61000 proto udp
sudo ufw delete allow OpenSSH
sudo ufw enable
sudo ufw status verbose

Wende diese Regeln aus einer Sitzung an, die bereits über den Tunnel läuft, und öffne eine zweite Verbindung zu 10.8.0.1, bevor du die erste schließt. Am robustesten ist ufw pro Schnittstelle plus ListenAddress: Fällt eine Schicht aus, hält die andere den Port weiterhin geschlossen.

SSH über WireGuard auf iOS und Android im Vergleich zum Desktop

Auf dem Smartphone baut die offizielle WireGuard-App den Tunnel als VPN-Profil des Systems auf, und der SSH-Client verbindet sich mit 10.8.0.1 wie mit jedem anderen Host. Die App kann das Schlüsselpaar auf dem Gerät erzeugen oder eine .conf über einen QR-Code importieren, der mit qrencode -t ansiutf8 < client.conf erstellt wurde.

Was verglichen wirdiOS / AndroidDesktop
Tunnel-ClientOffizielle WireGuard-App, VPN-Profil des Systemswg-quick oder die offizielle App
Konfiguration importierenQR-Code oder .conf-DateiDie .conf nach /etc/wireguard kopieren
Wechsel von WLAN zu mobilen DatenMosh hält die SSH-Sitzung am LebenSelten; einfaches SSH reicht meist
Esc, Strg, Tab und PfeiltastenBrauchen die eigene Tastatur des TerminalsPhysische Tastatur
Privater SSH-SchlüsselSicherer Speicher des Systems~/.ssh mit 700, Schlüssel mit 600

In termi1, dem mobilen SSH-Terminal, wird der Ed25519-Schlüssel auf dem Smartphone erzeugt und verlässt das Gerät nie; Mosh hält die Sitzung, wenn du von WLAN zu mobilen Daten wechselst, und tmux bewahrt alles, was du laufen gelassen hast. Ist die Verbindung zu 10.8.0.1 als Produktion markiert, hält Production Guard Befehle zurück, die etwas löschen oder stoppen, bevor sie den Prompt erreichen. Wenn du WireGuard-Schlüssel nicht von Hand verwalten möchtest, erfüllt ein Mesh wie ein privates Netzwerk ohne offene Ports oder Tailscale denselben Zweck.

4 Fehler beim Absichern von SSH innerhalb von WireGuard

  1. Den öffentlichen Port 22 ohne Fallback schließen. Fällt der Tunnel aus, bleibt nur die Konsole des Providers; prüfe vorher, dass sie funktioniert.
  2. Überlappende AllowedIPs zwischen Peers. Haben zwei Peers denselben Bereich, geht der Verkehr an den zuletzt deklarierten.
  3. Die UDP-Ports von Mosh vergessen. Mosh startet über SSH, aber ohne offene Ports 60000-61000 auf wg0 kommt die Sitzung nie zustande.
  4. Die sshd_config nicht validieren. Führe vor dem Neustart sshd -t aus; ein Syntaxfehler legt den Dienst lahm.

Häufig gestellte Fragen

Reicht WireGuard, ohne die SSH-Konfiguration zu ändern?

WireGuard allein schützt Port 22 nicht: sshd lauscht weiterhin auf der öffentlichen IP, und jeder kann versuchen, sich zu verbinden. Zusätzlich brauchst du ListenAddress mit der Tunneladresse oder eine ufw-Regel, die TCP 22 nur annimmt, wenn es über wg0 ankommt.

Was sollten die AllowedIPs des Clients nur für SSH enthalten?

Die AllowedIPs des Clients sollten nur die Tunneladresse des Servers enthalten, zum Beispiel 10.8.0.1/32. So leitet wg-quick nur diesen Verkehr durch das VPN, und normales Surfen läuft über die reguläre Verbindung. Mit 0.0.0.0/0 würde der gesamte Verkehr durch den Tunnel geleitet.

Funktioniert Mosh über WireGuard?

Mosh funktioniert über WireGuard, solange der Server UDP 60000-61000 auf wg0 annimmt. Mosh öffnet zuerst eine SSH-Verbindung, um mosh-server zu starten, und wechselt dann zu UDP. Port-Forwarding und X11-Forwarding beherrscht es nicht, dafür ist weiterhin klassisches SSH nötig.

Was passiert, wenn WireGuard ausfällt und SSH nur auf wg0 lauscht?

Fällt WireGuard aus, während SSH auf wg0 beschränkt ist, gibt es keinen SSH-Zugang aus dem Internet, bis der Tunnel wieder steht. Halte die Webkonsole des Providers bereit, aktiviere wg-quick@wg0 beim Booten und lass sshd per systemd erst nach dem Tunnel starten.