登录

📑 我做了一套云服务器间的 TLS 证书同步方案

53027
  • 楼主博主 编辑于

    用了一下午时间做,之前的证书同步方案还行,但是后来 cloudflare dcv 记录占据了 _acme-challenge 位置,导致签发失败,Google Trust Service 支持 _validation-persist 虽然 lego 客户端已经支持了这个验证方式,但是 nixos 自带的 acme 模块并不支持直接配置这个选项并且考虑到以后可能加更多证书 / 域名,还是图形化管理更好用,所以把主签发机 us.or.dls.2 上的签发器从 acme 模块换成了 certwarden 这个 docker 里的 webui 证书管理器

    换完后发现直接把证书同步模块叫作 acme 不合适,于是又对证书同步模块大改了下,换了单元名字和证书存放路径,并且把它从机器配置里抽出来,成为了独立模块,还加了证书更新时 reload 相关单元的功能

    然后又发现 cert-sync 每天拉一次遇到紧急情况需要立刻同步证书时需要逐个 ssh 上去重启单元,非常麻烦所以又给 us.or.dls.2 部署了 ntfy 服务器,在上传后 certwarden 会向 ntfy 服务器发送消息,其他机器则用 cert-notify 单元和 ntfy 服务器保持 wss 长连接,在收到更新消息 cert-notify 会自动拉起 cert-sync 从存储桶拉取证书

    后续会详细写篇博客说是如何实现的(先让我咕咕咕一会)

    具体流程如下

    ---
    config:
      theme: redux-color
      themeVariables:
        edgeLabelBackground: "#ffffff"
    ---
    
    flowchart BT
        %% 公网下游 · 6 台 VPS
        subgraph EU["eu.de.0"]
            direction TB
            EU_N["cert-notify"]
            EU_S["cert-sync<br/>cert-sync.timer"]
        end
    
        subgraph HK2["hk.2"]
            direction TB
            HK2_N["cert-notify"]
            HK2_S["cert-sync<br/>cert-sync.timer"]
        end
    
        subgraph HK3["hk.3.cnix"]
            direction TB
            HK3_N["cert-notify"]
            HK3_S["cert-sync<br/>cert-sync.timer"]
        end
    
        subgraph SG["sg.0"]
            direction TB
            SG_N["cert-notify"]
            SG_S["cert-sync<br/>cert-sync.timer"]
        end
    
        subgraph PHX["us.az.phx.0"]
            direction TB
            PHX_N["cert-notify"]
            PHX_S["cert-sync<br/>cert-sync.timer"]
        end
    
        subgraph LAX["us.ca.lax.0"]
            direction TB
            LAX_N["cert-notify"]
            LAX_S["cert-sync<br/>cert-sync.timer"]
        end
    
        %% 证书与通知汇聚节点
        NB(("更新消息推送"))
        DB(("证书下载"))
    
        subgraph CF["Cloudflare Global Network"]
            direction LR
            EDGE["https://ntfy.nahida.im"]
            R2[("Cloudflare R2<br/>r2:tls")]
        end
    
        subgraph GCP["GCP 集群 · 同一 VPC"]
            direction LR
            subgraph G0["us.or.dls.0"]
                direction TB
                T0["cloudflared"]
                N0["cert-notify"]
                S0["cert-sync<br/>cert-sync.timer"]
            end
            subgraph G1["us.or.dls.1"]
                direction TB
                T1["cloudflared"]
                N1["cert-notify"]
                S1["cert-sync<br/>cert-sync.timer"]
            end
            subgraph G2["us.or.dls.2 · 签发主节点"]
                direction TB
                CW["Cert Warden<br/><br/>Google Trust Service + DNS-PERSIST-01"]
                NTFY["ntfy-sh Server<br/>10.138.0.5:8000"]
                T2["cloudflared"]
            end
        end
    
        %% 紫色:systemd trigger (0-7)
        EU_N -->|"trigger"| EU_S
        HK2_N -->|"trigger"| HK2_S
        HK3_N -->|"trigger"| HK3_S
        SG_N -->|"trigger"| SG_S
        PHX_N -->|"trigger"| PHX_S
        LAX_N -->|"trigger"| LAX_S
        N0 -->|"trigger"| S0
        N1 -->|"trigger"| S1
    
        %% 绿色:ntfy publish (8)
        CW -->|"R2 上传完成后 publish: sync"| NTFY
    
        %% 绿色:ntfy Tunnel / Origin (9-14)
        NTFY ---|"VPC Origin"| T0
        NTFY ---|"VPC Origin"| T1
        NTFY ---|"本机 Origin"| T2
        T0 ---|"Tunnel · 路径 0"| EDGE
        T1 ---|"Tunnel · 路径 1"| EDGE
        T2 ---|"Tunnel · 路径 2"| EDGE
    
        %% 绿色:ntfy JSON Streaming (15-23)
        NTFY -.->|"HTTP · VPC"| N0
        NTFY -.->|"HTTP · VPC"| N1
        EDGE -.- NB
        NB -.-> EU_N
        NB -.-> HK2_N
        NB -.-> HK3_N
        NB -.-> SG_N
        NB -.-> PHX_N
        NB -.-> LAX_N
    
        %% 蓝色:R2 证书上传、下载 (24-33)
        CW ==>|"上传 PEM"| R2
        R2 === DB
        DB ==> EU_S
        DB ==> HK2_S
        DB ==> HK3_S
        DB ==> SG_S
        DB ==> PHX_S
        DB ==> LAX_S
        DB ==> S0
        DB ==> S1
    
        %% 连线颜色与线宽
        linkStyle 0,1,2,3,4,5,6,7 stroke:#9333ea,color:#9333ea,stroke-width:1.2px;
        linkStyle 8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23 stroke:#059669,color:#059669,stroke-width:1.3px;
        linkStyle 24,25,26,27,28,29,30,31,32,33 stroke:#2563eb,color:#2563eb,stroke-width:1.6px;
    
        %% 应用节点配色
        classDef issuer fill:#dbeafe,stroke:#2563eb,color:#1e40af;
        classDef cloudflare fill:#ffedd5,stroke:#ea580c,color:#9a3412;
        classDef notify fill:#dcfce7,stroke:#16a34a,color:#166534;
    
        class CW issuer
        class EDGE,R2,T0,T1,T2 cloudflare
        class NTFY,EU_N,HK2_N,HK3_N,SG_N,PHX_N,LAX_N,N0,N1 notify
    
        %% 汇聚节点:白色背景、彩色边框与文字
        classDef notifyBus fill:#ffffff,stroke:#16a34a,color:#16a34a;
        classDef dataBus fill:#ffffff,stroke:#2563eb,color:#2563eb;
    
        class NB notifyBus
        class DB dataBus
    
        %% Sky Blue:所有机器的独立容器
        classDef machine fill:#f0f9ff,stroke:#38bdf8,color:#0369a1,stroke-width:1px;
        class EU,HK2,HK3,SG,PHX,LAX,G0,G1,G2 machine
    
        %% Cloudflare:橙色
        style CF fill:#fff7ed,stroke:#f97316,color:#9a3412,stroke-width:1.5px
    
        %% GCP 集群:黄色
        style GCP fill:#fefce8,stroke:#eab308,color:#854d0e,stroke-width:1.5px
    
    收藏 1支持反对打赏
    个性签名

    我的网站:nahida.im | 相关服务监控:status.nahida.im

27 条回复

发表回复