L’une des meilleures pratiques sécurité 2026 pour un VPS : fermer le port 22 sur l’IP publique et n’autoriser SSH que depuis votre tailnet Tailscale. Plus aucun brute-force possible, plus de scan de port qui réussit, plus de risque de fuite de credentials. Tailscale SSH va même plus loin en remplaçant l’authentification clef par identité utilisateur. Voici le tutoriel complet.
Voir notre guide Tailscale.
Architecture recommandée
Trois approches possibles, du plus simple au plus sophistiqué :
- SSH classique restreint au tailnet : OpenSSH écoute uniquement sur l’IP Tailscale du VPS. Authentification par clef SSH classique.
- Tailscale SSH : remplace OpenSSH par le serveur Tailscale qui authentifie via identité Tailscale (Google/GitHub/SSO).
- Bastion central : un seul VPS « jump host » en tailnet, tous les autres VPS accessibles uniquement depuis le bastion.
Recommandation : approche 2 (Tailscale SSH) pour la simplicité, ou 3 (bastion) pour les architectures avec strict audit.
Approche 2 : Tailscale SSH
Étape 1 — Activer sur le VPS
# Sur le VPS
sudo tailscale up --ssh
# Vérifier
tailscale status
Étape 2 — Connecter depuis votre laptop
# Via tailscale CLI
tailscale ssh user@web-prod-01
# Ou via SSH classique (Tailscale gère le port)
ssh user@web-prod-01
# Avec hostname court (Magic DNS)
ssh deploy@web-prod-01.tailnet-name.ts.net
L’authentification se fait par votre identité Tailscale. Plus besoin de copier des clefs publiques sur chaque VPS.
Étape 3 — Restreindre OpenSSH au tailnet
# Trouver l'IP tailscale du VPS
ip a show tailscale0
# inet 100.x.y.z/32
# Modifier /etc/ssh/sshd_config
ListenAddress 100.x.y.z
# Et supprimer/commenter les autres ListenAddress
systemctl restart ssh
# Vérifier que SSH n'écoute plus sur l'IP publique
ss -tlnp | grep :22
Étape 4 — Fermer port 22 sur Hetzner Firewall
- Console Hetzner Cloud → Firewalls
- Éditer la règle entrante TCP 22 → la supprimer
- Sauvegarder
Désormais le port 22 est inaccessible depuis Internet. SSH n’est joignable que via Tailscale.
Approche 3 : Bastion central
Pour une infrastructure avec 5-10+ VPS, un bastion centralise les accès :
# Architecture
laptop --(tailscale)--> bastion --(tailscale ou réseau privé)--> web/db/etc
# Bastion : Tailscale + ACL stricte
sudo tailscale up --ssh --hostname=bastion --advertise-tags=tag:bastion
# Web servers : Tailscale, ACL n'autorise que tag:bastion comme source SSH
sudo tailscale up --advertise-tags=tag:web
Configurez les ACLs (voir notre tutoriel ACLs) pour que seul le bastion puisse SSH vers les autres VPS.
Audit log SSH
Tailscale enregistre toutes les sessions SSH dans le dashboard (Logs → SSH). Vous voyez : qui s’est connecté, depuis quel device, à quel hôte, quand, durée. Pratique pour conformité et détection d’anomalies.
Recovery en cas de panne Tailscale
Tailscale est un service externe. Que faire si login.tailscale.com est down ?
- Les nœuds déjà connectés restent connectés (peer-to-peer)
- Les nouvelles connexions ne marchent pas pendant la panne
- Mitigation : garder un accès « break-glass » — par exemple console KVM Hetzner, ou un compte SSH local sur une IP whitelistée temporaire
- Alternative : Headscale (auto-hébergé) — voir tutoriel
Adaptation Afrique de l’Ouest
Pour une équipe distribuée Sénégal/CI/Mali avec VPS Hetzner européens, Tailscale SSH bastion supprime totalement le risque de brute-force depuis les bots qui scannent en permanence vos IPs publiques. La latence ajoutée est minime (~10-20 ms vs SSH direct).
Erreurs fréquentes
| Erreur | Cause | Solution |
|---|---|---|
| SSH lockout après fermeture port | Tailscale pas encore actif côté laptop | Console KVM Hetzner pour rouvrir temporairement |
| Tailscale SSH refuse connection | –ssh pas activé | tailscale up –ssh |
| OpenSSH n’écoute plus | ListenAddress mauvaise IP | Vérifier ip a show tailscale0 |
| « Permission denied » via Tailscale SSH | ACLs mal configurées | Vérifier policy ssh dans tailnet ACLs |
Lectures complémentaires
Un hébergeur abordable pour vos projets
Hostinger combine prix raisonnable et stabilité. Lien partenaire — pas de surcoût pour vous.
Lien d affiliation. Si vous achetez via ce lien, le blog reçoit une petite commission sans surcoût pour vous.
Pourquoi un bastion Tailscale SSH plutot qu’un bastion classique
Un bastion SSH traditionnel expose un port 22 sur Internet, accumule les cles publiques de l’equipe et devient une cible permanente pour les bots qui scannent les VPS Hetzner, Contabo ou OVH heberges en Europe. Tailscale SSH inverse la logique : votre VPS n’expose plus aucun port public, l’authentification s’appuie sur l’identite de l’utilisateur (Google Workspace, Microsoft 365 ou GitHub) et chaque connexion est tracee dans la console Tailscale.
Pour une PME a Dakar, Abidjan ou Douala qui paie son VPS en euros (a convertir au taux fixe 1 EUR = 655,957 FCFA pour la zone UEMOA), supprimer la surface d’attaque SSH c’est aussi reduire la facture indirecte : moins de fail2ban, moins de logs a stocker, moins d’incidents a investiguer. Le forfait Tailscale Free couvre jusqu’a 100 appareils et 3 utilisateurs, largement suffisant pour une equipe technique de demarrage.
Etape 1 : Creer le tailnet et inviter l’equipe
Avant d’installer quoi que ce soit sur le VPS, on prepare le tailnet. Rendez-vous sur login.tailscale.com et connectez-vous via le fournisseur d’identite que votre organisation utilise deja. Le tailnet herite du domaine de connexion : si vous vous identifiez avec contact@itskillscenter.io, votre tailnet s’appelle itskillscenter.io.ts.net.
# Sur votre poste de travail (Linux, macOS ou WSL)
curl -fsSL https://tailscale.com/install.sh | sh
sudo tailscale up --ssh
Le flag --ssh active le mode serveur SSH cote client : votre laptop devient atteignable par les autres membres du tailnet sans cle SSH. Vous devriez voir une URL d’authentification dans le terminal. Une fois cliquee, le poste apparait dans la console Tailscale avec une IP du bloc 100.64.0.0/10.
Etape 2 : Installer Tailscale sur le VPS
Connectez-vous une derniere fois en SSH classique a votre VPS (root@ip-publique). Apres cette etape, vous pourrez fermer le port 22 dans le firewall du fournisseur. Sur Ubuntu 24.04 LTS ou Debian 12, l’installation passe par le depot officiel.
curl -fsSL https://tailscale.com/install.sh | sh
sudo tailscale up --ssh --hostname=bastion-prod --advertise-tags=tag:bastion
L’option --advertise-tags declare le VPS comme appartenant au groupe bastion, ce qui sera utile pour les ACLs. Le hostname remplace le nom de machine par defaut, plus parlant dans la console. Apres validation dans l’interface web, le VPS apparait avec une IP 100.x.y.z.
Etape 3 : Definir les ACLs SSH dans la console
Dans login.tailscale.com, ouvrez l’onglet Access Controls. Le fichier JSON par defaut autorise tout le monde a tout faire : on va le restreindre. Voici une politique minimale qui n’autorise que les membres du groupe admin a se connecter en SSH au tag bastion, en tant qu’utilisateur root ou ubuntu.
{
"tagOwners": {
"tag:bastion": ["autogroup:admin"]
},
"ssh": [
{
"action": "accept",
"src": ["autogroup:admin"],
"dst": ["tag:bastion"],
"users": ["root", "ubuntu"]
}
]
}
Cliquez sur Save. La syntaxe est validee cote serveur : si une accolade manque ou un tag est inconnu, Tailscale refuse l’enregistrement et affiche l’erreur ligne par ligne. Aucun risque de se verrouiller en testant.
Etape 4 : Tester la connexion sans cle SSH
Depuis votre poste de travail, lancez la commande suivante. Notez qu’on utilise le hostname Tailscale, pas l’IP publique du VPS.
ssh root@bastion-prod
# ou avec le FQDN MagicDNS
ssh root@bastion-prod.itskillscenter-io.ts.net
Aucune cle SSH n’est requise : Tailscale injecte une cle ephemere signee par votre identite Google ou Microsoft, valide quelques minutes. Le shell s’ouvre directement. Cote VPS, le journal /var/log/auth.log montre une connexion publickey acceptee, et la console Tailscale enregistre l’evenement avec votre email.
Etape 5 : Fermer le port 22 sur Internet
Maintenant que Tailscale fonctionne, on coupe l’acces SSH classique. Sur Hetzner, OVH ou Scaleway, modifiez le firewall cloud pour ne plus accepter le port 22 entrant. Sur le VPS lui-meme, on durcit avec ufw.
sudo ufw allow in on tailscale0
sudo ufw deny 22/tcp
sudo ufw enable
sudo ufw status verbose
La sortie doit montrer « 22/tcp DENY IN » et « Anywhere on tailscale0 ALLOW IN ». Testez immediatement depuis un reseau exterieur (4G de votre telephone) que ssh root@ip-publique echoue avec Connection refused. Si la commande tente toujours de se connecter, verifiez le firewall du fournisseur cloud.
Etape 6 : Activer la verification d’appareil et la session recording
Pour une PME qui manipule des donnees clients, deux options Tailscale ajoutent une couche d’audit. Device approval oblige un admin a valider chaque nouvelle machine qui rejoint le tailnet, et SSH session recording enregistre toutes les sessions root pour relecture posterieure.
Dans la console, onglet Settings, activez Device approval. Pour le recording SSH, ajoutez ce bloc a votre policy ACL.
"sshRules": [
{
"action": "accept",
"src": ["autogroup:admin"],
"dst": ["tag:bastion"],
"users": ["root"],
"recorder": ["tag:recorder"]
}
]
Le tag recorder pointe vers une machine dediee qui stocke les enregistrements en local ou sur un bucket S3 compatible (Backblaze B2 a 6 USD/To/mois, Wasabi a 6,99 USD/To/mois). Les enregistrements sont chiffres cote client et rejouables depuis la console.
Etape 7 : Automatiser la rotation des admins
Le risque residuel d’un bastion classique, c’est qu’un developpeur quitte la societe et garde sa cle SSH. Avec Tailscale SSH, il suffit de retirer son compte du groupe admin dans Google Workspace ou Microsoft 365 : la prochaine tentative de connexion echoue dans la seconde, sans toucher au VPS.
Pour formaliser, creez un script mensuel qui exporte la liste des membres via l’API Tailscale et la compare a votre source de verite RH. La cle d’API se genere dans Settings, Keys, avec un scope read-only sur devices.
curl -u "tskey-api-xxx:" https://api.tailscale.com/api/v2/tailnet/itskillscenter.io/devices | jq '.devices[] | {hostname, user, lastSeen}'
La sortie liste tous les appareils avec leur dernier login. Croisez avec votre annuaire RH chaque debut de mois et revoquez les comptes inactifs depuis plus de 30 jours.
Etape 8 : Plan de reprise si Tailscale tombe
Tailscale est un service hebergement controle (control plane chez tailscale.com, data plane peer-to-peer). Si le control plane est indisponible, les connexions deja etablies continuent mais aucune nouvelle connexion ne peut s’authentifier. Le SLA officiel n’est pas publiquement chiffre pour le plan Free, donc prevoir une porte de secours.
Gardez une cle SSH d’urgence dans /root/.ssh/authorized_keys, generee depuis un poste hors-ligne et dont la cle privee est stockee dans un coffre KeePassXC chiffre, accessible par 2 personnes. Ouvrez le port 22 uniquement en cas d’incident, via un script declare a l’avance.
#!/bin/bash
# /usr/local/sbin/break-glass.sh
ufw allow from to any port 22
echo "Port 22 ouvert temporairement pour $1" | logger -t break-glass
Documenter ce script dans le wiki interne et le tester deux fois par an : c’est la difference entre une procedure d’urgence theorique et un plan qui marche le jour ou Tailscale est en panne pendant 30 minutes.
Pour creuser ce sujet, consultez notre guide sur les ACLs et tags Tailscale et notre tutoriel PocketBase hooks Go.
FAQ : questions frequentes sur Tailscale SSH bastion
Tailscale SSH fonctionne-t-il sans connexion Internet ?
Non pour l’authentification : le control plane est en SaaS chez tailscale.com et joignable uniquement via Internet. Une fois la session etablie, le trafic SSH passe en peer-to-peer (souvent via le LAN local si les deux machines sont sur le meme reseau, sinon via les relais DERP). Pour un bureau a Dakar avec connexion fibre Sonatel ou Orange, l’authentification prend 200-400 ms.
Combien coute Tailscale pour une PME de 10 personnes ?
Le plan Free convient jusqu’a 3 utilisateurs et 100 appareils. Au-dela, le plan Premium est facture 6 USD par utilisateur par mois (environ 3940 FCFA), donc 60 USD pour 10 personnes (39 400 FCFA). Le plan Personal Pro a 5 USD par mois reste limite a 1 utilisateur, inadapte pour une equipe.
Que faire si Tailscale est bloque par le pare-feu de l’employeur ?
Tailscale utilise UDP 41641 par defaut, fallback en TCP 443 via les relais DERP. Si l’entreprise filtre meme le 443 sortant (rare en Afrique de l’Ouest), il n’y a pas de bypass propre : negociez l’ouverture avec le service informatique, ou utilisez un poste personnel hors du reseau de l’employeur.
Puis-je migrer un bastion existant sans coupure ?
Oui : installez Tailscale sur le VPS sans toucher au port 22, validez les ACLs, faites tester l’equipe pendant une semaine. Une fois la confiance acquise, fermez le port 22 lors d’une fenetre de maintenance. Garder pendant 30 jours la cle de break-glass documentee a l’etape 8.
Resume operationnel
En 8 etapes, vous remplacez un bastion SSH expose par un acces Tailscale identifie, sans port public, avec audit centralise et plan de secours. La duree d’implementation pour un VPS unique est d’environ 90 minutes pour un admin junior, hors temps de validation des ACLs avec l’equipe.
A retenir avant de fermer le port 22
Verifiez systematiquement trois choses avant de couper l’acces SSH classique : le tailnet est joignable depuis un reseau exterieur (4G hors bureau), la procedure break-glass est documentee dans le wiki interne et testee, et au moins deux personnes de l’equipe ont reussi une connexion Tailscale SSH dans la derniere heure. Cette triple verification evite les coupures de service liees a une mauvaise configuration ACL ou a un compte d’identite mal synchronise avec Google Workspace.