mailcow-dockerized 如何开启 ACME DNS-01 挑战方式签发 Let‘s Encrypt 证书(ACME_DNS_CHALLENGE)
mailcow-dockerized 如何开启 ACME DNS-01 挑战方式签发 Lets Encrypt 证书ACME_DNS_CHALLENGE【免费下载链接】mailcow-dockerizedmailcow: dockerized - 项目地址: https://gitcode.com/GitHub_Trending/ma/mailcow-dockerizedmailcow 的acme-mailcow容器镜像ghcr.io/mailcow/acme:1.98负责为邮件域名签发和续期 Lets Encrypt 证书。默认走 HTTP-01 流程check_domain 会先校验域名的 A/AAAA 记录与服务器公网 IP 是否匹配再通过 Nginx 验证/.well-known/acme-challenge/的 HTTP 可达性。如果服务器位于 NAT/反向代理之后、80/443 端口不对外或者需要为通配符 SAN 签发证书可以改用 DNS-01 挑战通过修改 DNS 记录完成验证跳过 IP 与 HTTP 校验。本文基于仓库内的配置模板 generate_config.sh、docker-compose.yml 与 acme-mailcow 容器脚本说明如何开启ACME_DNS_CHALLENGE、配置 DNS 提供商密钥以及如何通过日志和证书文件确认签发成功。DNS-01 开启后行为变化先明确开启后代码路径的变化便于理解每一步配置的作用acme.sh 入口脚本会把ACME_DNS_CHALLENGE归一化y/yes均视为启用并在/etc/acme/dns-01.conf不存在时自动创建一个带注释的模板文件。check_domain 中当ACME_DNS_CHALLENGEy时直接跳过 IP 匹配和 HTTP 挑战路径校验日志输出ACME_DNS_CHALLENGEy - skipping IP and HTTP validation for domain。obtain-certificate.sh 检测到ACME_DNS_CHALLENGEy后直接exec /srv/obtain-certificate-dns.sh不再走 HTTP-01 流程。obtain-certificate-dns.sh 会先加载 DNS 提供商密钥校验ACME_DNS_PROVIDER非空然后调用镜像内置的 acme.sh--issue --dns provider为每个域名签发。步骤一在 mailcow.conf 中开启 DNS-01mailcow.conf中的三个相关选项及其默认值来自配置模板generate_config.sh 第 293-309 行new_options.sh 升级时也会向旧配置追加这三项# Enable DNS-01 challenge for ACME (acme-mailcow) - y/n # This requires you to set ACME_DNS_PROVIDER and ACME_ACCOUNT_EMAIL below ACME_DNS_CHALLENGEy # DNS provider for DNS-01 challenge (e.g. dns_cf, dns_azure, dns_gd, etc.) # See the dns-01 provider documentation for more information. ACME_DNS_PROVIDERdns_cf # Account email for ACME DNS-01 challenge registration ACME_ACCOUNT_EMAILmeexample.com替换要求ACME_DNS_PROVIDER必须从占位值dns_xxx改为你实际使用的 acme.sh dnsapi 提供商名配置模板注释中给出的示例为dns_cf、dns_azure、dns_gd等。若最终为空obtain-certificate-dns.sh 会以ACME_DNS_PROVIDER is required when ACME_DNS_CHALLENGE is enabled报错退出。ACME_ACCOUNT_EMAIL默认是占位邮箱meexample.com需替换为真实注册邮箱首次注册 acme.sh 账户时若该值为空脚本会记录ACME_ACCOUNT_EMAIL is required to register a new acme.sh account并中止。这三个变量由 docker-compose.yml 的acme-mailcow服务透传ACME_DNS_CHALLENGE${ACME_DNS_CHALLENGE:-n}等无需改 compose 文件本身。步骤二写入 DNS 提供商密钥dns-01.confgenerate_config.sh 的注释明确说明「You will need to pass provider-specific environment variables to the acme-mailcow container」并给出了 Azure DNS 的示例键名#AZUREDNS_SUBSCRIPTIONIDxxxxxxxx-xxxx-xxxx-xxxx-xxxxxxxxxxxx #AZUREDNS_TENANTIDxxxxxxxx-xxxx-xxxx-xxxx-xxxxxxxxxxxx #AZUREDNS_APPIDxxxxxxxx-xxxx-xxxx-xxxx-xxxxxxxxxxxx #AZUREDNS_CLIENTSECRETxxxxxxxx-xxxx-xxxx-xxxx-xxxxxxxxxxxx #AZUREDNS_RESOURCEGROUPyour-resource-group #AZUREDNS_ZONEyour-zone-name以上xxxxxxxx等均为文档示例值需替换为你的实际凭据。键名清单以模板注释中指向的 acme.sh 官方 dnsapi 文档为准模板注释原文要求查阅该文档。放置位置宿主机上的data/conf/acme/目录被 docker-compose.yml 挂载为容器内/etc/acme/。首次启动时 acme.sh 入口会自动创建/etc/acme/dns-01.conf模板内容为# Add here your DNS-01 challenge configuration等注释因此文件会出现在宿主机的data/conf/acme/dns-01.conf直接编辑它即可。load-dns-config.sh 的解析规则每行一个keyvalue支持#注释行和空行值两侧的双引号或单引号会被去除缺少或键为空的行会被跳过并记录Skipping invalid DNS config line N ...每个有效键都会被export进容器环境变量acme.sh 按提供商名读取对应变量。步骤三重启应用配置在 mailcow-dockerized 根目录执行source mailcow.conf后再跑 compose 是仓库内既有的调用方式见 data/web/_status.502.htmlsource mailcow.conf docker compose up -d副作用说明docker compose up -d只重建配置发生变化的容器本场景下变化的是acme-mailcow的环境变量其他服务不受影响。该命令不会删除数据卷。重启后 acme-mailcow 会依次等待 Redis、Docker API、Postfix、Dovecot、数据库、Nginx 和 unbound 解析器就绪acme.sh 中逐一 ping/检查然后进入签发循环。步骤四验证签发结果日志验证docker compose logs acme-mailcow中按顺序出现以下日志行即表示各阶段通过均为脚本中的固定日志文案Loading DNS-01 configuration from /etc/acme/dns-01.conf和逐行的Exported DNS config key KEY—— 密钥文件被正确解析ACME_DNS_CHALLENGE is enabled, DNS provider secrets loaded—— 密钥已加载进签发流程ACME_DNS_CHALLENGEy - skipping IP and HTTP validation for domain—— 确认已切换为 DNS-01 验证Using Lets Encrypt production servers或 staging见下文Certificate successfully obtained via DNS challenge—— 签发完成。文件验证容器内/var/lib/acme/挂载自宿主机data/assets/ssl/成功后每个域名下生成cert.pem、key.pem与domains文件。obtain-certificate-dns.sh 以openssl x509 -checkend 2592000剩余有效期不足 30 天作为续期判断可用同样命令抽查宿主机上的证书openssl x509 -checkend 2592000 -noout -in data/assets/ssl/你的域名/cert.pem脚本头注释也给出了返回码语义0 新建成功1 续期成功2 无需续期其他 错误。失败排查与限制失败时的现象与重试签发失败会记录Failed to obtain certificate cert for domains domains via DNS challenge完整 acme.sh 响应以 base64 形式写入 Redis日志中带b64标记同时向 Redis 写入ACME_FAIL_TIME。主循环在出错后 30 分钟自动重试全部成功则休眠一天后再检查。若日志出现Cannot validate any hostnames, skipping Lets Encrypt for 1 hour说明没有任何域名通过校验需回到步骤一/二检查配置。常见报错对照均为脚本内固定文案日志原因ACME_DNS_PROVIDER is required when ACME_DNS_CHALLENGE is enabledACME_DNS_PROVIDER为空ACME_ACCOUNT_EMAIL is required to register a new acme.sh account首次注册账户时邮箱为空Skipping invalid DNS config line N (missing keyvalue)dns-01.conf 该行格式非法该行密钥未生效Certificate was requested, but key and certificate hashes do not match证书与私钥不匹配本次结果被丢弃限制当前仅支持 RSA 证书两个 obtain 脚本均注明 only support rsa certificates for now。可用提供商取决于镜像内置 acme.sh 的 dnsapi 实现镜像构建时从 acme.sh 官方仓库克隆见 Dockerfile。通配符 SANADDITIONAL_SAN中的*.example.com只有在开启 DNS-01 时才会被视为已覆盖——functions.sh 的is_covered_by_wildcard注释说明通配符无法用 HTTP-01 验证这正是选择 DNS-01 的一个直接理由。测试可选分支在mailcow.conf中设置LE_STAGINGy后使用 Lets Encrypt staging 服务器日志为Using Lets Encrypt staging serversLE_STAGINGy时若同时设置了DIRECTORY_URL脚本会忽略后者。【免费下载链接】mailcow-dockerizedmailcow: dockerized - 项目地址: https://gitcode.com/GitHub_Trending/ma/mailcow-dockerized创作声明:本文部分内容由AI辅助生成(AIGC),仅供参考