SOMMAIRE
0 pourquoi teleport — le pitch
1 composants principaux — les briques
2 le principe du bastion — l'idée
3 pourquoi teleport & pourquoi un bastion — la raison
4 l'installation — architecture cible
5 reverse proxy — nginx + certbot
6 teleport — le serveur
7 conclusion — la suite
──[ 0. Pourquoi Teleport ]──
Ce que j'aime avec Teleport comme « passerelle » d'entrée dans ton Homelab :
- Auth forte avec MFA et WebAuthn
- Une seule entrée pour tout (SSH, applis web, Kubernetes, BDD, …)
- Gestion centralisée des accès avec RBAC
- Une UI web moderne et propre
- Audit complet de chaque session et action
- Zero Trust by design
Contrairement à un VPN classique, souvent bloqué partout, Teleport atteint tes
ressources via du trafic HTTPS-encapsulé (rarement bloqué) et rend la gestion
des certs et autorisations beaucoup moins galère.
Et là où un VPN te lâche sur tout le réseau (vrai risque sécu), Teleport te
laisse dire précisément qui accède à quoi, quand, comment.
──[ 1. Composants Principaux ]──
Teleport, c'est plusieurs services qui s'installent ensemble ou séparément,
selon le besoin :
Auth Service
Le cœur. Gère l'authentification et l'autorisation, détient la
base d'utilisateurs, émet des certificats à courte durée de vie,
applique les politiques d'accès.
Proxy Service
Le point d'entrée public qui route les connexions vers les
ressources internes. Sert l'interface web, gère le tunnel
sécurisé.
SSH Service
Accès SSH aux serveurs, avec enregistrement de session,
remplaçant les clés SSH traditionnelles par des certs.
Application Service
Accès aux applis web internes sans les modifier.
Database Service
Accès BDD sécurisé avec gestion d'identité.
Tout ça peut vivre sur une seule machine pour une install simple (parfait pour
un Homelab), ou s'étaler sur plusieurs serveurs si tu veux scaler.
──[ 2. Le Principe du Bastion ]──
Pour ceux qui découvrent Teleport et les bastions : un bastion, c'est un serveur
exposé (pas forcément sur internet) sur lequel l'authentification est stricte.
Surtout, un bastion c'est une voie *contrôlée* vers tes ressources. Pense-le
comme un reverse proxy, mais avec la sécurité comme job principal.
──[ 3. Pourquoi Teleport & Pourquoi un Bastion ]──
Plein de solutions permettent de rejoindre ton Homelab depuis l'extérieur, open
source (Apache Guacamole…) comme proprio (WALLIX, CyberArk…).
Mais pour moi, aucune n'est aussi bien foutue et facile à utiliser que Teleport
:
1. Moderne, bien documenté, communauté active.
2. L'édition Community est gratuite pour particuliers et petites équipes.
3. Zero Trust natif sans compromis sur la sécurité.
4. S'intègre bien à l'outillage moderne (Kubernetes, cloud, …).
5. Audit et conformité intégrés dès le jour 1.
Pour le bastion : j'ai souvent été coincé sans VPN pour une raison ou une autre
— pare-feu d'entreprise qui bloque, pas de droits admin local sur le poste, pas
ma machine, restrictions réseau, bref.
Un bastion te permet d'atteindre tes ressources avec rien d'autre qu'un
navigateur web. Ça marche à peu près partout.
──[ 4. L'Installation ]──
On passe à la mise en pratique.
L'install qu'on vise, c'est ce que tu chercherais dans un Homelab sécurisé,
qualité pro. Tu adaptes à tes besoins.
Au final on aura :
- Un serveur Teleport principal : notre point d'accès sécurisé vers
tout le reste.
- Un serveur Nginx : reverse proxy et terminaison SSL.
- Des serveurs clients privés, atteignables via le bastion.
- Des serveurs publics, accessibles direct sur internet.
Architecture cible :
Avec ce genre d'install, tu exposes chaque élément comme il faut : public pour
ce qui peut l'être (site, blog, services publics…), privé pour ce qui n'a rien à
faire d'exposé mais que tu veux quand même piloter à distance depuis internet,
sans VPN.
NOTE : Reverse proxy et bastion peuvent vivre sur la même machine
pour faire simple. En prod, sépare-les.
──[ 5. Reverse Proxy ]──
Pour la démo on suppose qu'on veut exposer un bastion + ses hôtes, plus un blog
public qui sort du bastion. Pour exposer plus, tu répètes les étapes et tu mets
à jour les configs.
Partout, le domaine d'exemple c'est `domain.test` — remplace par le tien.
Prérequis :
[ ] Une IP publique. Pour un Homelab tu peux souvent demander une
IPv4 Full-Stack à ton FAI (gratuit chez la plupart) ; un VPS
marche aussi.
[ ] Un nom de domaine avec contrôle DNS complet (OVH, Cloudflare…).
[ ] Des machines (un hyperviseur comme Proxmox ou VMware, c'est
pratique).
5.1 Prépa du serveur
Crée une machine (ou réutilise celle de Teleport) et installe les briques :
# Mise à jour système
sudo apt update && sudo apt upgrade -y
# Nginx
sudo apt install nginx -y
# Certbot pour Let's Encrypt (avec le plugin DNS Cloudflare)
sudo apt install curl certbot python3-certbot-nginx \
python3-certbot-dns-cloudflare -y
# Teleport (on fige une version stable)
TELEPORT_EDITION="oss"
TELEPORT_VERSION="17.6.0"
curl https://cdn.teleport.dev/install.sh | bash -s \
${TELEPORT_VERSION?} ${TELEPORT_EDITION?}
5.2 Config DNS
Crée les enregistrements DNS publics chez ton fournisseur :
*.domain.test -> ton IP publique (wildcard pour Teleport)
domain.test -> ton IP publique (apex)
blog.domain.test -> ton IP publique (exemple de service public)
5.3 Certificats TLS
Pour les wildcards, le challenge DNS-01 c'est la voie. Stocke d'abord tes creds
API Cloudflare :
sudo mkdir -p /root/.secrets
sudo nano /root/.secrets/cloudflare.ini
# /root/.secrets/cloudflare.ini
dns_cloudflare_api_token = ton_token_api_scope
Astuce : utilise un *token* API scopé (Zone:DNS:Edit) plutôt que la
clé API globale historique. Même résultat, bien moins à perdre si le
fichier fuit.
Puis les certs :
# On verrouille le fichier
sudo chmod 600 /root/.secrets/cloudflare.ini
# Certificat wildcard pour Teleport
sudo certbot certonly \
--dns-cloudflare \
--dns-cloudflare-credentials /root/.secrets/cloudflare.ini \
--dns-cloudflare-propagation-seconds 30 \
-d '*.domain.test' -d domain.test
# Certificat pour le blog
sudo certbot certonly \
--dns-cloudflare \
--dns-cloudflare-credentials /root/.secrets/cloudflare.ini \
--dns-cloudflare-propagation-seconds 30 \
-d blog.domain.test
5.4 Nginx, le blog (service public)
# /etc/nginx/conf.d/blog.conf
map $http_upgrade $connection_upgrade {
default upgrade;
'' close;
}
upstream blog_backend {
server 192.168.1.4:80; # IP privée de ton serveur de blog
keepalive 32;
}
server {
listen 443 ssl;
http2 on;
server_name blog.domain.test;
ssl_certificate /etc/letsencrypt/live/blog.domain.test/fullchain.pem;
ssl_certificate_key /etc/letsencrypt/live/blog.domain.test/privkey.pem;
ssl_protocols TLSv1.2 TLSv1.3;
add_header Strict-Transport-Security "max-age=31536000; includeSubDomains" always;
add_header X-Frame-Options DENY always;
add_header X-Content-Type-Options nosniff always;
client_max_body_size 100M;
proxy_read_timeout 600s;
location / {
proxy_pass http://blog_backend;
proxy_http_version 1.1;
proxy_set_header Host $host;
proxy_set_header X-Real-IP $remote_addr;
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
proxy_set_header X-Forwarded-Proto $scheme;
proxy_set_header Upgrade $http_upgrade;
proxy_set_header Connection $connection_upgrade;
}
}
server {
listen 80;
listen [::]:80;
server_name blog.domain.test;
return 301 https://$host$request_uri;
}
5.5 Nginx, Teleport
# /etc/nginx/conf.d/teleport.conf
map $http_upgrade $connection_upgrade {
default upgrade;
'' close;
}
upstream teleport_backend {
server 192.168.1.2:443; # IP de ton serveur Teleport
keepalive 32;
}
server {
listen 443 ssl;
http2 on;
server_name *.domain.test domain.test;
ssl_certificate /etc/letsencrypt/live/domain.test/fullchain.pem;
ssl_certificate_key /etc/letsencrypt/live/domain.test/privkey.pem;
ssl_protocols TLSv1.2 TLSv1.3;
add_header Strict-Transport-Security "max-age=31536000; includeSubDomains" always;
# On re-chiffre vers Teleport et on transporte le bon SNI
proxy_ssl_server_name on;
proxy_ssl_name $host;
location / {
proxy_pass https://teleport_backend;
proxy_http_version 1.1;
proxy_set_header Host $host;
proxy_set_header X-Real-IP $remote_addr;
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
proxy_set_header X-Forwarded-Proto $scheme;
proxy_set_header Upgrade $http_upgrade;
proxy_set_header Connection $connection_upgrade;
proxy_read_timeout 600s;
proxy_buffering off;
}
}
server {
listen 80;
listen [::]:80;
server_name *.domain.test domain.test;
return 301 https://$host$request_uri;
}
Test et reload :
sudo nginx -t
sudo systemctl reload nginx
sudo systemctl status nginx
──[ 6. Teleport ]──
Maintenant le serveur Teleport principal. Une fois installé, un seul fichier
principal suffit pour démarrer.
6.1 Config de base
sudo nano /etc/teleport.yaml
# /etc/teleport.yaml
version: v3
teleport:
nodename: bastion-teleport
data_dir: /var/lib/teleport
log:
output: stderr
severity: INFO
diag_addr: "127.0.0.1:3000" # diagnostics internes
auth_service:
enabled: true
cluster_name: "domain.test"
listen_addr: 0.0.0.0:3025
proxy_listener_mode: multiplex
authentication:
type: local
second_factor: webauthn # clés de sécurité (YubiKey, etc.)
webauthn:
rp_id: domain.test
session_recording: node-sync
tokens:
- "proxy,node:your-secret-token-here"
ssh_service:
enabled: true
listen_addr: 0.0.0.0:3022
x11:
enabled: true
proxy_service:
enabled: true
web_listen_addr: 0.0.0.0:443
tunnel_listen_addr: 0.0.0.0:3024
public_addr: domain.test:443
acme:
enabled: false # TLS géré par Nginx + Let's Encrypt
# On fait confiance aux X-Forwarded-* venant du reverse proxy
trust_x_forwarded_for: true
# Application Service, à privilégier pour exposer des UIs web spécifiques
app_service:
enabled: true
apps:
- name: pfsense
uri: https://192.168.1.1
public_addr: "pfsense.domain.test"
insecure_skip_verify: true
labels:
env: "production"
team: "infrastructure"
- name: nas
uri: http://192.168.1.10:5000
public_addr: "nas.domain.test"
insecure_skip_verify: true
labels:
env: "production"
team: "storage"
Note : `insecure_skip_verify: true` saute la vérif TLS vers l'appli
backend. OK sur un segment LAN de confiance ; resserre si le chemin
vers l'appli n'est pas entièrement chez toi.
6.2 Démarrage
# Validation de la config
sudo teleport configure --test
# Activation et démarrage
sudo systemctl enable teleport
sudo systemctl start teleport
# Statut et logs
sudo systemctl status teleport
sudo journalctl -u teleport -f
6.3 Premier admin
sudo tctl users add admin --roles=editor,access \
--logins=root,admin,john
6.4 Test de bon fonctionnement
Une fois configuré, tu devrais pouvoir :
1. Atteindre l'UI web sur https://domain.test
2. Voir tes applis dans l'onglet Applications
3. SSH dans les serveurs que tu as ajoutés
4. Ouvrir les applis web via leurs sous-domaines configurés
──[ 7. Conclusion ]──
Ton infra Homelab est en place. Y'a évidemment plein de marge pour faire grossir
tout ça, mais ça te donne une base solide pour héberger tes services,
atteignables de manière sécurisée depuis n'importe où, avec rien de plus qu'un
navigateur.
Références :
[0] Documentation Teleport
https://goteleport.com/docs/
[1] Exemples de configuration
https://github.com/gravitational/teleport/tree/master/examples
[2] Communauté Teleport
https://goteleport.com/community/
[3] Bonnes pratiques de sécurité
https://goteleport.com/docs/admin-guides/access-controls/
──[ EOF ]──