# ============================================================================= # CLOUDFLARE : Access Controls : Applications > SSH (accès par clé classique) # ============================================================================= # BRIQUE SSH n°2 : accès SSH traditionnel par paire de clés, publié via le # tunnel Cloudflare. À comparer avec la brique n°1 (certificats éphémères, # Access_Controls-Service_Auth-Short_Lived_Certificates.tf). # # Chaîne complète : # 1. Terraform génère une paire de clés ED25519 (ci-dessous) # 2. L'application "ssh-classic" du tfvars publie ssh://:22 dans # l'ingress du tunnel home + crée le DNS ssh.tips-of-mine.org # 3. L'application Access ci-dessous protège ce hostname (IdP + MFA) # 4. Côté client : # cloudflared access ssh-config --hostname ssh.tips-of-mine.org # puis connexion habituelle : ssh -i user@ssh.tips-of-mine.org # # ACTIONS EXTERNES (voir ACTIONS_EXTERNES.md) : # - Déposer la clé publique (terraform output ssh_classic_public_key) dans # ~/.ssh/authorized_keys du serveur cible # - Récupérer la clé privée : terraform output -raw ssh_classic_private_key # ATTENTION : elle est stockée dans le state Terraform (bucket S3). C'est # le compromis de cette approche "classique" — c'est exactement ce que la # brique n°1 (certificats éphémères) permet d'éviter. # ============================================================================= #====================================================== # Paire de clés SSH d'exemple #====================================================== resource "tls_private_key" "ssh_classic" { algorithm = "ED25519" } #====================================================== # Application Access protégeant le hostname SSH #====================================================== resource "cloudflare_zero_trust_access_application" "cloudflare_home_app_ssh_classic" { account_id = local.cloudflare_account_id type = "self_hosted" name = "SSH classique par cle : Home" domain = "ssh.${var.cloudflare_zone}" app_launcher_visible = false session_duration = "24h" tags = [cloudflare_zero_trust_access_tag.tags["engineers"].name] custom_deny_url = "https://denied.tips-of-mine.org/" custom_non_identity_deny_url = "https://denied.tips-of-mine.org/" allowed_idps = [ cloudflare_zero_trust_access_identity_provider.authentik_oidc.id, ] auto_redirect_to_identity = true # Réutilise la politique admin de la brique Authentik policies = [{ id = cloudflare_zero_trust_access_policy.allow_policie_it_admin.id }] }