SSD Nodes Learn Hosting plans →
Guides Matt ConnorPar Matt Connor · Mis à jour le 2026-08-22

SSH via Tor onion service sans ouvrir de port

Placez sshd derrière un service onion Tor pour n’exposer aucun port entrant. Configurez l’accès v3, l’autorisation client et l’ordre des étapes sans vous bloquer.

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 revient par cette connexion. Rien n’a donc besoin d’écouter sur l’adresse IP publique.

L’effet sur le journal 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 au niveau du pare-feu. /var/log/auth.log n’enregistre alors plus que les sessions que vous avez démarrées.

Le coût 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évoyez ce cas avant de fermer le port, car vous risquez de perdre l’accès à une machine que vous ne pouvez pas atteindre physiquement.

Mettez en place 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 ne passe pas par 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.

  1. Installez tor et vérifiez qu’il termine son bootstrap.
  2. Définissez le service onion et relevez son adresse.
  3. Connectez-vous via onion pendant que le port 22 est encore ouvert.
  4. Ajoutez l’autorisation client, puis reconnectez-vous.
  5. Liez sshd à la loopback et fermez le port 22.
  6. 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 pare-feu qui bloquerait une nouvelle connexion. Elle constitue donc votre première solution de secours.

Installer Tor sur le serveur

Ubuntu fournit Tor dans son propre dépôt, mais cette version est souvent obsolète. Le dépôt du projet Tor contient la version indiquée 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/null

Écrivez /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.gpg
sudo apt update
sudo apt install -y tor deb.torproject.org-keyring
sudo journalctl -u tor@default -n 20 --no-pager

Le journal doit se terminer par Bootstrapped 100% (done). S’il reste bloqué avant cette ligne, Tor ne peut pas accéder au réseau. La cause est presque toujours une règle de pare-feu sortante ou une horloge fortement désynchronisée.

Le nom de l’unité est trompeur. systemctl status tor affiche Active: active (exited) même lorsque tout fonctionne correctement, car Debian et Ubuntu empaquettent Tor comme une unité maître multi-instance dont le seul rôle est d’activer la véritable instance. Le daemon s’exécute sous le nom tor@default.service. Utilisez ce nom pour status et journalctl. Les commandes de démarrage, d’arrêt et de rechargement de tor atteignent tout de même 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:22

La 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. Remplacez 127.0.0.1:22 par un serveur web sur 127.0.0.1:80 et les deux mêmes directives publient un site sur une adresse onion, ce qui constitue un deuxième service utile à exécuter une fois tor installé.

sudo systemctl reload tor
sudo cat /var/lib/tor/ssh/hostname

Cette commande affiche 56 caractères base32 suivis de .onion. Ces caractères correspondent à 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 le mauvais propriétaire ou avec un mode plus permissif 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 impose 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 ensuite 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 est important ici.

OpenSSH ne possède pas son propre client SOCKS. Un programme auxiliaire établit donc la connexion. Ajoutez ceci à ~/.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 service Tor local. %h transmet le nom onion à Tor en tant que nom. Tor le résout ainsi à l’intérieur du réseau. Il doit s’agir de la version OpenBSD de netcat. GNU netcat ne possède pas l’option -X et s’arrête avec nc: invalid option -- 'X'.

ssh myvps

La première connexion est lente, car Tor construit un circuit avant toute autre opération. Acceptez l’empreinte de la clé de l’hôte comme vous le feriez ailleurs. Ensuite, la gestion habituelle des clés SSH reste inchangée. Le transport a changé. L’authentification, elle, n’a pas changé.

Pour une connexion 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

En l’état, toute personne qui connaît l’adresse peut atteindre votre bannière SSH et commencer à deviner. Les adresses Onion ne peuvent pas être énumérées à partir du 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 commités dans un dépôt git. L’autorisation des clients comble cette faille. 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 projet Tor, 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.key

La version publiée de ces lignes utilise base64pem -d, qui n’est pas fourni par une installation Ubuntu standard. La commande s’arrête alors avec base64pem: command not found. GNU base64 -d décode le même corps PEM. Utilisez-le à 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 tor

Seuls les fichiers qui se terminent par .auth sont lus. Enregistrez-la sous laptop.auth.txt. Sinon, tor ignore le fichier sans afficher d’erreur et le service reste discrètement accessible à toute personne qui connaît 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_private

Ajoutez 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 un filet de sécurité. Cette commande annule les deux modifications ci-dessous après quinze minutes si vous vous retrouvez bloqué hors du 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.

Ensuite, empêchez sshd d’écouter sur l’adresse publique. Ubuntu 24.04 active SSH via une unité socket, donc ListenAddress dans sshd_config est ignoré : ssh.socket gère le socket d’écoute, pas sshd. Vérifiez dans quel cas vous vous trouvez.

systemctl is-enabled ssh.socket

Si cette commande affiche enabled, exécutez sudo systemctl edit ssh.socket et ajoutez ceci.

[Socket]
ListenStream=
ListenStream=127.0.0.1:22

La 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 socket d’écoute tout en conservant le socket 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. Cette sortie constitue la preuve dans les deux cas.

Passez ensuite au pare-feu, avec la gestion habituelle 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 verbose

Laissez le trafic sortant autorisé. Tor se connecte aux relais en sortie sur des ports tels que 443 et 9001. Une politique sortante par défaut qui refuse le trafic empêche donc Tor d’établir ses connexions initiales et supprime en même temps votre seul accès restant. La plupart des fournisseurs disposent également d’un pare-feu réseau séparé dans le panneau de contrôle. Fermez-y aussi le port 22, sinon le port reste accessible, quel que soit le résultat indiqué par ufw.

Si Docker s’exécute sur ce serveur, vérifiez ses ports publiés avant de considérer la tâche terminée. Docker ajoute ses propres règles dans les mêmes tables et publie directement les ports des conteneurs en contournant ufw, donc une politique ufw de refus ne suffit pas à décrire toute la situation.

Redémarrez avant de lui faire confiance

systemctl is-enabled tor@default
sudo reboot

Si 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.

Si le service 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-config

Ce que cela coûte par rapport à un tunnel WireGuard

Par rapport à un VPN WireGuard sur votre propre VPS, un service onion est plus lent et moins prévisible. Évaluez honnêtement ce compromis avant de l’adopter.

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 présente 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 en espace utilisateur 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 services onion sont publiés pour des périodes données. Une horloge fortement décalé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 correction d’une règle de firewall. Aucun port ne peut être scanné 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 donc 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 comme accès quotidien et conservez le service onion comme route de secours lorsque la configuration WireGuard est incorrecte. Vous ne laissez ainsi ouvert qu’un port UDP, au lieu d’un port SSH public. Cela ne dispense pas de renforcer sshd lui-même : l’authentification par clé uniquement et une connexion qui n’utilise pas root restent importantes, car un service onion protège le chemin réseau, et rien au-delà.

Cas d’échec et erreurs affichées

Tor ne dépasse jamais Bootstrapped 0%. Le trafic sortant est bloqué ou l’horloge est fortement décalée. Vérifiez la règle de trafic sortant avec sudo ufw status verbose, puis exécutez timedatectl.

systemctl status tor affiche 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, « On­ion Service Descriptor Can Not be Found ». Le descripteur n’est peut-être pas encore publié, ce qui peut prendre un court moment après un rechargement, ou tor ne fonctionne 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 superflu 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 ordinaire. Celle-ci ne renvoie aucune réponse pour .onion, donc ProxyCommand n’a jamais été 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 permissions publickey refusée et ne mettez pas tor en cause.

FAQ

Un service onion signifie-t-il réellement qu’aucun port n’est ouvert sur mon VPS ?

Oui, une fois que sshd est lié à 127.0.0.1 et que le pare-feu bloque le trafic entrant. Tor établit une connexion TCP sortante vers un relais, puis votre session revient par ce relais. 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 pare-feu réseau du fournisseur dans le panneau de contrôle. Il est distinct de ufw et doit également bloquer le trafic entrant.

L’adresse .onion suffit-elle à elle seule pour sécuriser SSH ?

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 les fichiers de configuration. Ajoutez l’autorisation des clients v3. Avec cette configuration, le descripteur du service est chiffré avec la clé de votre client. Une personne qui ne possède que l’adresse reçoit l’erreur étendue F4 et n’atteint jamais sshd.

Que se passe-t-il si tor ne démarre pas 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 s’initialiser après le démarrage. L’adresse répond donc plus tard que la machine aux requêtes 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 via Tor est-il plus lent que WireGuard ?

Oui, avec une différence importante. Une connexion vers un service onion traverse environ six relais choisis aléatoirement, tandis que WireGuard établit un seul saut chiffré directement vers votre serveur. La saisie devient moins réactive et les transferts sont lents. Une configuration courante consiste à utiliser WireGuard pour les opérations quotidiennes et à conserver le service onion comme voie d’accès d’urgence, qui reste disponible même si la configuration du VPN est défectueuse.