You need to enable JavaScript to run this app.
最新活动
大模型
产品
解决方案
定价
生态与合作
支持与服务
开发者
了解我们

Synology上部署Traefik+Let's Encrypt遇DNS错误,但证书文件显示有效

Synology上部署Traefik+Let's Encrypt遇DNS错误,但证书文件显示有效

嘿,我来帮你梳理下当前的问题,先从你的环境和遇到的状况说起:

一、当前网络环境

物理设备(静态IP)

  • 路由器:192.168.1.1
  • Windows PC:192.168.1.10
  • Synology NAS:192.168.1.11

Docker网络配置

  • macvlan静态网络(Pi-Hole、Unbound、Traefik共享):
    • DockerPihole:192.168.1.12
    • DockerUnbound:192.168.1.13
    • DockerTraefik:192.168.1.14
  • Bridge静态网络(供Traefik连接容器):
    • DockerTraefik:192.168.10.2
    • DockerNginx1:192.168.10.10
    • DockerNginx2:192.168.10.20

二、已搞定的目标

  • ✅ 能通过域名访问Docker容器(比如nginx.mydomain.com
  • ✅ 能直接用IP+端口访问容器(比如192.168.1.14:10080

三、已经解决的坑

  • 解决了Synology NAS占用80/443端口导致Traefik没法用的问题:把Traefik部署在macvlan网络里
  • 解决了容器ping不通宿主NAS的问题:在容器栈里加了端口映射(比如180:801443:443

四、当前核心问题

你现在碰到两个关联的问题:

  1. Traefik日志里出现Let's Encrypt的DNS验证错误:

level=error
msg=Unable to obtain ACME certificate for domains "nginx2.mydomain.com":
unable to generate a certificate for the domains [nginx2.mydomain.com]:
error: one or more domains had a problem:
[nginx2.mydomain.com] acme: error: 400 :: urn:ietf:params:acme:error:dns :: DNS problem: NXDOMAIN looking up A for nginx2.mydomain.com

  • check that a DNS record exists for this domain; DNS problem: NXDOMAIN looking up AAAA for nginx2.mydomain.com
  • check that a DNS record exists for this domain
    providerName=staging.acme
    routerName=nginx2@docker
    rule=Host(nginx2.mydomain.com)
    ACME CA=https://acme-staging-v02.api.letsencrypt.org/directory
  1. 访问nginx2.mydomain.com时,浏览器显示的是Traefik默认证书(TRAEFIK DEFAULT CERT),不是预期的Let's Encrypt staging证书。

另外你提到:本地pingnginx2.mydomain.com能返回Traefik的macvlan IP(192.168.1.14),而且acme.json里有状态为valid的staging证书,但浏览器还是用默认证书。

五、问题原因分析

为什么本地DNS正常,但Let's Encrypt报错NXDOMAIN?

Let's Encrypt的验证服务器是公网环境,它会查公网DNS服务器来验证你的域名记录,不是你本地Synology的DNS。你只在本地DNS加了nginx2.mydomain.com的记录,公网DNS里根本没有这个域名的A/AAAA记录,所以验证服务器找不到对应的IP,就返回NXDOMAIN错误,导致证书拿不到。

为什么acme.json里有valid的证书?

这个大概率是之前成功获取的其他域名证书,或者是Traefik尝试获取但没关联到当前路由的无效记录。你可以打开acme.json仔细看看里面的域名字段,确认是不是包含nginx2.mydomain.com

为什么浏览器显示默认证书?

因为Traefik没能成功拿到nginx2.mydomain.com的有效证书,所以自动 fallback 到内置的默认证书了。

六、解决方案建议

根据你“暂时不想把服务暴露到公网,只用VPN访问”的需求,推荐以下两种方案:

方案1:用DNS-01验证方式(首推)

HTTP-01验证需要公网能访问你的Traefik 80端口,而DNS-01验证只需要你能控制域名的DNS记录,通过添加TXT记录完成所有权验证,不需要公网能访问你的服务。

具体步骤:

  1. 确认你的域名DNS服务商在Traefik官方支持的DNS挑战提供商列表里(比如Cloudflare、阿里云、DNSPod这些常见的都支持)
  2. 在Traefik的静态配置里添加DNS挑战的certificatesResolver,配置好DNS服务商的API密钥(不同服务商的配置方式不一样,你可以查Traefik的官方文档对应服务商的参数)
  3. 在每个需要证书的容器路由配置中,指定使用这个DNS resolver(比如在Portainer的容器标签里加traefik.http.routers.nginx2.tls.certResolver=staging

这种方式能让Let's Encrypt通过查公网DNS的TXT记录来验证你对域名的所有权,就算你的服务没有公网访问权限,也能正常拿到证书。

方案2:用自签名证书(适合纯本地使用)

如果你只是在本地/VPN环境用,也可以让Traefik生成自签名证书。虽然浏览器会默认提示不安全,但你把自签名的根证书导入到设备的信任列表里,就能显示“安全”标识了。

配置示例(可以加在Traefik动态配置或者容器标签里):

tls:
  selfSigned: true

额外要检查的点

  1. 确认Traefik的容器标签里有没有正确指定tls.certResolver,比如:
    - "traefik.http.routers.nginx2.tls.certResolver=staging"
    
  2. 检查acme.json的权限,确保Traefik容器有读写权限(Synology上通常要把文件权限设为600,并且所属用户和容器一致)
  3. 确认Traefik的静态配置里有没有启用ACME,并且指定了正确的CA地址和存储路径:
    certificatesResolvers:
      staging:
        acme:
          server: https://acme-staging-v02.api.letsencrypt.org/directory
          storage: /acme.json
          # 这里配置DNS挑战
          dnsChallenge:
            provider: 你的DNS服务商名称
            resolvers:
              - "8.8.8.8:53"
    

备注:内容来源于stack exchange,提问作者LorneCash

火山引擎 最新活动