papanito.cloudflared

Ansible 角色 "papanito.cloudflared"

Ansible 角色 Ansible 质量评分 Ansible 角色 GitHub 问题 GitHub 拉取请求

此 Ansible 角色在主机上下载并安装 cloudflared,并可选择将 argo-tunnel 安装为服务。

3.0.0 版本有重大变化

这是一个重大变化,以反映 新行为命名隧道

如果您在 v3.0.0 之前使用过该角色,该角色会处理清理工作。但 您必须更新您的 ansible 项目中的配置(变量)。我将变量重命名了 - 通常以 cf_ 前缀开头,以使其唯一。如果它们不是唯一的,可能会导致不同角色中的同名变量产生不良副作用。

Cloudflared 和连接应用程序到隧道

根据1,要创建和管理隧道,您首先需要:

  1. 在您的机器上 下载并安装 cloudflared
  2. 认证 cloudflared

安装并认证 cloudflared 后,启动您第一个隧道的流程包含三个高层步骤:

  1. 创建隧道
  2. 将流量路由到您的隧道
  3. 运行您的隧道

步骤 4-5 每个隧道执行一次,通常由管理员执行,而步骤 6 则在每次需要启动隧道时执行,通常由隧道的拥有者(可能与管理员不同)执行。

该角色做什么?

该角色实际上有两个目的

服务器端守护程序安装

该角色仅负责 在节点上设置服务,即执行上述的第 1、2、4 和 5 步,因为

创建隧道并启用路由是管理员的任务,而不是该角色 1

您可以配置一个或多个 命名隧道 以及 单一服务 - 尽管对于 命名隧道,通常只需要一个守护程序。该角色实际上执行以下步骤:

  1. 根据[下载]]下载并安装二进制文件

  2. 安装/配置守护程序 - 请参见 认证守护程序

  3. 对于 命名隧道,在 {{ cf_credentials_dir }}/{{ tunnel_id }}.json 下创建一个 凭证文件,类似于:

    {"AccountTag":"{{ account_tag }}","TunnelSecret":"{{ tunnel_secret }}","TunnelID":"{{ tunnel_id }}","TunnelName":"{{ cf_tunnels.key }}"}
    
  4. 对于 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 }}
    

    其他参数使用 隧道配置参数 进行配置。

  5. 根据您的初始化系统 - 由 cf_init_system 控制,角色执行如下操作:

    • Systemd

      创建一个 systemd 单元模板 cloudflared@{{ tunnel }}.service 并为 cf_tunnels 列表中的每个服务启动一个实例。

      cloudflared tunnel --config {{ tunnel }}.yml
      
    • Init-V 系统

      1. 安装 cloudflared 服务/etc/init.d/{{ systemd_filename }}-{{ tunnel_name }}
      2. 将停止脚本链接到 /etc/init.d/{{ systemd_filename }}-{{ tunnel_name }}
      3. 将启动脚本链接到 /etc/init.d/{{ systemd_filename }}-{{ tunnel_name }}
  6. 如果您使用 命名隧道,该角色还会创建 dns 路由

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,您将为 host001host002 获取一个条目。

需求

角色变量

安装和卸载参数

以下参数控制安装和/或卸载

参数 描述 默认值
cf_download_baseurl cloudflare 二进制文件的基础 URL https://github.com/cloudflare/cloudflared/releases/latest/download/
cf_install_only 如果您只想安装二进制文件而不进行任何配置或登录,请设置为 true false
cf_ssh_client_config 如果您想为 [ssh 指南客户端] 配置代理配置,请设置为 true,请参见 SSH 客户端配置 false
cf_ssh_client_config_group 要为其创建 ssh 代理配置的清单组的名称,请参见 SSH 客户端配置 ``
cf_force_install 如果您想重新安装 cloudflared,请设置为 true。默认假设 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,apt 存储库的 GPG 密钥的 URL https://pkg.cloudflare.com/pubkey.gpg
cf_repository_key_install_path 如果 cf_os_package_enable 为 true,apt 存储库的 GPG 密钥安装路径 /usr/share/keyrings/cloudflare-main.gpg
cf_repository 如果 cf_os_package_enable 为 true,Cloudflare apt 存储库的 URL 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 定义使用的初始化服务。可能的值为 systemdinitv systemd
cf_systemd_user 如果 cf_init_system: systemd,则为 systemd 服务指定的用户 root
cf_systemd_group 如果 cf_init_system: systemd,则为 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 [必填] 隧道的 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 [配置],例如 ssh://localhost:22https://localhost:443 -

隧道配置参数

这些用于配置每个 cloudflared 服务的参数。您仍然可以在 cf_tunnels 下的 ingress 部分配置 命名隧道的每个规则配置

参数 描述 默认值
autoupdate_freq 自动更新频率 - 请参见 文档 24h
edge_ip_version 指定用于在 cloudflared 和 Cloudflare 全球网络之间建立连接的 IP 地址版本(IPv4 或 IPv6)。可用值为 auto46 auto
edge_bind_address 指定用于在 cloudflared 和 Cloudflare 全球网络之间建立连接的出站 IP 地址 -
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 禁用对您的源的证书的 TL S 验证。将允许接收源的任何证书 - 请参见 文档 -
origin_server_name cloudflared 应该从源服务器证书中预期的主机名 - 请参见 文档 -
origin_ca_pool 源证书的 CA 路径。此选项仅在您的证书未由 Cloudflare 签名时使用 - 请参见 文档 -
protocol Specifies the protocol to use for the tunnel - see docu auto
logfile 启用为 cloudflared 写入日志文件 - 它仍将记录到日志中心 true
loglevel 指定日志的详细程度。默认的 "info" 不是噪音,但您可能希望在生产中使用 "warn" info
region 允许您选择建立连接的区域。省略或留空以连接到全球区域。设置 --region=us 将所有连接路由通过 us 区域 1 和 us 区域 2 -
retries 连接/协议错误的最大重试次数。重试使用指数回退(默认情况下,在 1、2、4、8、16 秒时重试),因此不建议显著增加此值 5
tag 用于标识此隧道的自定义标签,格式为 KEY=VALUE -
token 将 cloudflared 实例与特定隧道关联。隧道的令牌在您首次 创建隧道 时会显示在仪表板中。您还可以使用 API 检索令牌 -
transport_loglevel 指定 cloudflared 与 Cloudflare 边缘之间传输的日志详细程度。可用级别为:tracedebuginfowarnerrorfatalpanic。任何低于警告的值都会产生大量输出,仅应用于调试低级性能问题和协议问题 - 请参见 docu info
warp_routing 允许用户使用 WARP 连接到内部服务,详细信息请见 warp-routing false

依赖关系

示例剧本

以下示例为每个 server 安装单一服务的 ssh 隧道:

- 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

以下示例安装了具有 {{ inventory_hostname }}.mycompany.com ingress 的 命名隧道 servers,如果您通过浏览器访问 hello-{{ inventory_hostname }}.mycompany.com,则为 ssh 和 hello world

- 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-config 文件:

- 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

其他信息

认证守护程序

根据 认证云彩守护程序,在认证守护程序时,打开一个浏览器窗口;如果这不可能,则需要手动输入链接。在此期间,守护程序等待。我无法想出如何自动化此行为,因此我想出了以下实现。

  • 如果没有指定,则 ansible 调用 cloudflared login 并在认证完成后继续 - 如果您使用该角色在本地计算机上安装守护程序,并且您有浏览器窗口,这很有意义。
  • 如果 cf_cert_location 中的证书会从 cf_cert_location 复制,或者如果定义了 cf_cert_content,则证书将直接从存储中的值创建。因此,您可以从主节点(您运行 ansible 的地方)或远程位置登陆 cloudflare 一次。

您可以使用 ansible vault 加密 cert.pem 并将其存放在安全地方。

参考:

许可

这是自由软件,依据 Apache v2 许可条款发布。

作者信息

Papanito 编写 - Gitlab / Github

关于项目

Ansible role do install and run cloudflare argo tunnel

安装
ansible-galaxy install papanito.cloudflared
许可证
apache-2.0
下载
2.3k
拥有者
A passionate DevOps Engineer from Switzerland, father of five and husband of the most beautiful and most amazing woman in the world.