🧰 Installation de Teleport avec Traefik en front-end
Dans un précédent article, j'avais documenté l'installation bare-metal de Teleport. Voyons maintenant comment faire avec Docker qui va nous permettre de déployer un serveur Teleport en quelques minutes.
Je scinderai la documentation en deux parties : une avec Traefik seul et une autre avec HAProxy/Traefik. Pourquoi HAProxy ? Il permet de router le traffic vers différents reverse-proxy suivant les url saisies (sans casser le chiffrement), ce qui est très pratique quand on veut héberger plusieurs infrastructures (prod, preprod, dev, lab...) avec une seule et même IP publique.
👋 Teleport
L'application bastion Teleport est une solution open-source développée par Teleport Inc. pour la gestion des accès sécurisés à des infrastructures informatiques. Elle propose des fonctionnalités telles que l'accès sécurisé aux serveurs SSH, aux machines Windows, aux clusters Kubernetes, aux bases de données, et aux applications internes, tout en centralisant la gestion des identités et des autorisations.
Dans cet exemple, Teleport nous servira de porte d'entrée depuis l'extérieur pour prendre la main sur des serveurs non exposés sur Internet. En tête de l'infra, j'ai mis OPNSense.

📋 Prérequis
Avant de se lancer il faut préparer les DNS locaux et du registrar. Dans cet exemple, les ndd seront :
- teleport.prod-1.domaine.fr
- *.teleport.prod-1.domaine.fr
Cas du DNS sur le LAN
Dans mon cas, j'utilise Pi-Hole pour mon LAN. Il suffit de déclarer le RR teleport.prod-1.domaine.fr
rattaché à l'IP (ici 10.100.1.253) du serveur faisant tourner Docker depuis l'interface web de PI-Home. De même j'ai créé un RR du type CNAME de *.teleport.prod-1.domaine.fr
associé à teleport.prod-1.domaine.fr
.
Il faut également déclaré le RR *.teleport.prod-1.domaine.fr
pointant vers la même IP de cette manière dans PI-Hole :
vim /etc/dnsmasq.d/07-my-teleport-dns.conf
address=/teleport.prod-1.domaine.fr/10.100.1.253
# Relance du service
service pihole-FTL restart
# Vérification
dig +short teleport.prod-1.domaine.fr
10.100.1.253
dig +short nddtemp.teleport.prod-1.domaine.fr
10.100.1.253
🧰 Installation de Teleport avec Traefik en frontend
Traefik
mkdir -p traefik/{config/{dyn_traefik,secrets},logs}
touch config/acme.json
chmod 600 config/acme.json
traefik/
|-- config/
| |-- acme.json
| |-- dyn_traefik/
| |-- secrets/
`-- logs/
Les fichiers contenant les secrets "ovh_*" seront contenus dans le répertoire traefik/config/secrets
. Ils seront utilisés pour l'authentification sur l'API d'OVH dans le cadre de la génération du certificat TLS avec Let's Encrypt et le challenge DNS.
---
networks:
traefik:
external: true
secrets:
ovh_endpoint:
file: "./config/secrets/ovh_endpoint.secret"
ovh_application_key:
file: "./config/secrets/ovh_application_key.secret"
ovh_application_secret:
file: "./config/secrets/ovh_application_secret.secret"
ovh_consumer_key:
file: "./config/secrets/ovh_consumer_key.secret"
services:
traefik:
image: "traefik:v3"
container_name: traefik
networks:
- traefik
secrets:
- "ovh_endpoint"
- "ovh_application_key"
- "ovh_application_secret"
- "ovh_consumer_key"
environment:
- "TZ=Europe/Paris"
- "OVH_ENDPOINT_FILE=/run/secrets/ovh_endpoint"
- "OVH_APPLICATION_KEY_FILE=/run/secrets/ovh_application_key"
- "OVH_APPLICATION_SECRET_FILE=/run/secrets/ovh_application_secret"
- "OVH_CONSUMER_KEY_FILE=/run/secrets/ovh_consumer_key"
volumes:
# Mapping sur le socket interne de Docker
- '/var/run/docker.sock:/var/run/docker.sock:ro'
# Mapping du fichier de configuration statique
- './config/traefik.yml:/traefik.yml'
# Mapping du dossier contenant la configuration dynamique
- './config/dyn_traefik/:/dyn_traefik/'
# Mapping du fichier de stockage des certificats
- './config/acme.json:/acme.json'
- "./logs:/var/log"
ports:
- "80:80"
- "443:443"
restart: unless-stopped
labels:
- "traefik.enable=true"
- "traefik.http.routers.traefik-dashboard.rule=Host(`traefik.prod-1.domaine.fr`)"
- "traefik.http.routers.traefik-dashboard.service=api@internal"
- "traefik.http.routers.traefik-dashboard.entrypoints=websecure"
- "traefik.http.routers.traefik-dashboard.tls.certresolver=letsencrypt"
- "traefik.http.routers.traefik-dashboard.middlewares=traefik-dashboard-ipallowlist"
- "traefik.http.middlewares.traefik-dashboard-ipallowlist.ipallowlist.sourcerange=127.0.0.1/32, 192.168.1.0/24"
- "traefik.http.services.traefik-dashboard-service.loadbalancer.server.port=8080"
---
api:
dashboard: true
providers:
docker:
endpoint: "unix:///var/run/docker.sock"
exposedByDefault: false
file:
directory: /dyn_traefik/
watch: true
entryPoints:
web:
address: ":80"
http:
redirections:
entryPoint:
to: websecure
scheme: https
websecure:
address: ":443"
certificatesResolvers:
letsencrypt:
acme:
caServer: "https://acme-v02.api.letsencrypt.org/directory"
email: "VOTRE_EMAIL"
storage: "/acme.json"
keyType: EC384
dnsChallenge:
provider: ovh
delayBeforeCheck: 10
resolvers:
- "1.1.1.1:53"
- "8.8.8.8:53"
# La connexion à Teleport se fera à travers
# une liaison https avec un certificat auto-signé
serversTransport:
insecureSkipVerify: true
log:
filePath: "/var/log/traefik.log"
format: json
level: INFO
maxSize: 5
maxBackups: 50
maxAge: 10
compress: true
accessLog:
filePath: "/var/log/access.log"
format: json
fields:
defaultMode: keep
names:
StartUTC: drop
Lancez la commande docker compose pull
. Nous lancerons les conteneurs après avoir la rotation des logs.
docker network create traefik
docker compose pull
docker compose up -d
Teleport
---
networks:
traefik:
external: true
services:
teleport:
image: public.ecr.aws/gravitational/teleport-distroless:17.4.2
container_name: teleport
volumes:
- ./config:/etc/teleport
- ./data:/var/lib/teleport
labels:
- "traefik.enable=true"
- "traefik.http.services.teleport-prod.loadbalancer.server.port=3080"
- "traefik.http.services.teleport-prod.loadbalancer.server.scheme=https"
- "traefik.http.routers.teleport-prod-https.entrypoints=websecure"
- "traefik.http.routers.teleport-prod-https.rule=Host(`teleport.maison.raspot.in`) || HostRegexp(`^.+.teleport.prod-1.domaine.fr$`)"
- "traefik.http.routers.teleport-prod-https.tls=true"
- "traefik.http.routers.teleport-prod-https.tls.certresolver=letsencrypt"
- "traefik.http.routers.teleport-prod-https.tls.domains[0].main=teleport.prod-1.domaine.fr"
- "traefik.http.routers.teleport-prod-https.tls.domains[0].sans=*.teleport.prod-1.domaine.fr"
networks:
- traefik
restart: unless-stopped
Configuration du service Teleport :
version: v3
teleport:
nodename: teleport.prod-1.domaine.fr
data_dir: /var/lib/teleport
log:
output: stderr
severity: INFO
format:
output: text
auth_service:
enabled: yes
listen_addr: 0.0.0.0:3025
proxy_listener_mode: multiplex
cluster_name: teleport.prod-1.domaine.fr
ssh_service:
enabled: no
proxy_service:
enabled: yes
web_listen_addr: 0.0.0.0:3080
public_addr: ['teleport.prod-1.domaine.fr:443']
https_keypairs: []
acme: {}
trust_x_forwarded_for: true # Pour récupérer l'IP réelle du client et non celle du CT Traefik
docker network create traefik
docker compose pull
docker compose up -d
Et voilà ! Il ne vous reste plus qu'à vous connecter sur l'URL https://teleport.prod-1.domaine.fr ou bien en utilisant la commande curl
.
curl https://teleport.prod-1.domaine.fr/
# Sortie
<a href="/web">Found</a>.
👤 Création du premier utilisateur
cd /src/docker/teleport
docker compose exec teleport tctl users add bart.simpson --roles=editor,access --logins=bart.simpson
User "bart.simpson" has been created but requires a password. Share this URL with the user to complete user setup, link is valid for 1h:
https://teleport.prod-1.domaine.fr:443/web/invite/c98f4d8ecdda397e3fe4c72aaa2d5352
NOTE: Make sure teleport.prod-1.domaine.fr:443 points at a Teleport proxy which users can access.
Rendez-vous sur l'URL en question et renseignez le formulaire d'inscription.

Paramétrez ensuite le MFA (avec Vaultwarden par exemple) :

Et vous voilà connecté au dashboard de Teleport. Vous pouvez dès à présent ajouter des serveurs ou des applications.
🧰 Installation de Teleport avec HAProxy et Traefik
HAproxy
(...)
frontend https
bind *:443
mode tcp
option tcplog
tcp-request inspect-delay 5s
tcp-request content accept if { req_ssl_hello_type 1 }
use_backend TRAEFIK_TELEPORT_HTTPS_BACKEND if { req_ssl_sni -i teleport.prod-1.domaine.fr }
use_backend TRAEFIK_TELEPORT_HTTPS_BACKEND if { req_ssl_sni -m end .teleport.prod-1.domaine.fr }
backend TRAEFIK_TELEPORT_HTTPS_BACKEND
mode tcp
server TRAEFIK_TELEPORT_HTTPS_BACKEND01 10.1.1.253:443 send-proxy check
(...)
Important : vous devez mettre send-proxy et non send-proxy-v2 sinon vous ne pourrez pas connecter les nodes Teleport au serveur.
Traefik
Modifiez la partie entryPoints du fichier config/traefik.yml
comme ceci :
---
(...)
entryPoints:
web:
address: ":80"
forwardedHeaders:
trustedIPs:
- "127.0.0.1/32"
- "10.100.1.254" # IP de HAProxy
proxyProtocol:
trustedIPs:
- "127.0.0.1/32"
- "10.100.1.254" # IP de HAProxy
http:
redirections:
entryPoint:
to: websecure
scheme: https
websecure:
address: ":443"
forwardedHeaders:
trustedIPs:
- "127.0.0.1/32"
- "10.100.1.254" # IP de HAProxy
proxyProtocol:
trustedIPs:
- "127.0.0.1/32"
- "10.100.1.254" # IP de HAProxy
(...)
🏁 Conclusion
L'installation de Teleport est clairement plus simple avec Docker et Traefik que l'installation bare-metal. Maintenant que notre serveur est opérationnel, nous allons renforcer la sécurité et connecter des serveurs et des applications.