IT博客汇
  • 首页
  • 精华
  • 技术
  • 设计
  • 资讯
  • 扯淡
  • 权利声明
  • 登录 注册

    内网环境或NAT环境下Caddy基于DNSPOD签发证书

    ysicing (i@ysicing.me)发表于 2024-06-05 13:19:56
    love 0

    纯个人喜好,Docker环境下比较喜欢Caddy,k8s环境下比较喜欢Traefik

    前提条件

    • 域名托管在DNSPOD(腾讯云DNS)
    • 内网环境或者NAT环境(即没有办法使用HTTP-01方式签发证书)

    通常来说(不负责任), 内网环境没必要使用证书。

    本文演示环境为鸡仔云NAT,端口映射方式暴露Caddy HTTP(S)端口,使用非标准协议端口,故而只能使用DNS-01方式

    简单科普

    HTTP-01

    适合简单、快速的验证,通常访问http://yourdomain.com/.well-known/.... 这个目录下的文件并验证其内容是否正确,然后签发证书,依赖80端口可被公网访问

    DNS-01

    添加TXT记录来验证域名

    其他

    如果域名托管在CF,还可以选择CF的15年证书

    腾讯云DNS配置

    创建普通用户

    通常情况下,选择新建一个普通用户,只给编程访问权限, 其他默认即可

    腾讯云访问管理

    创建自定义策略

    出于某些考虑,限制我这个API使用,只允许白名单IP(合法IP,示例可以理解为马赛克)可访问,不需要去掉即可

    {
        "statement": [
            {
                "action": [
                    "dnspod:DescribeDomainDigResult",
                    "dnspod:DescribeDomainExistRecordList",
                    "dnspod:DescribeRecord",
                    "dnspod:DescribeRecordImpactInfo",
                    "dnspod:CreateRecord",
                    "dnspod:DeleteRecord"
                ],
                "condition": {
                    "ip_equal": {
                        "qcs:ip": [
                            "2409:...",
                            "183..."
                        ]
                    }
                },
                "effect": "allow",
                "resource": [
                    "qcs::dnspod::uin/账号ID:domain/DomainID"
                ]
            }
        ],
        "version": "2.0"
    }
    
    • 账号ID: 点击右上角主账号就可以看到了, 也可以通过账号中心/账号信息
    • DomainID: 云解析-域名设置中可看

    关联策略

    用户列表-关联策略,效果如下

    完成之后,获取API密钥备用

    构建Caddy镜像

    目前情况下Caddy是不支持DNSPOD方式签发证书的。这里我提供一下我构建好的镜像

    • ccr.ccs.tencentyun.com/k7scn/caddy:2024

    我还是推荐自行构建好,因为我会经常调整我的镜像,增删插件。

    构建Dockerfile如下

    FROM ccr.ccs.tencentyun.com/k7scn/god AS builder
    
    RUN go install github.com/caddyserver/xcaddy/cmd/xcaddy@latest
    
    WORKDIR /go/src/
    
    RUN xcaddy build \
                --with github.com/caddy-dns/cloudflare \
                --with github.com/caddy-dns/tencentcloud \
                --with github.com/caddy-dns/alidns \
                --with github.com/caddy-dns/dnspod
    
    RUN /go/src/caddy list-modules
    
    FROM ccr.ccs.tencentyun.com/k7scn/debian
    
    COPY --from=builder /go/src/caddy /usr/bin/caddy
    
    RUN chmod +x /usr/bin/caddy && \
      mkdir -p \
      /config/caddy \
      /etc/caddy \
      /data/caddy \
      /var/log/caddy
    
    ENV XDG_CONFIG_HOME /config
    
    ENV XDG_DATA_HOME /data
    
    EXPOSE 80
    EXPOSE 443
    EXPOSE 443/udp
    
    VOLUME /config
    
    VOLUME /data
    
    VOLUME /var/log/caddy
    
    CMD caddy run --config /etc/caddy/Caddyfile --adapter caddyfile
    

    结构还是比较清晰的

    部署Caddy

    使用compose方式部署镜像

    services:
    
      caddy:
        image: ccr.ccs.tencentyun.com/k7scn/caddy:2024
        container_name: caddy
        volumes:
          - /etc/caddy:/etc/caddy
          - /var/log/caddy:/var/log/caddy
          - /data/caddy/data:/data
          - /data/caddy/config:/config
        ports:
          - "38080:38080"
          - "38443:38443"
        restart: always
        network_mode: "host"
    

    给大家看下/etc/caddy目录结构

    .
    ├── Caddyfile # 全局配置
    ├── site # 域名配置
    │   ├── default.caddy
    │   ├── tea.caddy
    │   └── tts.caddy
    └── ssl # CF15证书、自签证书或其他证书
        └── ysicing.eu.org
            ├── ysicing.key
            └── ysicing.pem
    

    全局配置Caddyfile

    主要定义了3个全局模块,方式域名里单独引用

    (LOG) {
    	log {
    		output file "{args[0]}" {
    			roll_size 50M
    			roll_uncompressed
    			roll_local_time
    			roll_keep 3
    			roll_keep_for 7d
    		}
    		format json
    	}
    }
    
    (TLS) {
    	tls {
    		load /etc/caddy/ssl
    	}
    }
    
    (CFIP) {
    	@ip_whitelist {
    		not remote_ip 2400:cb00::/32 2606:4700::/32 2803:f800::/32 2405:b500::/32 2405:8100::/32 2a06:98c0::/29 2c0f:f248::/32 fd7a:115c:a1e0::/96 173.245.48.0/20 103.21.244.0/22 103.22.200.0/22 103.31.4.0/22 141.101.64.0/18 108.162.192.0/18 190.93.240.0/20 188.114.96.0/20 197.234.240.0/22 198.41.128.0/17 162.158.0.0/15 104.16.0.0/13 104.24.0.0/14 172.64.0.0/13 131.0.72.0/22
    	}
    	route @ip_whitelist {
    		respond 451
    	}
    }
    
    {
    	debug
    	admin off
    	http_port 38080
    	https_port 38443
    	email 邮箱(建议写上)
    	acme_dns tencentcloud {
    		secret_id "腾讯云AK"
    		secret_key "腾讯云Key"
    	}
    }
    
    import /etc/caddy/site/*.caddy
    

    独立站点示例

    这里以/etc/caddy/site/default.caddy简单说下,主要是对接CF的,设置了日志和IP访问策略

    :38080 {
    	import CFIP
    	import LOG "/var/log/caddy/default-http.log"
    	respond "http, cf: {remote_host}, ip: {http.request.header.CF-Connecting-IP}"
    }
    
    :38443 {
    	import CFIP
    	import LOG "/var/log/caddy/default-https.log"
    	import TLS
    	respond "tls, cf: {remote_host}, ip: {http.request.header.CF-Connecting-IP}"
    }
    

    验证我的想法可以访问ysicing.eu.org

    其他站点按照Caddy的规则写就可以了,随便编个大概示例如下

    nat.ysicing.net {
        import CFIP
        import LOG "/var/log/caddy/nat-ysicing-net.log"
        import TLS
        reverse_proxy http://127.0.0.1:3333
    }
    

    其他问题

    由于使用非标准端口,默认配置是没办法实现http自动跳转https。



沪ICP备19023445号-2号
友情链接