Pour que SSH ne soit joignable qu'à travers WireGuard, montez l'interface wg0 avec wg-quick, attribuez une adresse à chaque client avec AllowedIPs et limitez le port 22 à ce réseau : soit avec ListenAddress dans sshd_config, soit avec une règle ufw qui n'accepte le TCP 22 que s'il arrive sur wg0. Vu de l'extérieur, le serveur n'expose que le port UDP de WireGuard.

Comment WireGuard modifie l'exposition d'un serveur SSH

Par défaut, OpenSSH écoute sur le port TCP 22 et, sauf indication contraire, sur toutes les interfaces, y compris l'interface publique. Avec WireGuard en façade, le seul port ouvert sur Internet est le port UDP du tunnel, et WireGuard reste muet face aux paquets qui ne sont pas signés par une clé connue : un scan ne voit donc rien.

La configuration de cet article utilise 10.8.0.0/24 : le serveur est 10.8.0.1 et le téléphone ou l'ordinateur portable est 10.8.0.2. SSH n'accepte les connexions que sur 10.8.0.1 ou uniquement depuis l'interface wg0. Il existe deux façons d'y parvenir, et elles se combinent bien : lier sshd à l'adresse du tunnel avec ListenAddress, ou filtrer par interface avec ufw.

Configurer WireGuard avec wg-quick et AllowedIPs pour SSH

wg-quick lit /etc/wireguard/wg0.conf, crée l'interface, attribue l'adresse et ajoute des routes pour chaque plage indiquée dans AllowedIPs. Commencez par générer les clés avec des permissions strictes :

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

Configuration du serveur :

# /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

Configuration du client, en split tunnel : seul le trafic vers 10.8.0.1 passe par le VPN, tout le reste utilise la connexion normale.

[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

Sur le serveur, AllowedIPs agit comme une liste d'accès : les paquets de ce pair ne sont acceptés qu'avec 10.8.0.2 comme source. Sur le client, il détermine quelles destinations sont routées dans le tunnel ; 0.0.0.0/0 y enverrait tout. Pour le démarrer et le rendre persistant :

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

Les détails du protocole et de l'échange de clés se trouvent dans le guide de démarrage rapide officiel de WireGuard.

Limiter SSH à wg0 avec ListenAddress dans sshd_config

La directive ListenAddress fait en sorte que sshd n'ouvre son socket que sur l'adresse indiquée ; le port 22 disparaît de l'IP publique, en IPv4 comme en IPv6.

# /etc/ssh/sshd_config
ListenAddress 10.8.0.1
PasswordAuthentication no

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

Le piège habituel est l'ordre de démarrage : si sshd démarre avant wg0, l'adresse n'existe pas encore et sshd échoue avec « Cannot assign requested address ». Corrigez-le avec un override systemd (sudo systemctl edit ssh) en ajoutant [email protected] et [email protected] sous [Unit]. Sur les distributions qui lancent sshd via ssh.socket, l'adresse d'écoute provient de l'unité socket, et non de sshd_config. Toutes les options sont documentées dans la page de manuel de sshd_config.

Limiter SSH à wg0 avec ufw : règles exactes par interface

Avec ufw, sshd continue d'écouter partout, mais le pare-feu ne laisse passer le TCP 22 que s'il arrive sur wg0. Cela ne dépend pas de l'ordre de démarrage et couvre aussi Mosh, qui utilise les ports UDP 60000-61000.

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

Appliquez ces règles depuis une session qui passe déjà par le tunnel, et ouvrez une seconde connexion vers 10.8.0.1 avant de fermer la première. La configuration la plus robuste combine ufw par interface et ListenAddress : si une couche lâche, l'autre maintient le port fermé.

SSH via WireGuard sur iOS et Android face au poste de travail

Sur un téléphone, l'application officielle WireGuard monte le tunnel sous forme de profil VPN système, et le client SSH se connecte à 10.8.0.1 comme à n'importe quel autre hôte. L'application peut générer la paire de clés sur l'appareil ou importer un .conf à partir d'un QR code créé avec qrencode -t ansiutf8 < client.conf.

Élément comparéiOS / AndroidPoste de travail
Client du tunnelApplication officielle WireGuard, profil VPN systèmewg-quick ou l'application officielle
Import de la configurationQR code ou fichier .confCopier le .conf dans /etc/wireguard
Passage du wifi aux données mobilesMosh maintient la session SSHRare ; SSH classique suffit généralement
Échap, Ctrl, Tab et flèchesNécessitent le clavier propre au terminalClavier physique
Clé privée SSHStockage sécurisé du système~/.ssh en 700, clés en 600

Dans termi1, le terminal SSH mobile, la clé Ed25519 est générée sur le téléphone et ne quitte jamais l'appareil ; Mosh conserve la session quand vous passez du wifi aux données mobiles, et tmux garde ce que vous avez laissé tourner. Si la connexion à 10.8.0.1 est marquée comme production, Production Guard retient les commandes qui suppriment ou arrêtent des éléments avant qu'elles n'atteignent le prompt. Si vous préférez ne pas gérer les clés WireGuard à la main, un réseau maillé comme un réseau privé sans ports ouverts ou Tailscale remplit le même rôle.

4 erreurs à éviter en enfermant SSH dans WireGuard

  1. Fermer le port 22 public sans solution de secours. Si le tunnel tombe, il ne reste que la console de l'hébergeur ; vérifiez d'abord qu'elle fonctionne.
  2. Des AllowedIPs qui se chevauchent entre pairs. Deux pairs avec la même plage envoient le trafic vers celui qui a été déclaré en dernier.
  3. Oublier les ports UDP de Mosh. Mosh démarre via SSH, mais sans 60000-61000 ouverts sur wg0, la session ne se connecte jamais.
  4. Ne pas valider sshd_config. Lancez sshd -t avant de redémarrer ; une erreur de syntaxe laisse le service arrêté.

Questions fréquentes

WireGuard suffit-il sans modifier la configuration SSH ?

WireGuard seul ne protège pas le port 22 : sshd écoute toujours sur l'IP publique et n'importe qui peut tenter de s'y connecter. Il faut aussi définir ListenAddress sur l'adresse du tunnel ou ajouter une règle ufw qui n'accepte le TCP 22 que s'il arrive sur wg0.

Que doit contenir l'AllowedIPs du client pour SSH uniquement ?

L'AllowedIPs du client ne doit contenir que l'adresse du serveur dans le tunnel, par exemple 10.8.0.1/32. Ainsi, wg-quick ne route que ce trafic dans le VPN et la navigation normale utilise la connexion habituelle. Indiquer 0.0.0.0/0 ferait passer tout le trafic par le tunnel.

Mosh fonctionne-t-il via WireGuard ?

Mosh fonctionne via WireGuard tant que le serveur accepte l'UDP 60000-61000 sur wg0. Mosh ouvre d'abord une connexion SSH pour lancer mosh-server, puis bascule en UDP. Il ne gère ni la redirection de ports ni la redirection X11, qui nécessitent donc toujours SSH classique.

Que se passe-t-il si WireGuard tombe et que SSH n'écoute que sur wg0 ?

Si WireGuard tombe alors que SSH est limité à wg0, aucun accès SSH n'est possible depuis Internet tant que le tunnel n'est pas rétabli. Gardez la console web de l'hébergeur disponible, activez wg-quick@wg0 au démarrage et faites démarrer sshd après le tunnel avec systemd.