cloudflared
Ansible роль "papanito.cloudflared"
Эта роль Ansible загружает и устанавливает cloudflared
на хост и по желанию устанавливает [argo-tunnel] в качестве сервиса.
Существенные изменения в версии 3.0.0
Это изменение, касающееся нового поведения именованных туннелей
Роль должна позаботиться о подготовке, если вы использовали ее до версии 3.0.0. Однако вы должны обновить конфигурацию (переменные) в вашем проекте Ansible. Я переименовал переменные - обычно с префиксом
cf_
, чтобы сделать их уникальными для роли. Если они не уникальны, может произойти, что переменные с одинаковыми именами в разных ролях могут иметь нежелательные побочные эффекты.
Cloudflared и подключение приложений к туннелям
Согласно [1], для создания и управления туннелями, вам сначала нужно:
- Скачать и установить cloudflared на вашем компьютере.
- Аутентифицировать cloudflared.
После установки и аутентификации cloudflared, процесс создания первого туннеля включает 3 основных шага:
Шаги 4-5 выполняются один раз для каждого туннеля, обычно администратором, а шаг 6 выполняется каждый раз, когда туннель необходимо запустить, обычно владельцем туннеля (который может отличаться от администратора).
Что делает роль?
Роль на самом деле имеет две цели:
Установка демон-системы на стороне сервера
Роль отвечает только за настройку сервиса на узлах, то есть выполняет шаги 1, 2, 4 и 5 из вышеуказанных, поскольку
Создание туннелей и включение маршрутизации - это задача администратора, а не роли [1].
Вы можете настроить одно или несколько [именованных туннелей], а также [один сервис] - даже так, для [именованных туннелей] обычно нужен только один демон. Роль фактически выполняет следующие шаги:
Скачать и установить двоичный файл согласно [загрузкам].
Установить/настроить демон - см. Аутентификация демона.
Для [именованных туннелей] создается [файл учетных данных] в
{{ cf_credentials_dir }}/{{ tunnel_id }}.json
, похожий на этот{"AccountTag":"{{ account_tag }}","TunnelSecret":"{{ tunnel_secret }}","TunnelID":"{{ tunnel_id }}","TunnelName":"{{ cf_tunnels.key }}"}
Для каждого ключа в
cf_tunnels
создается конфигурация туннеля в/etc/cloudflare
.Файл называется
{{ tunnel }}.yml
и будет содержать минимальную конфигурацию:Именованные туннели
tunnel: {{ cf_tunnels.key }} credentials-file: {{ cf_credentials_dir }}/{{ tunnel_id }}.json ingress: {{ item.value.ingress }}
Один сервис
hostname: {{ hostname }} url: {{ url }}
Дополнительные параметры настраиваются с помощью Параметры конфигурации туннеля.
В зависимости от вашей системы инициализации - в соответствии с
cf_init_system
- роль выполняет следующее:Systemd
Создает [шаблон юнита systemd]
cloudflared@{{ tunnel }}.service
и запускает экземпляр для каждого сервиса в спискеcf_tunnels
.cloudflared tunnel --config {{ tunnel }}.yml
Init-V системы
- Устанавливает сервис cloudflared в
/etc/init.d/{{ systemd_filename }}-{{ tunnel_name }}
. - Создает символическую ссылку на скрипт остановки в
/etc/init.d/{{ systemd_filename }}-{{ tunnel_name }}
. - Создает символическую ссылку на скрипт запуска в
/etc/init.d/{{ systemd_filename }}-{{ tunnel_name }}
.
- Устанавливает сервис cloudflared в
Если вы используете [именованные туннели], роль также создаст [dns маршрут].
Настройка SSH клиента
Для доступа к вашим узлам через ssh, который проксируется через cloudflared, вам нужно следовать [гайду ssh-клиента]. Вы должны добавить следующее
Host xxx.mycompany.com
ProxyCommand /usr/bin/cloudflared access ssh --hostname %h
Вы можете достигнуть этой конфигурации, если включите cf_ssh_client_config
. Кроме того, вам нужно также указать cf_ssh_client_config_group
. Предположим, ваши инвентарные данные выглядят следующим образом:
all:
children:
servers:
hosts:
host001:
host002:
Если вы укажете cf_ssh_client_config_group: servers
, вы получите запись для host001
и host002
.
Требования
Отсутствуют.
Переменные роли
Параметры установки и удаления
Следующие параметры контролируют установку и/или удаление:
Параметр | Описание | Значение по умолчанию |
---|---|---|
cf_download_baseurl |
Базовый URL для двоичных файлов cloudflare |
https://github.com/cloudflare/cloudflared/releases/latest/download/ |
cf_install_only |
Установите значение true , если вы хотите только установить двоичный файл без настройки или входа в систему |
false |
cf_ssh_client_config |
Установите значение true , если вы хотите настроить прокси-конфигурацию для вашего [ssh-гайда клиента], см. Настройка SSH клиента |
false |
cf_ssh_client_config_group |
Имя группы инвентаря, для которой должна быть создана конфигурация прокси ssh, см. Настройка SSH клиента | `` |
cf_force_install |
Установите значение true , если вы хотите переустановить cloudflared . По умолчанию предполагается, что cloudflared работает как сервис и автоматически обновляется. |
false |
cf_remove_unused_tunnel |
Удаляет неиспользуемые cf_tunnels, т.е. cf_tunnels, работающие, но не указанные в cf_tunnels . |
false |
cf_remove_setup_certificate |
Удаляет cert.pem после установки сервиса | false |
cf_credential_file_base |
Папка, где размещать файлы учетных данных | /root/.cloudflared/ |
cf_config_dir |
Папка для расположения конфигурационных файлов cloudflare | /etc/cloudflared |
cf_os_package_enable |
Использовать систему упаковки ОС и репозиторий пакетов Cloudflare (в настоящее время только Debian/Ubuntu) | false |
cf_repository_key_url |
Если cf_os_package_enable равно true, URL GPG-ключа для репозитория apt | https://pkg.cloudflare.com/pubkey.gpg |
cf_repository_key_install_path |
Если cf_os_package_enable равно true, путь для установки GPG-ключа для репозитория apt | /usr/share/keyrings/cloudflare-main.gpg |
cf_repository |
Если cf_os_package_enable равно true, URL для репозитория Cloudflare apt | deb [signed-by={{ cf_repository_key_install_path }}] https://pkg.cloudflare.com/cloudflared {{ ansible_distribution_release }} main |
cf_binary_name |
Имя двоичного файла демона cloudflare - измените только если вы уверены в своих действиях | cloudflared |
Параметры сервиса Cloudflared
Это параметры, необходимые для создания системного сервиса:
Параметр | Описание | Значение по умолчанию |
---|---|---|
cf_init_system |
Определите, какую службу инициализации использовать. Возможные значения: systemd и initv |
systemd |
cf_systemd_user |
Пользователь для сервиса systemd в случае cf_init_system: systemd |
root |
cf_systemd_group |
Группа для сервиса systemd в случае cf_init_system: systemd |
root |
cf_cert_location |
Место нахождения сертификата, который будет скопирован - см. Аутентификация демона | - |
cf_cert_content |
Содержимое сертификата, который будет скопирован - см. Аутентификация демона | - |
cf_tunnels |
[Обязательно] Список сервисов туннеля, каждый из которых определяет параметры Cloudflare | - |
cf_sysctl_buffer_size_increase |
Увеличить размер буфера приема UDP, разрешенный ОС (не BSD) - больше деталей | false |
Рекомендуется использовать [именованные туннели] для cf_tunnels
, которые требуют параметров именованного туннеля Cloudflare, но вы также можете использовать параметры старого туннеля Cloudflare.
Параметры именованного туннеля 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
key
туннеля должно совпадать с tunnel_id
.
Параметр | Описание | Значение по умолчанию |
---|---|---|
account_tag |
[Обязательно] Тег учетной записи из [файла учетных данных], созданного при создании туннеля | - |
tunnel_secret |
[Обязательно] Секрет туннеля из [файла учетных данных], созданного при создании туннеля | - |
tunnel_id |
[Обязательно] ID туннеля из [файла учетных данных], созданного при создании туннеля | - |
ingress |
[Обязательно] [правила входа] для туннеля | - |
routes |
Список маршрутов, которые должны быть созданы. В данный момент допускается список для dns -маршрутов (см. пример выше) |
- |
Маршруты
DNS
Маршруты dns
ожидают список CNAME
, которые нужно создать, как здесь описано. Если CNAME
уже существует, задача будет пропущена, но ошибка не будет выдана. Также добавляйте только CNAME
, а не FQDN, так как FQDN
определяется cloudflared
.
Частная сеть
Маршруты private network
ожидают список CIDR
, которые нужно создать, как здесь описано. Плейбук выполняет цикл по списку, чтобы выполнить cloudflared tunnel route ip add {{ cf_cidr_entry }} {{ cf_tunnel.key }}
. Если CIDR
уже существует, ошибка будет выдана, но игнорируется.
Балансировщик нагрузки
Маршруты lb
ожидают список существующих балансировщиков нагрузки cloudflared (плюс их пула) для маршрутизации туннеля, как здесь описано. Плейбук выполняет цикл по списку, чтобы выполнить cloudflared tunnel route lb {{ cf_tunnel.key }} {{ cf_lb_entry.host_name }} {{ cf_lb_entry.pool_name }}
. Если туннель уже связан с пулом, будет выдана игнорируемая ошибка.
Параметры единичного сервиса Cloudflare
Как и в предыдущих версиях этой роли, вы можете использовать [стиль конфигурации единичного сервиса][single service].
Если вам нужно перенаправить трафик только на один локальный сервис, вы можете сделать это, используя файл конфигурации. В качестве альтернативы можно настроить конфигурацию единичного сервиса.
cf_tunnels:
ssh:
hostname: xxx
url: ssh.mycompany.com
Параметр | Описание | Значение по умолчанию |
---|---|---|
hostname |
[Обязательно] Имя или уникальное значение | - |
url |
[Обязательно] URL, к которому нужно подключиться [config], например, ssh://localhost:22 или https://localhost:443 |
- |
Параметры конфигурации туннеля
Эти параметры используются для настройки параметров для каждого сервиса cloudflared. Вы все еще можете настраивать Конфигурацию на основе правил для именованных туннелей в качестве части ingress
в cf_tunnels
.
Параметр | Описание | Значение по умолчанию |
---|---|---|
autoupdate_freq |
Частота автоматического обновления - см. документацию | 24h |
edge_ip_version |
Указывает версию IP-адреса (IPv4 или IPv6), используемую для установления соединения между cloudflared и глобальной сетью Cloudflare. Доступные значения: auto , 4 и 6 |
auto |
edge_bind_address |
Указывает исходящий IP-адрес, используемый для установления соединения между cloudflared и глобальной сетью Cloudflare | - |
grace_period |
Когда cloudflared получает SIGINT/SIGTERM, он перестанет принимать новые запросы, подождет завершения текущих запросов, затем завершит работу. Ожидание завершения текущих запросов тайм-аутит после этого периода, или когда получен второй SIGTERM/SIGINT | 30s |
metrics |
Адрес для запроса статистики использования - см. документацию | localhost: |
metrics_update_freq |
Частота обновления метрик туннеля - см. документацию | 5s |
no_autoupdate |
Отключает периодическую проверку обновлений, перезапуская сервер с новой версией - см. документацию | false |
no_chunked_encoding |
Отключает кодировку по частям; полезно, если вы запускаете WSGI сервер - см. документацию | false |
no_tls_verify |
Отключает проверку TLS сертификата, представленного вашим источником. Это позволит принимать любые сертификаты от источника - см. документацию | - |
origin_server_name |
Имя хоста, который cloudflared должен ожидать от сертификата вашего сервера источника - см. документацию |
- |
origin_ca_pool |
Путь к CA для сертификата вашего источника. Этот параметр должен использоваться только в том случае, если ваш сертификат не подписан Cloudflare - см. документацию | - |
protocol |
Указывает протокол, который использовать для туннеля - см. документацию | auto |
logfile |
Включает запись файла журнала для cloudflared - он будет также записываться в журнал | true |
loglevel |
Указывает степень детализации логирования. Значение по умолчанию "info" не является шумным, но вы можете использовать "warn" в продакшене - см. документацию | info |
region |
Позволяет выбрать регионы, для которых установлены соединения. Опустите или оставьте пустым для подключения к глобальному региону. Установите --region=us , чтобы направлять все соединения через регионы 1 и 2 США |
- |
retries |
Максимальное количество повторных попыток при ошибках соединения/протокола. Попытки используют экспоненциальную задержку (повтор через 1, 2, 4, 8, 16 секунд по умолчанию), поэтому значительное увеличение этого значения не рекомендуется - см. документацию | 5 |
tag |
Пользовательские теги, используемые для идентификации этого туннеля, в формате KEY=VALUE - см. документацию |
- |
token |
Ассоциирует экземпляр cloudflared с конкретным туннелем. Токен туннеля отображается в панели управления, когда вы впервые создаете туннель. Вы также можете получить токен, используя API | - |
transport_loglevel |
Указывает степень детализации журналов для передачи между cloudflared и Cloudflare edge. Доступные уровни: trace , debug , info , warn , error , fatal , panic . Любое значение ниже warn производит значительный вывод и должно использоваться только для отладки проблем с производительностью на низком уровне и странностей протокола - см. документацию |
info |
warp_routing |
Позволяет пользователям подключаться к внутренним сервисам, используя WARP, подробнее см. [warp-routing] | false |
Зависимости
Отсутствуют.
Примеры плейбуков
Следующий пример устанавливает единичный сервис для ssh-туннеля для каждого server
:
- 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
Следующий пример устанавливает [именованный туннель] servers
с входом на {{ inventory_hostname }}.mycompany.com
для ssh и [hello world], если вы обращаетесь к hello-{{ inventory_hostname }}.mycompany.com
через браузер:
- 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
Следующий пример просто загружает cloudflared
на ваш локальный компьютер и настраивает файл конфигурации ssh:
- hosts: localhost
remote_user: papanito # ваш локальный пользователь с правами администратора
vars:
cf_install_only: true
cf_ssh_client_config: true
cf_ssh_client_config_group: servers
roles:
- papanito.cloudflared
Тест
ansible-playbook tests/test.yml -i tests/inventory
Дополнительная информация
Аутентификация демона
Согласно [authenticate-the-cloudflare-daemon], при аутентификации демона открывается оконный браузер или - если это невозможно - тогда ссылку нужно ввести вручную. В это время демон ждет. Я не смог придумать, как автоматизировать это поведение, так что я пришел к следующей реализации.
- если ничего не указано, то ansible вызывает
cloudflared login
и будет продолжать, когда аутентификация завершена - это имеет смысл, если вы используете роль для установки демона локально на своем компьютере, где есть оконный браузер. - если
cf_cert_location
, сертификат фактически будет скопирован изcf_cert_location
, или еслиcf_cert_content
определено, тогда сертификат создается непосредственно из значения, хранящегося в нем. Таким образом, вы можете войти в систему один раз в Cloudflare с вашего мастер-узла (где вы запускаете ansible) или из удаленного местоположения.
Вы можете зашифровать cert.pem
с помощью ansible vault и сохранить его где-то в безопасном месте.
Ссылки:
- [загрузки] - инструкции по загрузке cloudflared
- [ssh-гайд] - ssh-соединения с cloudflared
- [cli-args] - аргументы командной строки
- [config] - формат файла конфигурации использует синтаксис YAML
Лицензия
Это бесплатное программное обеспечение, выпущенное на условиях лицензии Apache v2.
Информация об авторе
ansible-galaxy install papanito/ansible-role-cloudflared