Traefik 从路由规则自动提取域名:用 ACME 为多域名路由自动签发 TLS 证书 📅 发布时间:2026/9/7 17:59:55 👁 浏览次数: Traefik 从路由规则自动提取域名用 ACME 为多域名路由自动签发 TLS 证书【免费下载链接】traefikThe Cloud Native Application Proxy项目地址: https://gitcode.com/GitHub_Trending/tr/traefik本篇技术指南聚焦 Traefik 中一个高频实战场景当一个 HTTP 路由的规则rule同时匹配多个域名时如何让 ACME 证书解析器自动从规则中解析出这些域名并一次性申请覆盖全部域名的证书而无需手动枚举tls.domains。文中给出 Docker、Docker Swarm、Kubernetes IngressRoute 以及 File 动态配置YAML/TOML五种完整可复制的配置写法并结合 Traefik 源码剖析“规则 → 域名列表 → 证书申请”的完整调用链读完后你可以独立配置多域名 ACME 自动签发并理解其底层触发机制。两种为 ACME 指定域名的方式显式声明 vs 从规则提取Traefik 的 ACME 提供程序pkg/provider/acme/在签发证书时需要知道“为谁签发”。仓库中提供了两种等价思路的配置示例文档可对照阅读显式声明在路由的tls.domains中直接列出主域名与 SAN备选名见 显式多域名示例从规则提取只写tls.certResolverTraefik 自动解析路由规则中所有Host()匹配器出现的域名即本文的主角 从规则提取域名的示例。后者的优势在于域名的唯一事实来源是路由规则本身。新增、修改域名只需改 rule 一处证书申请会自动跟随避免了rule与tls.domains两处维护、相互漂移的风险。动态配置示例一个规则覆盖两个域名下面完整继承关联文档中的官方示例。该示例的路由规则用和||组合了两个匹配条件分别涉及example.com和blog.example.org两个域名(Host(example.com) Path(/blog)) || Host(blog.example.org)Traefik 会从这条规则中提取出example.com与blog.example.org两个域名交给myresolver解析器申请证书。以下为文档中按不同 Provider 给出的五种等价写法。Docker标签方式# Dynamic configuration labels: - traefik.http.routers.blog.rule(Host(example.com) Path(/blog)) || Host(blog.example.org) - traefik.http.routers.blog.tlstrue - traefik.http.routers.blog.tls.certresolvermyresolver注意这里必须显式声明traefik.http.routers.blog.tlstrue否则路由不会启用 TLS。DockerSwarmdeploy.labels 方式# Dynamic configuration deploy: labels: - traefik.http.routers.blog.rule(Host(example.com) Path(/blog)) || Host(blog.example.org) - traefik.http.routers.blog.tlstrue - traefik.http.routers.blog.tls.certresolvermyresolver - traefik.http.services.blog-svc.loadbalancer.server.port8080Swarm 模式下标签放在deploy.labels中服务端口同样通过标签声明。KubernetesIngressRoute CRDapiVersion: traefik.io/v1alpha1 kind: IngressRoute metadata: name: blogtls spec: entryPoints: - websecure routes: - match: (Host(example.com) Path(/blog)) || Host(blog.example.org) kind: Rule services: - name: blog port: 8080 tls: certResolver: myresolverIngressRoute 中只要存在tls字段即表示该路由启用 TLS无需也没有tls: true开关这一点与 Docker 标签写法不同。File 动态配置YAML# Dynamic configuration http: routers: blog: rule: (Host(example.com) Path(/blog)) || Host(blog.example.org) tls: certResolver: myresolverFile 动态配置TOML# Dynamic configuration [http.routers] [http.routers.blog] rule (Host(example.com) Path(/blog)) || Host(blog.example.org) [http.routers.blog.tls] certResolver myresolver前置条件静态配置中的 ACME 解析器上述示例中的certResolver: myresolver指向一个必须先定义好的 ACME 证书解析器。Traefik 仓库随文档提供了完整的参数参考文件 ref-acme.toml、ref-acme.yaml 与命令行形式 ref-acme.txt核心项如下以 TOML 为例# Enable ACME (Lets Encrypt): automatic SSL. [certificatesResolvers.myresolver.acme] # Email address used for registration. # Required email testexample.com # File or key used for certificates storage. # Required storage acme.json # CA server to use. # Uncomment the line to use Lets Encrypts staging server, # leave commented to go to prod. # Optional # Default: https://acme-v02.api.letsencrypt.org/directory # caServer https://acme-staging-v02.api.letsencrypt.org/directory # The certificates duration in hours. # It defaults to 2160 (90 days) to follow Lets Encrypt certificates duration. # Optional # Default: 2160 # certificatesDuration2160 # KeyType to use. # Optional # Default: RSA4096 # Available values : EC256, EC384, RSA2048, RSA4096, RSA8192 # keyType RSA4096 # Use a TLS-ALPN-01 ACME challenge. # Optional (but recommended) [certificatesResolvers.myresolver.acme.tlsChallenge]结合参数注释使用上有几个值得注意的默认值与约束email与storage为必填项storage指向的acme.json保存私钥与注册信息需妥善备份且权限收紧caServer默认指向 Lets Encrypt 正式环境联调阶段建议切换为 staging 目录避免触发正式环境的速率限制挑战方式三选一tlsChallengeTLS-ALPN-01注释中标注“Optional (but recommended)”、httpChallengeHTTP-01必须指定entryPoint、dnsChallengeDNS-01ref-acme.toml中明确注释了关键限制DNS-01 挑战是通配符证书生成的必要条件mandatory for wildcard certificate generation。因此如果你的规则里出现*.example.com从规则提取出的通配符域名只能靠 DNS-01 签发仅配置 TLS-ALPN-01 或 HTTP-01 是不够的。源码解析从规则到证书申请的完整调用链从源码结构看“从规则提取域名”的能力由 ACME 提供程序与 HTTP 规则解析器协作完成关键路径如下。第一步持续监听路由配置变化。provider.go 中的watchNewDomains方法持续监听动态配置。对 HTTP 路由约 L558-L592判断逻辑是只处理route.TLS非空且CertResolver与当前解析器同名的路由如果显式配置了route.TLS.Domains则以显式声明为准先经deleteUnnecessaryDomains过滤否则调用httpmuxer.ParseDomains(route.Rule)从规则字符串中解析域名再交给resolveDomains处理。第二步从规则文本中提取所有 Host 匹配器。ParseDomains定义于 mux.go它复用 Traefik 通用规则解析器rules.NewParser把整条规则编译成解析树然后只保留Host匹配器对应的域名列表parse, err : parser.Parse(rule) ... buildTree, ok : parse.(rules.TreeBuilder) ... return buildTree().ParseMatchers([]string{Host}), nil对本篇示例该函数将返回[example.com, blog.example.org]——无论 Host 条件出现在还是||的哪一侧、被括号如何嵌套都会被完整提取。TCP/UDP 路由则走对称路径调用tcpmuxer.ParseHostSNI(route.Rule)提取HostSNI匹配器同见watchNewDomains中对 TCP 路由的处理。第三步组装“主域名 SAN”并异步申请证书。resolveDomainsprovider.go将解析结果组装为单个证书请求第一个域名作为Main其余全部作为SANsif len(domains) 0 { domain types.Domain{Main: domains[0]} if len(domains) 1 { domain.SANs domains[1:] } ... dom, cert, err : p.resolveCertificate(ctx, domain, tlsStore)即本例中example.com为主域名blog.example.org进入 SAN 列表最终得到一张同时覆盖两个域名的证书然后通过addCertificateForDomain写入默认的 TLS Store。整个申请过程包在safe.Go中异步执行不阻塞配置监听主流程解析器内部还维护resolvingDomains去重集合避免对同一域名并发重复申请。第四步证书落库与续期。申请的证书与账户状态统一由storage指定的文件保存见 local_store.go 等本地存储实现Traefik 在运行期间定期检查到期时间并自动续期这也是certificatesDuration默认 2160 小时90 天的意义所在。与集成测试的对照验证Traefik 的集成测试为 ACME 场景提供了可直接参考的端到端验证样本测试套件 acme_test.go 中的TestHTTP01StoreDomains等用例使用 acme_domains.toml 作为动态配置夹具该夹具展示了“显式声明”一侧的完整形态静态段通过 Go template 生成certificatesResolvers含 email、storage、keyType、caServer 及 http/tls 挑战段动态段则通过[[http.routers.test.tls.domains]]逐条注入main与sans与本文“从规则提取”的写法互为镜像夹具同时启用了webHTTP-01 验证用与websecure两个入口这正是 HTTP-01 挑战方式下入口点配置的参考形态。若要在自己环境中验证“从规则提取”是否生效最快的做法是参照 acme_base.toml 等基础夹具把caServer指向 staging 环境后观察 Traefik 日志中 “Trying to challenge certificate for domain ... found in HostSNI rule” 一类的调试输出该日志文案正出自 provider.go 的resolveDomains。实践要点小结单一事实来源多域名路由优先依赖规则提取减少tls.domains与rule的双向维护成本两者共存时以tls.domains显式声明为准源码中先判断len(route.TLS.Domains) 0分支Provider 差异Docker 标签需显式tlstrueIngressRoute 有tls字段即启用File 配置中tls.certResolver本身即开启 TLS通配符域名规则中出现*.domain时必须配置dnsChallenge可配delayBeforeCheck、resolvers等参数详见 ref-acme.toml 注释速率限制防护联调阶段用 stagingcaServer并保证storage文件持久化防止重启后重复申请触发 Lets Encrypt 限流。【免费下载链接】traefikThe Cloud Native Application Proxy项目地址: https://gitcode.com/GitHub_Trending/tr/traefik创作声明:本文部分内容由AI辅助生成(AIGC),仅供参考