Tailscale sur VPS Hetzner — zéro port public
Installer Tailscale sur un VPS Ubuntu 24.04, basculer SSH sur le réseau Tailscale et fermer tous les ports publics.
Temps estimé : 20 min
Résultat final : Le VPS est accessible uniquement via le réseau Tailscale. Aucun port public exposé. SSH passe par l’IP Tailscale (100.x.x.x), UFW bloque tout le reste.
Objectif
Par défaut, le port SSH 22 est ouvert publiquement — ce qui expose le serveur aux scans automatisés, brute-force et zero-days OpenSSH. Tailscale crée un tunnel chiffré point-à-point (WireGuard) entre tes machines. Une fois activé, SSH n’est joignable que depuis les appareils authentifiés dans ton compte Tailscale.
Ce tuto remplace la règle UFW allow 22/tcp (publique) par allow in on tailscale0 port 22 (réseau Tailscale uniquement).
Prérequis
- VPS Ubuntu 24.04 avec accès SSH fonctionnel (port 22 public temporairement ouvert)
- UFW actif et configuré — voir TUTO-01b
- SSH durci (Ed25519, PasswordAuthentication no) — voir TUTO-02
- Un compte Tailscale (gratuit, jusqu’à 100 appareils)
- Tailscale installé sur ta machine locale (WSL2 ou Windows)
Vérification des prérequis :
# Sur le VPS — vérifier UFW et SSH
sudo ufw status verbose | grep -E "(22|Status)"
systemctl is-active ssh
Attendu :
Status: active
22/tcp ALLOW IN Anywhere
active
Étape 1 : Auditer le script d’installation
Ne jamais exécuter un script externe sans l’inspecter d’abord.
curl -fsSL https://tailscale.com/install.sh -o /tmp/tailscale-install.sh
head -30 /tmp/tailscale-install.sh
grep -E '(curl|wget|https?)' /tmp/tailscale-install.sh | head -20
Vérifier que le script ne contacte que pkgs.tailscale.com et tailscale.com. Tout domaine inconnu (CDN tiers, domaine IP directe) est un signal d’alarme.
Vérification :
sha256sum /tmp/tailscale-install.sh
# Comparer avec le hash affiché sur https://tailscale.com/install (section Linux)
Étape 2 : Installer Tailscale
Après audit confirmé :
bash /tmp/tailscale-install.sh
Vérification :
tailscale version
systemctl status tailscaled | grep Active
Attendu :
1.xx.x
Active: active (running) since ...
Étape 3 : Authentifier le nœud
sudo tailscale up --ssh
Le flag --ssh active le serveur SSH intégré de Tailscale (port 22 via tailscale0). C’est différent du SSH système — les deux coexistent. Confirme que tu veux bien les deux ou retire --ssh si tu gères SSH manuellement via UFW (recommandé dans ce tuto).
La commande affiche une URL d’authentification du type :
To authenticate, visit: https://login.tailscale.com/a/xxxxxxxxxxxxxx
Ouvre cette URL dans ton navigateur et connecte-toi à ton compte Tailscale pour autoriser ce nœud. Reviens ici après validation.
Vérification :
tailscale status
Attendu : le VPS apparaît avec un état active (ou idle).
Étape 4 : Récupérer et noter l’IP Tailscale
tailscale ip -4
Exemple de résultat : 100.64.x.x (plage 100.64.0.0/10, attribuée par Tailscale).
L’IP Tailscale est stable tant que le nœud reste dans ton compte. Elle peut changer si tu le supprimes et le ré-enregistres. Note-la dans un gestionnaire de mots de passe (Bitwarden) sous l’entrée de ce VPS.
Action requise : Note cette IP dans Bitwarden — c’est ton accès permanent au VPS une fois le port 22 public fermé.
Étape 5 : Tester SSH via Tailscale AVANT de fermer le port public
Cette étape est obligatoire. Ne pas la sauter.
Ouvre un terminal WSL2 séparé (ne ferme pas la session SSH actuelle sur le VPS) et exécute :
# Dans WSL2 local
ssh -i ~/.ssh/hermes_hetzner hermes@<IP_TAILSCALE>
# Exemple : ssh -i ~/.ssh/hermes_hetzner hermes@100.86.202.66
Remplace <IP_TAILSCALE> par l’IP obtenue à l’étape 4.
Si cette connexion échoue, NE PAS passer à l’étape 6. Diagnostiquer d’abord (voir section Dépannage). Fermer le port 22 public sans accès Tailscale validé = lockout définitif du VPS.
Vérification :
# Dans la session SSH via Tailscale
ip addr show tailscale0 | grep "inet "
# Attendu : inet 100.64.x.x/...
Confirmer explicitement que la connexion fonctionne avant de continuer.
Étape 6 : Verrouiller SSH sur Tailscale uniquement
Uniquement après validation de l’étape 5.
# Autoriser SSH uniquement depuis l'interface Tailscale
sudo ufw allow in on tailscale0 to any port 22 proto tcp comment "SSH via Tailscale"
La règle suivante supprime l’accès SSH public. Assure-toi d’être connecté via Tailscale (étape 5 validée) avant de l’exécuter.
# Supprimer la règle SSH publique
sudo ufw delete allow 22/tcp
sudo ufw status verbose
Attendu : la règle 22/tcp ALLOW IN Anywhere a disparu. Seule reste :
22/tcp on tailscale0 ALLOW IN Anywhere
Vérification finale :
# Depuis WSL2, tenter une connexion sur l'IP publique (doit échouer)
ssh -o ConnectTimeout=5 -i ~/.ssh/hermes_hetzner hermes@95.216.161.94
# Attendu : Connection timed out ou Connection refused
# Connexion Tailscale (doit fonctionner)
ssh -i ~/.ssh/hermes_hetzner hermes@<IP_TAILSCALE>
# Attendu : connexion établie
Étape 7 : Mettre à jour la config SSH locale
WSL2 — ~/.ssh/config
Host hermes-vps
HostName 100.86.202.66
User hermes
IdentityFile ~/.ssh/hermes_hetzner
IdentitiesOnly yes
Après ajout :
# Tester l'alias
ssh hermes-vps
Windows — C:\Users\raffi\.ssh\config
Host hermes-hetzner
HostName 100.86.202.66
User hermes
IdentityFile C:\Users\raffi\.ssh\hermes_hetzner
IdentitiesOnly yes
Après ajout, tester depuis VS Code Remote-SSH avec la cible hermes-hetzner.
Si d’autres machines (laptop perso, serveur CI) ont besoin d’accéder au VPS, elles doivent également être enregistrées dans ton compte Tailscale. L’accès n’est pas lié à l’IP publique mais à l’appartenance au réseau Tailscale.
Checklist sécurité finale
- Tailscale installé et service
tailscaledactif - Nœud visible dans le dashboard Tailscale avec statut connecté
- Connexion SSH via IP Tailscale testée et validée (étape 5)
- Port 22 public fermé dans UFW (étape 6)
- Seule la règle
tailscale0autorise SSH dans UFW - Config SSH locale (WSL2 + Windows) mise à jour avec l’IP Tailscale
- IP Tailscale notée dans Bitwarden
Dépannage
| Symptôme | Cause probable | Fix |
|---|---|---|
tailscale up bloque sans afficher d’URL | Pas d’accès sortant vers login.tailscale.com | sudo ufw allow out 443/tcp temporairement, puis supprimer |
| SSH Tailscale timeout à l’étape 5 | Tailscale pas encore connecté | Attendre 30s, relancer tailscale status |
tailscale ip -4 retourne rien | Service non démarré | sudo systemctl start tailscaled && sudo tailscale up |
VS Code Remote-SSH échoue avec hermes-hetzner | Config SSH Windows pointe sur l’ancienne IP publique | Mettre à jour C:\Users\raffi\.ssh\config avec l’IP Tailscale |
ufw delete allow 22/tcp échoue | La règle exacte n’existe pas (peut être 22 sans /tcp) | sudo ufw status numbered → sudo ufw delete <N> |
Références
- Tailscale — Linux installation — script officiel et paquets
- Tailscale — UFW integration — guide officiel Ubuntu
- TUTO-01b — provisioning initial et UFW
- TUTO-02 — durcissement SSH, Fail2ban
- TUTO-12 — hardening complémentaire post-Tailscale