papanito.cloudflared

Rôle Ansible "papanito.cloudflared"

Ansible Role Ansible Quality Score Ansible Role GitHub issues GitHub pull requests

Ce rôle Ansible télécharge et installe cloudflared sur l'hôte et, en option, installe argo-tunnel en tant que service.

Changements majeurs avec la version 3.0.0

Il s'agit d'un changement important pour refléter le nouveau comportement des tunnels nommés

Le rôle doit gérer le nettoyage si vous avez utilisé le rôle avant la version 3.0.0. Cependant, vous devez mettre à jour la configuration (variables) dans votre projet Ansible. J'ai renommé les variables - elles sont généralement préfixées par cf_ afin de les rendre uniques au rôle. Si elles ne sont pas uniques, il peut arriver que des variables utilisant le même nom dans différents rôles aient des effets secondaires indésirables.

Cloudflared et connexion des applications aux tunnels

Selon 1, pour créer et gérer des Tunnels, vous devez d'abord :

  1. Télécharger et installer cloudflared sur votre machine
  2. Authentifier cloudflared

Une fois cloudflared installé et authentifié, le processus pour mettre votre premier Tunnel en fonction comprend 3 étapes principales :

  1. Créer un Tunnel
  2. Router le trafic vers votre Tunnel
  3. Exécuter votre Tunnel

Les étapes 4-5 sont exécutées une fois par Tunnel, normalement par un administrateur, et l'étape 6 est exécutée chaque fois que le Tunnel doit être démarré, généralement par le propriétaire du Tunnel (qui peut être différent de l'administrateur).

Que fait le rôle ?

Le rôle a en réalité deux objectifs :

Installation du démon côté serveur

Le rôle s'occupe uniquement de configurer le service sur les nœuds, c'est-à-dire les étapes 1, 2, 4 et 5 ci-dessus, car

La création de tunnels et l'activation du routage sont des tâches qui doivent être effectuées par un administrateur et non par le rôle 1

Vous pouvez configurer un ou plusieurs [tunnels nommés] ainsi qu'un [service unique] - cependant, avec les [tunnels nommés], vous n'avez généralement besoin que d'un seul démon. Le rôle exécute réellement ces étapes :

  1. Télécharger et installer le binaire selon [les téléchargements]

  2. Installer/configurer le démon - voir Authentifier le démon

  3. Pour les [tunnels nommés], un [fichier de credentials] est créé sous {{ cf_credentials_dir }}/{{ tunnel_id }}.json semblable à ceci

    {"AccountTag":"{{ account_tag }}","TunnelSecret":"{{ tunnel_secret }}","TunnelID":"{{ tunnel_id }}","TunnelName":"{{ cf_tunnels.key }}"}
    
  4. Pour chaque clé dans cf_tunnels, créez une configuration de tunnel dans /etc/cloudflare

    Le fichier est nommé {{ tunnel }}.yml et contiendra la configuration minimale comme suit :

    tunnels nommés

    tunnel: {{ cf_tunnels.key }}
    credentials-file: {{ cf_credentials_dir }}/{{ tunnel_id }}.json
    ingress:
      {{ item.value.ingress }}
    

    service unique

    hostname: {{ hostname }}
    url: {{ url }}
    

    Des paramètres supplémentaires sont configurés à l'aide des paramètres de configuration du tunnel

  5. En fonction de votre système d'init - contrôlé par cf_init_system - le rôle effectue les actions suivantes :

    • Systemd

      Crée un [modèle d'unité systemd] cloudflared@{{ tunnel }}.service et démarre une instance pour chaque service dans la liste de cf_tunnels

      cloudflared tunnel --config {{ tunnel }}.yml
      
    • Systèmes Init-V

      1. Installez le service cloudflared dans /etc/init.d/{{ systemd_filename }}-{{ tunnel_name }}
      2. Lien du script d'arrêt vers /etc/init.d/{{ systemd_filename }}-{{ tunnel_name }}
      3. Lien du script de démarrage vers /etc/init.d/{{ systemd_filename }}-{{ tunnel_name }}
  6. Si vous utilisez [tunnels nommés], le rôle créera également une [route dns].

Configuration du client SSH

Depuis lequel vous accédez à vos nœuds via ssh proxy par cloudflared, vous devez suivre le [guide ssh-client]. Vous devez ajouter ce qui suit

Host xxx.mycompany.com
  ProxyCommand /usr/bin/cloudflared access ssh --hostname %h

Vous pouvez réaliser cette configuration si vous activez cf_ssh_client_config. En plus, vous devez également spécifier cf_ssh_client_config_group. Supposons que votre inventaire ressemble à ceci :

all:
  children:
    servers:
      hosts:
        host001:
        host002:

Si vous spécifiez cf_ssh_client_config_group: servers, vous obtiendrez une entrée pour host001 et host002.

Exigences

aucune

Variables du rôle

Paramètres d'installation et de désinstallation

Les paramètres suivants contrôlent l'installation et/ou la désinstallation.

Paramètre Description Valeur par défaut
cf_download_baseurl URL de base pour les binaires cloudflare https://github.com/cloudflare/cloudflared/releases/latest/download/
cf_install_only Mettez à true si vous souhaitez uniquement installer le binaire sans aucune configuration ou connexion false
cf_ssh_client_config Mettez à true si vous souhaitez configurer la configuration proxy pour votre [guide ssh-client], voir Configuration du client SSH false
cf_ssh_client_config_group Nom du groupe d'inventaire pour lequel la configuration proxy ssh sera créée, voir Configuration du client SSH ``
cf_force_install Mettez à true si vous souhaitez réinstaller cloudflared. Par défaut, on part du principe que cloudflared s'exécute en tant que service et se met automatiquement à jour. false
cf_remove_unused_tunnel Supprime les cf_tunnels non utilisés, c'est-à-dire les cf_tunnels exécutés mais non listés dans cf_tunnels. false
cf_remove_setup_certificate Supprime cert.pem après l'installation du service false
cf_credential_file_base Dossier où placer les fichiers d'identification /root/.cloudflared/
cf_config_dir Dossier où placer les fichiers de configuration cloudflare /etc/cloudflared
cf_os_package_enable Utiliser le système de paquets OS et le dépôt de paquets Cloudflare (actuellement juste Debian/Ubuntu) false
cf_repository_key_url Si cf_os_package_enable est vrai, URL de la clé GPG pour le dépôt apt https://pkg.cloudflare.com/pubkey.gpg
cf_repository_key_install_path Si cf_os_package_enable est vrai, chemin où installer la clé GPG pour le dépôt apt /usr/share/keyrings/cloudflare-main.gpg
cf_repository Si cf_os_package_enable est vrai, URL pour le dépôt apt Cloudflare deb [signed-by={{ cf_repository_key_install_path }}] https://pkg.cloudflare.com/cloudflared {{ ansible_distribution_release }} main
cf_binary_name Nom du binaire de démon cloudflare - à changer seulement si vous savez ce que vous faites cloudflared

Paramètres de service Cloudflared

Ce sont des paramètres requis pour créer le service système.

Paramètre Description Valeur par défaut
cf_init_system Définir quel service d'init utiliser. Les valeurs possibles sont systemd et initv systemd
cf_systemd_user Utilisateur pour le service systemd en cas cf_init_system: systemd root
cf_systemd_group Groupe pour le service systemd en cas cf_init_system: systemd root
cf_cert_location Emplacement du certificat à copier - voir Authentifier le démon -
cf_cert_content Contenu du certificat à copier - voir Authentifier le démon -
cf_tunnels [Obligatoire] Liste des services de tunnel, chacun définissant paramètres Cloudflare -
cf_sysctl_buffer_size_increase Augmente la taille du tampon de réception UDP autorisée par l'OS (non BSD) - plus de détails false

Il est recommandé d'utiliser des [tunnels nommés] pour cf_tunnels qui nécessitent paramètres de tunnel nommé Cloudflare mais vous pouvez également utiliser des paramètres de tunnel hérités Cloudflare

Paramètres de tunnel nommé Cloudflare

  ...
    cf_tunnels:
      test:
        routes:
          dns:
            - "{{ inventory_hostname }}"
          cidr:
            - "192.168.42.0/24"
          lb:
            - hostname: website.mycompany.com
              poolname: bzh-west1.website.mycompany.com
        account_tag:  !vault....
        tunnel_secret: !vault....
        tunnel_id: !vault....
        ingress:
          - hostname: website.mycompany.com
            service: http://localhost:1313
          - hostname: hello.mycompany.com
            service: hello_world
          - hostname: ssh.mycompany.com
            service: ssh://localhost:22
          - service: http_status:404

La clé du tunnel doit correspondre à celle de tunnel_id.

Paramètre Description Valeur par défaut
account_tag [Obligatoire] Tag de compte du [fichier de credentials] généré lors de la création d'un tunnel -
tunnel_secret [Obligatoire] Secret du tunnel du [fichier de credentials] généré lors de la création d'un tunnel -
tunnel_id [Obligatoire] ID du tunnel du [fichier de credentials] généré lors de la création d'un tunnel -
ingress [Obligatoire] [règles d'ingress] pour le tunnel -
routes Liste des routes à créer. Cela permet une liste pour les routes dns pour le moment (voir l'exemple ci-dessus) -

Routes

DNS

Les routes dns s'attendent à une liste de CNAME à créer comme décrit ici. Si le CNAME existe déjà, la tâche sera ignorée mais aucune erreur ne sera lancée. N'ajoutez également que des CNAME, pas un FQDN, car le FQDN est déterminé par cloudflared.

Réseau Privé

Les routes réseau privé s'attendent à une liste de CIDR à créer comme décrit ici. Le playbook boucle sur la liste pour exécuter cloudflared tunnel route ip add {{ cf_cidr_entry }} {{ cf_tunnel.key }}. Si le CIDR existe déjà, une erreur sera lancée mais ignorée.

Équilibreur de Charge

Les routes lb s'attendent à une liste de balancers de charge cloudflared existants (ainsi que son pool) sur lequel router le tunnel comme décrit ici. Le playbook boucle sur la liste pour exécuter cloudflared tunnel route lb {{ cf_tunnel.key }} {{ cf_lb_entry.host_name }} {{ cf_lb_entry.pool_name }}. Si le tunnel est déjà lié au pool, une erreur ignorée sera lancée.

Paramètres de service unique Cloudflare

Comme avec les versions précédentes de ce rôle, vous pouvez utiliser le [style de configuration de service unique][service unique]

Si vous devez proxy le trafic vers un seul service local, vous pouvez le faire en utilisant le fichier de configuration. En alternative, vous pouvez configurer une configuration de service unique.

cf_tunnels:
  ssh:
    hostname: xxx
    url: ssh.mycompany.com
Paramètre Description Valeur par défaut
hostname [Obligatoire] Nom ou unique -
url [Obligatoire] URL à laquelle se connecter config par exemple ssh://localhost:22 ou https://localhost:443 -

Paramètres de configuration du tunnel

Ceux-ci sont utilisés pour configurer les paramètres par service cloudflared. Vous pouvez toujours configurer des configuration par règle pour les tunnels nommés dans le cadre de l'ingress sous cf_tunnels.

Paramètre Description Valeur par défaut
autoupdate_freq Fréquence de mise à jour automatique - voir docu 24h
edge_ip_version Spécifie la version de l'adresse IP (IPv4 ou IPv6) utilisée pour établir une connexion entre cloudflared et le réseau global Cloudflare. Les valeurs disponibles sont auto, 4 et 6 auto
edge_bind_address Spécifie l'adresse IP sortante utilisée pour établir une connexion entre cloudflared et le réseau global Cloudflare -
grace_period Lorsque cloudflared reçoit SIGINT/SIGTERM, il cessera d'accepter de nouvelles requêtes, attendra que les requêtes en cours se terminent, puis s'arrêtera. Le temps d'attente pour les requêtes en cours expirera après cette période de grâce, ou lorsqu'un deuxième SIGTERM/SIGINT est reçu 30s
metrics Adresse pour interroger les statistiques d'utilisation - voir docu localhost:
metrics_update_freq Fréquence de mise à jour des statistiques de tunnel - voir docu 5s
no_autoupdate Désactive la vérification périodique des mises à jour, redémarrant le serveur avec la nouvelle version - voir docu false
no_chunked_encoding Désactive l'encodage de transfert fragmenté ; utile si vous exécutez un serveur WSGI - voir docu false
no_tls_verify Désactive la vérification TLS du certificat présenté par votre origine. Permettra à tout certificat de l'origine d'être accepté - voir docu -
origin_server_name Nom d'hôte que cloudflared doit attendre du certificat de votre serveur d'origine - voir docu -
origin_ca_pool Chemin vers l'CA pour le certificat de votre origine. Cette option ne doit être utilisée que si votre certificat n'est pas signé par Cloudflare - voir docu -
protocol Spécifie le protocole à utiliser pour le tunnel - voir docu auto
logfile Permet d'écrire un fichier journal pour cloudflared - il continuera à consigner dans le journal true
loglevel Spécifie la verbosité des journaux. Le paramètre par défaut "info" n'est pas bruyant, mais vous pouvez souhaiter exécuter avec "warn" en production - voir docu info
region Vous permet de choisir les régions vers lesquelles les connexions sont établies. Omettez ou laissez vide pour vous connecter à la région globale. Réglez --region=us pour router toutes les connexions par les régions 1 et 2 des États-Unis -
retries Nombre maximum de tentatives pour des erreurs de connexion/protocole. Les tentatives utilisent un backoff exponentiel (réessayant à 1, 2, 4, 8, 16 secondes par défaut), donc augmenter considérablement cette valeur n'est pas recommandé - voir docu 5
tag Tags personnalisés utilisés pour identifier ce tunnel, au format KEY=VALUE - voir docu -
token Associe l'instance cloudflared à un tunnel spécifique. Le token du tunnel est affiché dans le tableau de bord lorsque vous créez pour la première fois le tunnel. Vous pouvez également récupérer le token à l'aide de l'API -
transport_loglevel Spécifie la verbosité des journaux pour le transport entre cloudflared et l'edge Cloudflare. Les niveaux disponibles sont : trace, debug, info, warn, error, fatal, panic. Toute valeur en dessous de warn produit une sortie considérable et ne doit être utilisée que pour déboguer des problèmes de performance de bas niveau et des anomalies de protocole - voir docu info
warp_routing Permet aux utilisateurs de se connecter à des services internes en utilisant WARP, détails voir warp-routing false

Dépendances

aucune

Exemples de Playbooks

L'exemple suivant installe un service unique pour un tunnel ssh pour chaque serveur.

- hosts: servers
  vars:
    cf_systemd_user: root
    cf_systemd_group: root
    cf_cert_location: /home/papanito/cert.pem
    services:
      ssh:
        hostname: "{{ inventory_hostname }}.mycompany.com"
        url: ssh://localhost:22
  roles:
    - papanito.cloudflared

L'exemple suivant installe un [tunnel nommé] servers avec un ingress à {{ inventory_hostname }}.mycompany.com pour ssh et un hello world si vous accédez à hello-{{ inventory_hostname }}.mycompany.com via le navigateur.

- hosts: servers
  remote_user: ansible
  become: true
  vars:
    cf_cert_location: /home/papanito/.cloudflared/cert.mycompany.com.pem
    cf_tunnels:
      test:
        account_tag: !vault...
        tunnel_secret: !vault...
        tunnel_id: !vault...
        routes:
          dns:
          - "{{ inventory_hostname }}"
          - "hello-{{ inventory_hostname }}"
        ingress:
        - hostname: "hello-{{ inventory_hostname }}.mycompany.com"
          service: hello_world
        - hostname: "{{ inventory_hostname }}.mycompany.com"
          service: ssh://localhost:22
        - service: http_status:404
  roles:
    - papanito.cloudflared

L'exemple suivant télécharge simplement cloudflared sur votre machine locale et configure le fichier ssh-config :

- hosts: localhost
  remote_user: papanito #votre utilisateur local ayant des droits d'admin
  vars:
    cf_install_only: true
    cf_ssh_client_config: true
    cf_ssh_client_config_group: servers
  roles:
    - papanito.cloudflared

Test

ansible-playbook tests/test.yml -i tests/inventory

Informations Supplémentaires

Authentifier le démon

Selon [authentifier-le-démon-cloudflare], lors de l'authentification du démon, une fenêtre de navigateur s'ouvre ou - si cela n'est pas possible - il faut mettre le lien manuellement. Pendant ce temps, le démon attend. Je n'ai pas trouvé de solution pour automatiser ce comportement, alors j'ai mis en place l'implémentation suivante.

  • Si rien n'est spécifié, Ansible appelle cloudflared login et continuera lorsque l'authentification sera terminée - cela a du sens si vous utilisez le rôle pour installer le démon localement sur votre machine où vous avez une fenêtre de navigateur.

  • Si cf_cert_location est défini, le certificat est effectivement copié depuis cf_cert_location, ou si cf_cert_content est défini alors le certificat est créé directement à partir de la valeur stockée. Vous pourriez donc vous connecter une fois à Cloudflare depuis votre nœud maître (où vous exécutez Ansible) ou d'un emplacement distant.

    Vous pouvez chiffrer cert.pem avec ansible vault et le stocker quelque part en sécurité.

Références :

  • [téléchargements] - instructions de téléchargement de cloudflared
  • [guide-ssh] - connexions ssh avec cloudflared
  • cli-args - arguments de ligne de commande
  • config - Le format du fichier de configuration utilise la syntaxe YAML

Licence

C'est un logiciel libre, publié sous les termes de la licence Apache v2.

Informations sur l'auteur

Écrit par Papanito - Gitlab / Github

À propos du projet

Ansible role do install and run cloudflare argo tunnel

Installer
ansible-galaxy install papanito.cloudflared
Licence
apache-2.0
Téléchargements
2.3k
Propriétaire
A passionate DevOps Engineer from Switzerland, father of five and husband of the most beautiful and most amazing woman in the world.