文章摘要
文章讨论了为内部服务配置TLS证书的最佳实践,对比了使用ICANN限制的私有顶级域名(如.internal)和自有的公共域名两种方案,指出私有域名需要自签名证书,而公共域名可借助权威CA签发证书,更推荐后者。
文章总结
好的,这是根据您的要求,对原文进行的中文重述,保留了核心细节,并删减了与主题无关的评论性内容。
标题:为内部服务正确配置TLS证书
本文介绍了一种为内部HTTP服务配置TLS证书的可靠方法。核心思路是结合“分裂域DNS”和“Web应用防火墙(WAF)”来解决问题。
问题背景:
假设有一台服务器运行着多个HTTP服务,其中一些是外部服务,另一些是内部服务(需通过VPN访问)。为内部服务(如Grafana)配置TLS时,通常有两种选择:
1. 使用ICANN保留的私有顶级域名(如.internal)。
2. 使用自己拥有的公共顶级域名(如tuxnet.dev)。
方案一(使用.internal)的弊端:
如果使用grafana.tuxnet.internal这样的域名,由于它不是公共域名,无法从公共CA(如Let's Encrypt)获取证书,只能使用自签名证书。这会导致每个需要访问该服务的客户端都必须手动配置信任该证书,否则会不断遇到TLS错误,操作繁琐且不优雅。
“正确的方式”:分裂域DNS + WAF
采用“分裂域DNS”配置:对于公共DNS解析器,grafana.tuxnet.dev解析到公网IP;对于VPN内的客户端,该域名解析到内部IP(如10.0.1.10)。
这样做的好处是,因为域名是公共的,我们可以使用Let's Encrypt等公共CA签发证书,避免了自签名证书的麻烦。缺点是需要一个WAF来拒绝来自VPN外部的流量。
权衡利弊后,作者认为在服务器上统一配置一个WAF,远比在每台加入内部网络的机器上安装自签名证书要简单得多。
具体实现步骤:
1. VPN与DNS:选择支持DNS解析功能的VPN(如NetBird)。利用其“自定义区域”功能,可以轻松实现分裂域DNS,并可以设置规则,让服务器本身不使用该自定义区域,以便通过http-01挑战获取证书。
2. 获取证书:使用ACME客户端(如acme.sh)的--standalone模式签发证书。此模式下,acme.sh会临时监听80端口完成验证,无需Nginx一直监听80端口。
* 命令示例:acme.sh --issue -d grafana.tuxnet.dev --server letsencrypt --standalone
3. 配置反向代理与WAF:使用Nginx作为反向代理。关键配置是listen our-server.netbird.cloud:443 ssl;,将Nginx绑定到服务器的VPN网络接口上。这样,任何来自公共互联网、试图访问grafana.tuxnet.dev的流量都会被Nginx拒绝,这本身就是一道WAF。
4. 证书自动续期:设置一个每日执行的cron任务,调用acme.sh --cron。该任务会自动检查并续期即将过期的证书,并将新证书复制到Nginx配置指定的位置,最后重新加载Nginx。
总结: 通过结合分裂域DNS、WAF和ACME协议,可以免费、安全地为内部服务配置TLS证书,而不会给下游的HTTP客户端带来任何证书信任问题。这种方法确保了无论服务是内部还是外部,TLS都能正常工作。
补充:多域名与SAN
如果有多项内部服务,无需为每个子域名生成单独的证书。可以使用TLS的“主题备用名称(SAN)”功能,生成一个包含多个域名的证书。例如,为internal.tuxnet.dev创建A记录,并为grafana.tuxnet.dev和analytics.tuxnet.dev创建指向它的CNAME记录,然后使用acme.sh --issue -d internal.tuxnet.dev -d grafana.tuxnet.dev -d analytics.tuxnet.dev生成一个证书,即可在多个Nginx的server配置中复用。
评论总结
根据评论内容,总结如下:
主要观点分歧:
支持使用公共证书+DNS验证(多数派)
- 通过DNS-01挑战获取Let's Encrypt证书,无需暴露内部服务
- 可使用通配符证书避免泄露具体服务名
- 关键引用:
- "I use the acme dns-1 challenge on my public domain. That gives you certificates you can use as you see fit, without needing to expose anything else to the public internet." (wrxd)
- "Use DNS validation to allow these internal services to pull ACME certs. There's so much less headache, long-term." (EvanAnderson)
反对使用公共证书/暴露内部域名(少数派)
- 公共证书会记录在证书透明度日志中,泄露内部网络信息
- 内部服务应使用内部CA或自签名证书
- 关键引用:
- "Public certs are for public services." (AtNightWeCode)
- "I wonder if the author realizes that getting public certificates results in them being recorded in CT logs." (aliasxneo)
对split-horizon DNS的争议
- 部分人认为split-horizon DNS增加复杂性,容易导致问题
- 另一些人认为这是可行的方案,但需谨慎使用
- 关键引用:
- "Split-horizon DNS (and the tedious make-work it can create when you start needing to mirror public-accessibly records in the private DNS) has always been something to aspire to move away from." (EvanAnderson)
- "Personally, I hate split horizon DNS. I prefer the 'BeyondCorp' model." (thomashabets2)
替代方案建议
- 使用内部CA(如step-ca)+内部DNS(如.home.arpa)
- 通过VPN访问内部服务,避免暴露公网
- 使用TOFU(信任首次使用)机制
- 关键引用:
- "I'll just rock out with .internal or .home.arpa, have step-ca and bind communicate to each other... slap the internal ca root certs everywhere, and keep my home infra out of the crt.sh logs." (samgranieri)
- "I find myself wishing there was a dead simple self hosted CA solution and also that trust on first use (à la ssh) was A Thing." (jmbwell)
总体评价: 评论者普遍认为,为内部服务配置TLS证书没有"唯一正确"的方法,最佳方案取决于具体场景(规模、安全需求、管理复杂度)。多数人倾向于使用DNS验证+通配符证书的公共CA方案,但需注意证书透明度日志的隐私泄露风险。少数人坚持使用内部CA以完全避免暴露。split-horizon DNS被认为是一种可行但需谨慎使用的方案。