papanito.cloudflared
Rol de Ansible "papanito.cloudflared"
Esta rol de Ansible descarga e instala cloudflared
en el host y opcionalmente instala argo-tunnel como un servicio.
Cambios importantes en la versión 3.0.0
Este es un cambio importante para reflejar el nuevo comportamiento de túneles nombrados
La rol debería encargarse de la limpieza si usaste la rol antes de la versión 3.0.0. Sin embargo, tienes que actualizar la configuración (variables) en tu proyecto de Ansible. He renombrado las variables, en general prefijadas con
cf_
, para hacerlas únicas para la rol. Si no son únicas, puede suceder que las variables con el mismo nombre en diferentes roles tengan efectos secundarios no deseados.
Cloudflared y conexión de aplicaciones a túneles
Según 1, para crear y gestionar Túneles, primero debes:
- Descargar e instalar cloudflared en tu máquina
- Autenticar cloudflared
Una vez que cloudflared ha sido instalado y autenticado, el proceso para poner en marcha tu primer Túnel incluye 3 pasos generales:
Los pasos 4-5 se ejecutan una vez por Túnel, normalmente por un administrador, y el Paso 6 se ejecuta cada vez que se va a iniciar el Túnel, normalmente por el propietario del Túnel (quien puede ser diferente del administrador).
¿Qué hace la rol?
La rol tiene en realidad dos propósitos:
Instalación del daemon en el lado del servidor
La rol solo se encarga de configurar el servicio en los nodos, es decir, pasos 1, 2, 4 y 5 de arriba, porque
Crear túneles y habilitar el enrutamiento es una tarea que debe realizar un administrador y no la rol 1
Puedes configurar uno o múltiples [túneles nombrados] así como [un único servicio]; incluso así, con [túneles nombrados] usualmente solo necesitas un daemon. La rol efectivamente realiza los siguientes pasos:
Descargar e instalar el binario según downloads
Instalar/configurar el daemon - ver Autenticar el daemon
Para [túneles nombrados] se crea un [archivo de credenciales] en
{{ cf_credentials_dir }}/{{ tunnel_id }}.json
, similar a esto{"AccountTag":"{{ account_tag }}","TunnelSecret":"{{ tunnel_secret }}","TunnelID":"{{ tunnel_id }}","TunnelName":"{{ cf_tunnels.key }}"}
Para cada clave en
cf_tunnels
, crear una configuración de túnel en/etc/cloudflare
El archivo se llama
{{ tunnel }}.yml
y contendrá la configuración mínima, que es la siguiente:túneles nombrados
tunnel: {{ cf_tunnels.key }} credentials-file: {{ cf_credentials_dir }}/{{ tunnel_id }}.json ingress: {{ item.value.ingress }}
un solo servicio
hostname: {{ hostname }} url: {{ url }}
Se configuran parámetros adicionales mediante parámetros de configuración del túnel
Dependiendo de tu sistema de inicio - controlado por
cf_init_system
- la rol realiza lo siguienteSystemd
Crear una [plantilla de unidad de systemd]
cloudflared@{{ tunnel }}.service
y comenzar una instancia para cada servicio en la lista decf_tunnels
cloudflared tunnel --config {{ tunnel }}.yml
Sistemas Init-V
- Instalar servicio cloudflared en
/etc/init.d/{{ systemd_filename }}-{{ tunnel_name }}
- Vincular el script de detención a
/etc/init.d/{{ systemd_filename }}-{{ tunnel_name }}
- Vincular el script de inicio a
/etc/init.d/{{ systemd_filename }}-{{ tunnel_name }}
- Instalar servicio cloudflared en
Si usas [túneles nombrados], la rol también creará una [ruta dns].
Configuración del cliente SSH
Desde donde accesas a tus nodos a través de ssh, que está proxiedo por cloudflared, necesitas seguir [guía de ssh-cliente]. Tienes que añadir lo siguiente
Host xxx.mycompany.com
ProxyCommand /usr/bin/cloudflared access ssh --hostname %h
Puedes lograr esta configuración si habilitas cf_ssh_client_config
. Además, también necesitas especificar cf_ssh_client_config_group
. Así que asumamos que tu inventario se ve de la siguiente manera:
all:
children:
servers:
hosts:
host001:
host002:
Si especificas cf_ssh_client_config_group: servers
, obtendrás una entrada para host001
y host002
.
Requisitos
ninguno
Variables de la rol
Parámetros de instalación y desinstalación
Los siguientes parámetros controlan la instalación y/o desinstalación:
Parámetro | Descripción | Valor por defecto |
---|---|---|
cf_download_baseurl |
URL base para los binarios de cloudflare |
https://github.com/cloudflare/cloudflared/releases/latest/download/ |
cf_install_only |
Establecer a true si solo deseas instalar el binario sin configuración ni inicio de sesión |
false |
cf_ssh_client_config |
Establecer a true si deseas configurar la configuración del proxy para tu [guía de ssh-cliente] |
false |
cf_ssh_client_config_group |
Nombre del grupo de inventario para el cual se creará la configuración del proxy ssh | `` |
cf_force_install |
Establecer a true si deseas reinstalar cloudflared . Por defecto, se asume que cloudflared se está ejecutando como un servicio y se actualiza automáticamente. |
false |
cf_remove_unused_tunnel |
Elimina túneles cf_tunnels no utilizados, es decir, cf_tunnels que se están ejecutando pero no están listados en cf_tunnels . |
false |
cf_remove_setup_certificate |
Eliminar cert.pem después de instalar el servicio | false |
cf_credential_file_base |
Carpeta donde se colocan los archivos de credenciales | /root/.cloudflared/ |
cf_config_dir |
Carpeta donde se colocan los archivos de configuración de cloudflare | /etc/cloudflared |
cf_os_package_enable |
Usar el sistema de empaquetado del SO y el repositorio de paquetes de Cloudflare (actualmente solo Debian/Ubuntu) | false |
cf_repository_key_url |
Si cf_os_package_enable es verdadero, URL de la clave GPG para el repositorio apt | https://pkg.cloudflare.com/pubkey.gpg |
cf_repository_key_install_path |
Si cf_os_package_enable es verdadero, ruta donde instalar la clave GPG para el repositorio apt | /usr/share/keyrings/cloudflare-main.gpg |
cf_repository |
Si cf_os_package_enable es verdadero, URL para el repositorio apt de Cloudflare | deb [signed-by={{ cf_repository_key_install_path }}] https://pkg.cloudflare.com/cloudflared {{ ansible_distribution_release }} main |
cf_binary_name |
Nombre del binario del daemon de cloudflare - cambia solo si sabes lo que estás haciendo | cloudflared |
Parámetros del servicio Cloudflared
Estos son los parámetros requeridos para crear el servicio del sistema:
Parámetro | Descripción | Valor por defecto |
---|---|---|
cf_init_system |
Definir qué servicio de inicio usar. Los valores posibles son systemd e initv |
systemd |
cf_systemd_user |
Usuario para el servicio systemd en caso de cf_init_system: systemd |
root |
cf_systemd_group |
Grupo para el servicio systemd en caso de cf_init_system: systemd |
root |
cf_cert_location |
Ubicación del certificado que se debe copiar - ver Autenticar el daemon | - |
cf_cert_content |
Contenido del certificado que se debe copiar - ver Autenticar el daemon | - |
cf_tunnels |
[Obligatorio] Lista de servicios de túnel, cada uno definiendo parámetros de Cloudflare | - |
cf_sysctl_buffer_size_increase |
Aumentar el tamaño del buffer UDP recibido permitido por el SO (no BSD) - más detalles | false |
Se recomienda usar [túneles nombrados] para cf_tunnels
, lo que requiere parámetros de túnel nombrado de Cloudflare, pero también puedes usar parámetros de túnel heredados de Cloudflare.
Parámetros de túnel nombrado de 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 clave
del túnel debe coincidir con la de tunnel_id
.
Parámetro | Descripción | Valor por defecto |
---|---|---|
account_tag |
[Obligatorio] Etiqueta de cuenta del [archivo de credenciales] generado al crear un túnel | - |
tunnel_secret |
[Obligatorio] Secreto del túnel del [archivo de credenciales] generado al crear un túnel | - |
tunnel_id |
[Obligatorio] ID del túnel del [archivo de credenciales] generado al crear un túnel | - |
ingress |
[Obligatorio] [reglas de ingreso] para el túnel | - |
routes |
Lista de rutas que deben ser creadas. En este momento permite una lista para las rutas dns (ver ejemplo arriba) |
- |
Rutas
DNS
Las rutas dns
esperan una lista de CNAME
que se deben crear como se describe aquí. Si el CNAME
ya existe, la tarea se omitirá pero no se lanzará ningún error. Además, solo agrega CNAME
, no un FQDN, ya que el FQDN
es determinado por cloudflared
.
Red Privada
Las rutas de red privada
esperan una lista de CIDR
que se deben crear como se describe aquí. El playbook recorre la lista para ejecutar cloudflared tunnel route ip add {{ cf_cidr_entry }} {{ cf_tunnel.key }}
. Si el CIDR
ya existe, se lanzará un error pero se ignorará.
Balanceador de Carga
Las rutas lb
esperan una lista de balanceadores de carga existentes de cloudflared (más su grupo) para enrutarse a través del túnel como se describe aquí. El playbook recorre la lista para ejecutar cloudflared tunnel route lb {{ cf_tunnel.key }} {{ cf_lb_entry.host_name }} {{ cf_lb_entry.pool_name }}
. Si el túnel ya está vinculado al grupo, se lanzará un error ignorado.
Parámetros de servicio único de Cloudflare
Al igual que con versiones anteriores de estas roles, puedes usar el estilo de configuración de servicio único.
Si necesitas enviar tráfico solo a un servicio local, puedes hacerlo usando el archivo de configuración. Como alternativa, puedes configurar la configuración de servicio único.
cf_tunnels:
ssh:
hostname: xxx
url: ssh.mycompany.com
Parámetro | Descripción | Valor por defecto |
---|---|---|
hostname |
[Obligatorio] Nombre o único | - |
url |
[Obligatorio] URL a la que conectarse config e.g. ssh://localhost:22 o https://localhost:443 |
- |
Parámetros de configuración del túnel
Estos se utilizan para configurar los parámetros por servicio cloudflared. Aún puedes configurar Configuración por regla para túneles nombrados como parte del ingress
bajo cf_tunnels
.
Parámetro | Descripción | Valor por defecto |
---|---|---|
autoupdate_freq |
Frecuencia de actualización automática - ver documentación | 24h |
edge_ip_version |
Especifica la versión de dirección IP (IPv4 o IPv6) utilizada para establecer una conexión entre cloudflared y la red global de Cloudflare. Los valores disponibles son auto , 4 , y 6 |
auto |
edge_bind_address |
Especifica la dirección IP de salida utilizada para establecer una conexión entre cloudflared y la red global de Cloudflare | - |
grace_period |
Cuando cloudflared recibe SIGINT/SIGTERM dejará de aceptar nuevas solicitudes, esperará a que se terminen las solicitudes en curso y luego se apagará. Esperar las solicitudes en curso tendrá un tiempo de espera después de este período de gracia, o cuando se reciba una segunda señal SIGTERM/SIGINT | 30s |
metrics |
Dirección para consultar métricas de uso - ver documentación | localhost: |
metrics_update_freq |
Frecuencia para actualizar métricas del túnel - ver documentación | 5s |
no_autoupdate |
Deshabilitar la verificación periódica de actualizaciones, reiniciando el servidor con la nueva versión - ver documentación | false |
no_chunked_encoding |
Desactiva la codificación de transferencia fragmentada; útil si estás ejecutando un servidor WSGI - ver documentación | false |
no_tls_verify |
Desactiva la verificación TLS del certificado presentado por tu origen. Aceptará cualquier certificado del origen - ver documentación | - |
origin_server_name |
Nombre de host que cloudflared debería esperar de tu certificado de servidor de origen - ver documentación |
- |
origin_ca_pool |
Ruta al CA para el certificado de tu origen. Esta opción debe usarse solo si tu certificado no está firmado por Cloudflare - ver documentación | - |
protocol |
Especifica el protocolo a utilizar para el túnel - ver documentación | auto |
logfile |
Habilita la escritura de un archivo de registro para cloudflared - aún registrará en el journal | true |
loglevel |
Especifica la verbosidad del registro. El valor predeterminado "info" no es ruidoso, pero puedes desear ejecutarlo con "warn" en producción - ver documentación | info |
region |
Te permite elegir las regiones a las que se establecen las conexiones. Omite o deja vacío para conectar a la región global. Configura --region=us para enrutear todas las conexiones a través de las regiones 1 y 2 de EE.UU. |
- |
retries |
Número máximo de reintentos para errores de conexión/protocolo. Los reintentos usan retroceso exponencial (reintentando en 1, 2, 4, 8, 16 segundos por defecto), así que no se recomienda aumentar este valor significativamente - ver documentación | 5 |
tag |
Etiquetas personalizadas utilizadas para identificar este túnel, en formato KEY=VALUE - ver documentación |
- |
token |
Asocia la instancia de cloudflared con un túnel específico. El token del túnel se muestra en el panel cuando creas el túnel por primera vez. También puedes recuperar el token usando la API | - |
transport_loglevel |
Especifica la verbosidad de los registros para el transporte entre cloudflared y el borde de Cloudflare. Los niveles disponibles son: trace , debug , info , warn , error , fatal , panic . Cualquier valor por debajo de "warn" produce una salida sustancial y solo debe usarse para depurar problemas de rendimiento de bajo nivel y peculiaridades de protocolo - ver documentación |
info |
warp_routing |
Permitir a los usuarios conectarse a servicios internos utilizando WARP, más detalles ver warp-routing | false |
Dependencias
ninguna
Ejemplos de Playbooks
El siguiente ejemplo instala un servicio único para un túnel ssh para cada servidor
.
- 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
El siguiente ejemplo instala un [túnel nombrado] servidores
con una entrada a {{ inventory_hostname }}.mycompany.com
para ssh y un [hola mundo] si accedes a hello-{{ inventory_hostname }}.mycompany.com
a través del navegador.
- 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
El siguiente ejemplo simplemente descarga cloudflared
en tu máquina local y configura el archivo ssh-config:
- hosts: localhost
remote_user: papanito # tu usuario local con permisos de administrador
vars:
cf_install_only: true
cf_ssh_client_config: true
cf_ssh_client_config_group: servers
roles:
- papanito.cloudflared
Prueba
ansible-playbook tests/test.yml -i tests/inventory
Información Adicional
Autenticación del daemon
Según authenticate-the-cloudflare-daemon, al autenticar el daemon, se abrirá una ventana del navegador o, si esto no es posible, se deberá colocar el enlace manualmente. Durante este tiempo el daemon espera. No pude idear una solución para automatizar este comportamiento, así que propuse la siguiente implementación.
Si no se especifica nada, entonces ansible llama a
cloudflared login
y continuará cuando la autenticación esté lista - esto tiene sentido si usas la rol para instalar el daemon localmente en tu máquina y donde tienes una ventana del navegador.Si
cf_cert_location
, el certificado se copia de efectivamente desdecf_cert_location
, o sicf_cert_content
está definido, el certificado se crea directamente desde el valor almacenado en él. Así que podrías iniciar sesión una vez en cloudflare desde tu nodo maestro (donde ejecutas ansible) o desde una ubicación remota.Puedes cifrar el
cert.pem
con ansible vault y almacenarlo en un lugar seguro.
Referencias:
- downloads - instrucciones de descarga de cloudflared
- ssh-guide - conexiones ssh con cloudflared
- cli-args - argumentos de línea de comandos
- config - El formato del archivo de configuración usa sintaxis YAML
Licencia
Este es Software Libre, lanzado bajo los términos de la licencia Apache v2.
Información del Autor
Ansible role do install and run cloudflare argo tunnel
ansible-galaxy install papanito.cloudflared