SSH via Tor onion sans ouvrir de port
Placez sshd derrière un service onion Tor pour fermer tous les ports entrants. Configurez l’autorisation v3 et suivez l’ordre qui évite le lockout.
Ce que change SSH via un service onion Tor
SSH via un service onion Tor vous permet d’administrer un VPS qui n’accepte aucune connexion entrante sur aucun port. Le serveur se connecte au réseau Tor et maintient cette connexion ouverte. Votre session SSH l’emprunte dans l’autre sens. Aucun service n’a donc besoin d’écouter sur l’adresse IP publique.
L’effet sur les journaux est immédiat. Une machine dont le port SSH est public reçoit chaque jour des milliers de tentatives de mot de passe échouées provenant de scanners. Placez sshd derrière un service onion et bloquez le trafic entrant dans le pare-feu. /var/log/auth.log n’enregistre alors plus que les sessions que vous avez ouvertes.
Le contrepartie est que tor se trouve sur le chemin de chaque session d’administration. Il s’agit d’un daemon en espace utilisateur qui doit démarrer et s’initialiser après chaque redémarrage avant que vous puissiez vous connecter. Préparez cette étape avant de fermer le port. Sinon, vous risquez de perdre l’accès à une machine que vous ne pouvez pas atteindre physiquement.
Préparez un accès de secours avant toute modification
Ne commencez pas tant que vous ne disposez pas d’un accès de récupération qui n’utilise pas SSH.
Ouvrez maintenant la console de votre fournisseur, c’est-à-dire la console VNC ou série du panneau de contrôle, puis connectez-vous avec celle-ci. Si vous ne connaissez pas le mot de passe root, réinitialisez d’abord le mot de passe root depuis le panneau et vérifiez qu’il fonctionne. Une console que vous n’avez jamais testée ne constitue pas un accès de récupération.
L’ordre ci-dessous est important. Chaque étape est vérifiée avant l’exécution de la suivante, et le port 22 reste ouvert jusqu’à ce que la route onion fonctionne.
- Installez tor et vérifiez qu’il termine son bootstrap.
- Définissez le service onion et relevez son adresse.
- Connectez-vous via onion tant que le port 22 est encore ouvert.
- Ajoutez l’autorisation client, puis reconnectez-vous.
- Liez
sshdà l’interface loopback et fermez le port 22. - Redémarrez, puis reconnectez-vous via onion.
Gardez votre session SSH actuelle ouverte pendant toute la procédure. Une session établie reste active même après une modification du firewall qui bloquerait une nouvelle connexion. Elle constitue donc votre première ligne de secours.
Installer Tor sur le serveur
Ubuntu fournit Tor dans son propre dépôt, mais cette version est souvent en retard. Le dépôt du Tor Project contient la version décrite dans sa documentation. Ajoutez-le avec les commandes du guide du dépôt apt.
sudo apt update
sudo apt install -y apt-transport-https wget gpg
wget -qO- https://deb.torproject.org/torproject.org/A3C4F0F979CAA22CDBA8F512EE8CBC9E886DDD89.asc | gpg --dearmor | sudo tee /usr/share/keyrings/deb.torproject.org-keyring.gpg >/dev/nullExécutez /etc/apt/sources.list.d/tor.sources. Suites utilise le nom de code de votre version, que lsb_release -cs affiche (noble sur Ubuntu 24.04).
Types: deb deb-src
URIs: https://deb.torproject.org/torproject.org/
Suites: noble
Components: main
Signed-By: /usr/share/keyrings/deb.torproject.org-keyring.gpgsudo apt update
sudo apt install -y tor deb.torproject.org-keyring
sudo journalctl -u tor@default -n 20 --no-pagerLe journal doit se terminer par Bootstrapped 100% (done). S’il reste bloqué avant cette ligne, Tor ne peut pas accéder au réseau. Dans presque tous les cas, cela vient d’une règle de pare-feu sortante ou d’une horloge fortement incorrecte.
Le nom de l’unité est trompeur. systemctl status tor signale Active: active (exited) même lorsque tout fonctionne correctement, car Debian et Ubuntu empaquettent Tor sous la forme d’une unité maître multi-instance dont le seul rôle est de charger l’instance réelle. Le daemon s’exécute lui-même sous le nom tor@default.service. Utilisez ce nom pour status et journalctl. Les opérations de démarrage, d’arrêt et de rechargement de tor atteignent bien l’instance, donc sudo systemctl reload tor fonctionne comme prévu.
Définir le service onion pour le port 22
Ajoutez deux lignes à /etc/tor/torrc.
HiddenServiceDir /var/lib/tor/ssh/
HiddenServicePort 22 127.0.0.1:22La deuxième ligne indique à tor d’accepter le port virtuel 22 sur l’adresse onion et de se connecter à 127.0.0.1:22 sur le serveur. Tor atteint sshd via la loopback. C’est précisément pour cette raison que sshd pourra ensuite cesser d’écouter sur l’adresse publique.
sudo systemctl reload tor
sudo cat /var/lib/tor/ssh/hostnameCette commande affiche 56 caractères base32 suivis de .onion. Ces caractères sont la clé publique du service sous forme encodée. Il n’y a ni autorité de certification ni enregistrement de nom.
Laissez tor créer /var/lib/tor/ssh/ lui-même. Si vous le créez manuellement avec un propriétaire incorrect ou avec des permissions plus permissives que 0700, tor refuse de l’utiliser et le journal signale que le répertoire est trop permissif. Les fichiers qu’il contient constituent l’identité du service : hs_ed25519_secret_key est l’adresse. Sauvegardez ce répertoire avec le mode 600 et conservez la copie hors du serveur, car sa perte implique une nouvelle adresse et une modification de la configuration sur chaque client.
Se connecter depuis votre poste de travail
Votre poste de travail a besoin d’un client Tor, qui ne nécessite aucune configuration. Sur Debian ou Ubuntu, il s’agit de sudo apt install -y tor netcat-openbsd. Tor écoute alors sur 127.0.0.1:9050 en tant que proxy SOCKS5. SOCKS est un protocole de proxy générique. La version 5 peut transmettre un nom d’hôte au lieu d’une adresse IP. C’est ce qui nous intéresse ici.
OpenSSH ne possède pas son propre client SOCKS. Un programme auxiliaire établit donc la connexion. Ajoutez ceci dans ~/.ssh/config.
Host myvps
HostName xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx.onion
User admin
ProxyCommand /usr/bin/nc -X 5 -x 127.0.0.1:9050 %h %p
ServerAliveInterval 30-X 5 sélectionne SOCKS5 et -x 127.0.0.1:9050 pointe vers le processus Tor local. %h transmet le nom onion à Tor en tant que nom. Tor le résout ainsi à l’intérieur du réseau. Le programme doit être la version OpenBSD de netcat. GNU netcat ne possède pas l’option -X et s’arrête avec nc: invalid option -- 'X'.
ssh myvpsLa première connexion est lente, car Tor construit un circuit avant toute autre opération. Acceptez l’empreinte de la clé d’hôte comme vous le feriez ailleurs. À partir de là, la gestion habituelle des clés SSH s’applique sans modification. Le transport a changé. L’authentification n’a pas changé.
Pour une utilisation ponctuelle, vous pouvez ignorer l’entrée de configuration : torsocks ssh admin@xxxxx.onion fait la même chose.
Ajouter l’autorisation des clients v3
Dans l’état actuel, toute personne qui connaît l’adresse peut atteindre votre bannière SSH et commencer à essayer des identifiants. Les adresses Onion ne peuvent pas être énumérées via le système d’annuaire. L’adresse se comporte donc comme un secret, mais elle peut fuiter de manière ordinaire : dans l’historique du shell ou dans des fichiers de configuration envoyés vers un dépôt git. L’autorisation des clients comble cette lacune. Le service publie son descripteur chiffré avec une clé client. Une personne qui possède l’adresse mais aucune clé ne peut donc même pas localiser le service.
Générez une paire de clés x25519 sur le client. Voici le pipeline du guide d’autorisation des clients du Tor Project, avec une modification.
openssl genpkey -algorithm x25519 -out /tmp/k1.prv.pem
grep -v " PRIVATE KEY" /tmp/k1.prv.pem | base64 -d | tail --bytes=32 | base32 | sed 's/=//g' > /tmp/k1.prv.key
openssl pkey -in /tmp/k1.prv.pem -pubout | grep -v " PUBLIC KEY" | base64 -d | tail --bytes=32 | base32 | sed 's/=//g' > /tmp/k1.pub.keyLa version publiée de ces lignes utilise base64pem -d, qui n’est pas présent dans une installation Ubuntu standard. La commande s’arrête alors avec base64pem: command not found. GNU base64 -d décode le même contenu PEM. Utilisez donc cet outil à la place.
Sur le serveur, installez la clé publique.
sudo install -d -m 700 -o debian-tor -g debian-tor /var/lib/tor/ssh/authorized_clients
echo "descriptor:x25519:PASTE_PUBLIC_KEY_HERE" | sudo tee /var/lib/tor/ssh/authorized_clients/laptop.auth >/dev/null
sudo chown debian-tor:debian-tor /var/lib/tor/ssh/authorized_clients/laptop.auth
sudo systemctl reload torSeuls les fichiers qui se terminent par .auth sont lus. Enregistrez-la sous le nom laptop.auth.txt. Dans le cas contraire, tor ignore le fichier sans afficher d’erreur et le service reste discrètement accessible à toute personne connaissant l’adresse.
Sur le client, installez la clé privée. Sous Ubuntu, le daemon tor s’exécute avec l’utilisateur debian-tor et ne peut pas lire les fichiers de votre répertoire personnel. Placez donc le répertoire à un emplacement accessible à cet utilisateur.
sudo install -d -m 700 -o debian-tor -g debian-tor /var/lib/tor/onion_auth
echo "ADDRESS_WITHOUT_DOT_ONION:descriptor:x25519:PASTE_PRIVATE_KEY_HERE" | sudo tee /var/lib/tor/onion_auth/myvps.auth_private >/dev/null
sudo chown debian-tor:debian-tor /var/lib/tor/onion_auth/myvps.auth_private
sudo chmod 600 /var/lib/tor/onion_auth/myvps.auth_privateAjoutez ClientOnionAuthDir /var/lib/tor/onion_auth au /etc/tor/torrc du client, puis rechargez tor. Si vous exécutez plutôt tor avec votre propre utilisateur, par exemple avec la version Homebrew sur macOS, faites pointer ClientOnionAuthDir vers ~/.tor/onion_auth avec le mode 0700.
L’adresse contenue dans ce fichier correspond aux 56 caractères sans le suffixe .onion. Supprimez /tmp/k1.prv.pem et /tmp/k1.prv.key lorsque vous avez terminé.
Testez maintenant les deux directions. ssh myvps doit toujours se connecter. Depuis une machine qui ne possède aucune clé, la même adresse doit échouer. Cet échec confirme que l’autorisation est active.
Fermez le port 22 dans cet ordre
Commencez par mettre en place une sécurité de secours. Cette commande annule les deux modifications ci-dessous après quinze minutes si vous perdez l’accès au serveur.
sudo systemd-run --on-active=15m --unit=ssh-rescue \
/bin/sh -c 'ufw allow 22/tcp; rm -f /etc/systemd/system/ssh.socket.d/override.conf; systemctl daemon-reload; systemctl restart ssh.socket'Annulez-la avec sudo systemctl stop ssh-rescue.timer après avoir vérifié que la route onion fonctionne toujours.
Arrêtez ensuite sshd d’écouter sur l’adresse publique. Ubuntu 24.04 active SSH via une socket systemd, donc ListenAddress dans sshd_config est ignoré : ssh.socket possède la socket d’écoute, pas sshd. Vérifiez dans quel cas vous vous trouvez.
systemctl is-enabled ssh.socketSi cette commande affiche enabled, exécutez sudo systemctl edit ssh.socket et ajoutez ceci.
[Socket]
ListenStream=
ListenStream=127.0.0.1:22La valeur vide de ListenStream= efface la valeur héritée de l’unité fournie par le paquet. Si vous omettez cette ligne, vous ajoutez un second listener tout en conservant le listener public. C’est la cause la plus fréquente d’un échec silencieux à cette étape.
sudo systemctl daemon-reload
sudo systemctl restart ssh.socket
ss -tlnp | grep ':22'ss doit afficher 127.0.0.1:22 et rien sur 0.0.0.0:22. Si ssh.socket était désactivé, placez ListenAddress 127.0.0.1 dans /etc/ssh/sshd_config.d/10-onion.conf, exécutez sudo systemctl restart ssh, puis vérifiez avec la même ligne ss. Dans les deux cas, cette sortie constitue la preuve.
Passez ensuite au firewall. Il s’agit d’une gestion classique des règles ufw sur un VPS. Exécutez d’abord sudo ufw status numbered et supprimez la règle SSH qu’il affiche.
sudo ufw status numbered
sudo ufw delete allow OpenSSH
sudo ufw default allow outgoing
sudo ufw default deny incoming
sudo ufw status verboseLaissez le trafic sortant autorisé. Tor se connecte aux relays sur des ports tels que 443 et 9001. Une politique sortante par défaut en deny empêche donc Tor d’établir ses connexions et supprime au même moment votre seul accès restant. La plupart des fournisseurs exécutent également un firewall réseau distinct dans le panneau de contrôle. Fermez aussi le port 22 à cet endroit. Sinon, le port reste accessible, quelle que soit la sortie de ufw.
Si Docker fonctionne sur ce serveur, vérifiez ses ports publiés avant de considérer la tâche terminée. Docker écrit ses propres règles dans les mêmes tables et publie directement les ports des conteneurs en contournant ufw. Une politique ufw en deny ne suffit donc pas à décrire toute la situation.
Redémarrez avant de lui faire confiance
systemctl is-enabled tor@default
sudo rebootSi la première commande n’indique pas que le service est activé, exécutez sudo systemctl enable tor@default avant de redémarrer. Attendez deux minutes, puis exécutez ssh myvps. Tor doit effectuer son bootstrap après le démarrage. L’adresse onion commence donc à répondre quelque temps après le démarrage de la machine.
S’il ne revient jamais, ouvrez la console et consultez sudo journalctl -u tor@default -b. Une erreur de syntaxe dans torrc ou un problème de permissions sur un répertoire y est affiché. Vous pouvez également vérifier une modification de torrc avant de l’appliquer.
sudo -u debian-tor tor --verify-configCe que cela coûte par rapport à un tunnel WireGuard
Par rapport à un VPN WireGuard sur votre propre VPS, un onion service est plus lent et moins prévisible. Évaluez honnêtement ce compromis avant de l’utiliser.
Latence. Le circuit du client comporte trois relais et le service en ajoute trois autres. Vos frappes traversent donc environ six machines choisies aléatoirement dans le monde. La saisie interactive accuse un délai visible et les copies de fichiers sont lentes. WireGuard ajoute un seul saut. Mesurez votre propre cas avec time ssh myvps 'echo ok', car le résultat dépend du circuit que tor a construit et change lorsque tor en construit un autre.
Un daemon userspace sur le chemin critique. WireGuard s’exécute dans le kernel et démarre avec le réseau. Tor est un processus qui doit démarrer, s’amorcer et atteindre un relais guard avant que quoi que ce soit fonctionne. En cas d’échec, vous devez utiliser la console du fournisseur.
Exactitude de l’horloge. Les descripteurs des onion services sont publiés pour des périodes données. Une horloge très désynchronisée empêche donc la résolution de l’adresse, sans message explicite. timedatectl doit renvoyer System clock synchronized: yes.
En contrepartie, l’exposition ne dépend plus de la validité d’une règle de firewall. Aucun port n’est ouvert à l’analyse et aucune bannière ne peut être récupérée. De plus, l’adresse est elle-même une clé publique : le endpoint prouve son identité avant même le démarrage de SSH.
En pratique, la meilleure réponse consiste généralement à utiliser les deux. Utilisez WireGuard au quotidien et conservez l’onion service comme chemin de secours lorsque la configuration WireGuard est incorrecte. Vous ne laissez ainsi qu’un port UDP ouvert, au lieu d’un port SSH public. Cela ne remplace pas le durcissement de sshd lui-même : l’authentification par clé uniquement et la connexion avec un compte non-root restent importantes, car un onion service protège le chemin réseau, et rien au-delà.
Modes d’échec et erreurs affichées
Tor ne passe jamais Bootstrapped 0%. Le trafic sortant est bloqué ou l’horloge est fortement décalée. Vérifiez la policy sortante avec sudo ufw status verbose, puis exécutez timedatectl.
systemctl status tor indique active (exited). C’est normal sur Debian et Ubuntu. Consultez plutôt tor@default.
Le descripteur est introuvable. Tor renvoie l’erreur SOCKS étendue F0, « Onion Service Descriptor Can Not be Found ». Soit le descripteur n’est pas encore publié, ce qui prend un court moment après un reload, soit tor ne s’exécute pas sur le serveur.
F4, « Onion Service Missing Client Authorization ». Le client ne possède aucun .auth_private correspondant que tor puisse utiliser. Vérifiez que ClientOnionAuthDir figure dans torrc, que le répertoire est en mode 0700, que le nom de fichier se termine par .auth_private et que debian-tor peut le lire.
F5, « Onion Service Wrong Client Authorization ». La clé privée ne correspond pas au fichier .auth sur le serveur. Un = final ou un retour à la ligne isolé dans la chaîne base32 provoque cette erreur.
nc: invalid option -- 'X'. GNU netcat est installé à la place de la version OpenBSD. Exécutez sudo apt install -y netcat-openbsd.
Could not resolve hostname. ssh a tenté une résolution DNS classique. Celle-ci ne renvoie aucune réponse pour .onion, donc ProxyCommand ne s’est jamais exécuté. Le motif Host dans ~/.ssh/config ne correspond pas au nom que vous avez saisi.
Permission denied (publickey). Le tunnel a fonctionné et tor a terminé son traitement. Traitez ce problème comme un problème ordinaire de permission denied publickey et ne mettez pas tor en cause.
FAQ
Un service onion signifie-t-il vraiment qu’aucun port n’est ouvert sur mon VPS ?
Oui, une fois que sshd est lié à 127.0.0.1 et que le firewall bloque le trafic entrant. Tor établit une connexion TCP sortante vers un relay, puis votre session repasse par celui-ci. Aucun service sur la machine n’accepte donc de connexion sur l’adresse publique. Vérifiez-le avec ss -tlnp sur le serveur et avec un scan de ports depuis une autre machine. N’oubliez pas le firewall réseau du fournisseur dans le panneau de contrôle. Il est indépendant d’ufw et doit également être fermé.
L’adresse .onion suffit-elle à sécuriser SSH à elle seule ?
Non. L’adresse comporte 56 caractères et ne peut pas être devinée ou énumérée depuis le système d’annuaire. Elle se comporte donc comme un secret, mais elle peut apparaître dans l’historique du shell et dans les fichiers de configuration. Ajoutez l’autorisation client v3. Avec cette option, le descripteur du service est chiffré avec la clé de votre client. Une personne qui ne possède que l’adresse obtient l’erreur étendue F4 et n’atteint jamais sshd.
Que se passe-t-il si tor ne démarre plus après un redémarrage ?
Vous perdez complètement l’accès SSH, car l’adresse onion est alors le seul moyen d’accès. C’est pourquoi vous devez tester la console du fournisseur avant de fermer le port 22. Tor a également besoin de temps pour établir ses connexions après le démarrage. L’adresse répond donc plus tard que la machine au ping. Si elle ne répond jamais, connectez-vous à la console et consultez sudo journalctl -u tor@default -b. Une erreur de syntaxe dans torrc ou un problème de permissions sur /var/lib/tor/ssh y sera indiqué.
SSH sur Tor est-il plus lent que WireGuard ?
Oui, de façon importante. Une connexion vers un service onion traverse environ six relays choisis aléatoirement, tandis que WireGuard utilise un seul saut chiffré directement vers votre serveur. La saisie devient peu réactive et les transferts sont lents. Une configuration courante consiste à utiliser WireGuard au quotidien et à conserver le service onion comme voie d’accès d’urgence, capable de fonctionner même si la configuration du VPN est défectueuse.