Teleport vs Warpgate : Bastion SSH avec SSO et RBAC automatisé

devops
teleport
warpgate
keycloak
ansible
ssh
security
Author

Sylvain Pham

Published

January 31, 2026

Retour d’expérience sur le déploiement de deux solutions de bastion SSH avec SSO Keycloak : Teleport et Warpgate. Comparaison, problèmes rencontrés, et automatisation RBAC avec Ansible.

Contexte

Objectif : sécuriser l’accès SSH aux VMs Azure (PROD et DEV) avec :

  • Authentification centralisée via Keycloak SSO
  • Gestion des rôles (RBAC) par environnement
  • Audit des connexions
  • Support VSCode Remote-SSH

Teleport vs Warpgate : Comparaison

Fonctionnalité Teleport OSS Warpgate
Terminal web ✅ Oui ❌ Non
VSCode Remote-SSH ✅ Transparent ⚠️ Approbation manuelle
SSO OIDC (Keycloak) ❌ Enterprise only ✅ Gratuit
SSH standard Via tsh ✅ Direct
VMs derrière VPN ✅ Agent outbound ❌ Proxy doit atteindre VMs

Verdict

  • Teleport : Meilleur pour VSCode et terminal web, mais SSO payant
  • Warpgate : SSO gratuit, mais expérience VSCode dégradée

Problèmes rencontrés

1. Teleport + Keycloak : OIDC non supporté en OSS

Problème : Teleport OSS ne supporte pas OIDC/SAML (réservé à Enterprise).

Solution : Utiliser des utilisateurs locaux Teleport avec tctl users add.

# Créer un utilisateur local
tctl users add alice --roles=vm-admin-global,access

2. Warpgate + VSCode : URL non cliquable

Problème : L’URL d’approbation SSO n’apparaît pas dans VSCode Remote-SSH.

Tentatives échouées :

{
  "remote.SSH.showLoginTerminal": true,
  "remote.SSH.useLocalServer": false
}

Ces settings causent des blocages après approbation.

Workaround : Garder un onglet Warpgate ouvert dans le navigateur pour approuver manuellement.

3. Teleport : “Too many authentication failures”

Problème : SSH échoue avec trop de clés dans l’agent.

Solution : Ajouter IdentitiesOnly yes dans ~/.ssh/config :

Host teleport-*
  ProxyCommand tsh proxy ssh %r@%h:%p
  IdentitiesOnly yes

4. Teleport : Version mismatch agents/serveur

Problème : Agents en 14.4.1, serveur en 14.3.36 → comportements incohérents.

Solution : Aligner toutes les versions :

# jobs/infra/teleport.nomad.hcl
image = "public.ecr.aws/gravitational/teleport:14.4.1"

5. VMs DEV (VPN) : Accès via Teleport sans VPN

Problème : Les VMs DEV sont sur IPs privées (172.x.x.x), accessibles uniquement via VPN.

Solution : L’agent Teleport se connecte en outbound vers le proxy public. Une fois l’agent installé, plus besoin de VPN.

VM DEV (172.x.x.x)  ──outbound──▶  teleport.example.com
     (agent)                            (proxy public)

Installation one-time (nécessite VPN) :

ssh -i ~/.ssh/key-dev.pem ubuntu@172.30.16.28 "bash -s" < install-agent.sh

6. Scripts Windows : Line endings CRLF

Problème : Scripts bash avec fins de ligne Windows → $'\r': command not found

Solution :

# Convertir localement
sed -i 's/\r$//' script.sh

# Ou ajouter .gitattributes
*.sh text eol=lf

RBAC avec Ansible

Structure

ansible/teleport/
├── users.yml          # Définition des utilisateurs et rôles
├── sync-users.yml     # Playbook de synchronisation
└── README.md

users.yml

users:
  - name: alice
    roles:
      - vm-admin-global
    email: alice@example.com

  - name: bob
    roles:
      - vm-user-dev-server1
    email: bob@example.com

  - name: charlie
    roles:
      - vm-readonly-global
    email: charlie@example.com

Playbook sync-users.yml

- name: Sync Teleport Users
  hosts: localhost
  tasks:
    - name: Load users from YAML
      include_vars:
        file: users.yml
        name: config

    - name: Update existing users
      shell: |
        ssh bastion "nomad alloc exec {{ alloc }} tctl users update {{ item.name }} --set-roles={{ item.roles | join(',') }},access"
      loop: "{{ config.users }}"
      when: item.name in existing_users

    - name: Create new users
      shell: |
        ssh bastion "nomad alloc exec {{ alloc }} tctl users add {{ item.name }} --roles={{ item.roles | join(',') }},access"
      loop: "{{ config.users }}"
      when: item.name not in existing_users

Usage

# Mode dry-run
ansible-playbook ansible/teleport/sync-users.yml --check

# Appliquer
ansible-playbook ansible/teleport/sync-users.yml

Résultat

TASK [Summary]
ok: [localhost] => {
    "msg": "Sync completed:\n- Total users in config: 10\n- Existing users updated: 10\n- New users created: 0\n"
}

Commandes Azure utiles

Récupérer les infos des VMs sans VPN (via API Azure) :

# Lister les VMs DEV
az vm list --subscription MY-SUBSCRIPTION -d -o table \
  --query "[].{Name:name, Hostname:osProfile.computerName, PrivateIP:privateIps}"

# Démarrer les VMs
az vm start --subscription MY-SUBSCRIPTION -g MY-RG -n my-vm --no-wait

# Éteindre les VMs
az vm deallocate --subscription MY-SUBSCRIPTION -g MY-RG -n my-vm --no-wait

Monitoring avec Grafana

Dashboard Grafana pour monitorer Teleport :

Dashboard Teleport dans Grafana

Métriques disponibles (Teleport OSS)

Métrique Description
teleport_connected_resources{type="node"} Nodes connectés
teleport_active_connections Connexions actives
teleport_registered_servers Serveurs enregistrés
teleport_audit_emit_events Événements d’audit
teleport_user_certificates_generated Certificats générés

Configuration Prometheus

scrape_configs:
  - job_name: 'teleport'
    static_configs:
      - targets: ['teleport:3434']

Note : Teleport OSS expose des métriques différentes de la version Enterprise. Les métriques comme teleport_audit_events_total n’existent pas en OSS.

Architecture finale

                         Internet
                            │
                            ▼
┌───────────────────────────────────────────────────────┐
│              teleport.example.com:443                 │
│              (Proxy + Auth sur Nomad)                 │
└───────────────────────────────────────────────────────┘
         ▲              ▲              ▲           ▲
         │              │              │           │
    ┌────┴────┐    ┌────┴────┐    ┌────┴────┐    outbound
    │ server1 │    │ server2 │    │ server3 │    HTTPS
    │ (PROD)  │    │ (PROD)  │    │ (DEV)   │      │
    └─────────┘    └─────────┘    └─────────┘      │
                                              ┌────┴────┐
                                              │ dev-vm  │
                                              │(DEV/VPN)│
                                              └─────────┘

Conclusion

Critère Recommandation
VSCode Remote-SSH Teleport
Terminal web Teleport
SSO gratuit Warpgate
VMs derrière VPN Teleport (agents outbound)
RBAC automatisé Ansible + YAML

Teleport est le meilleur choix malgré l’absence de SSO gratuit, car l’expérience utilisateur (VSCode, terminal web) est bien meilleure.

Liens