自建Edge DNS的探索
大家好,我是无能。
最近ConoHa当然出现了故障,而且后端服务器不知不觉就宕机了(顺便说一下,通过主机迁移解决了),这让我很头疼,所以我正在尝试如何自建Edge DNS。
在CNAME记录中注册两个A记录
操作如下:
$ dig www.soulminingrig.com
; <<>> DiG 9.20.16 <<>> www.soulminingrig.com
;; global options: +cmd
;; Got answer:
;; ->>HEADER<<- opcode: QUERY, status: NOERROR, id: 33051
;; flags: qr rd ra; QUERY: 1, ANSWER: 3, AUTHORITY: 0, ADDITIONAL: 1
;; OPT PSEUDOSECTION:
; EDNS: version: 0, flags:; udp: 512
;; QUESTION SECTION:
;www.soulminingrig.com. IN A
;; ANSWER SECTION:
www.soulminingrig.com. 300 IN CNAME edge.soulminingrig.com.
edge.soulminingrig.com. 300 IN A 91.98.169.80
edge.soulminingrig.com. 300 IN A 163.44.113.145
;; Query time: 94 msec
;; SERVER: 192.168.1.1#53(192.168.1.1) (UDP)
;; WHEN: Mon Apr 06 20:40:33 JST 2026
;; MSG SIZE rcvd: 101根据RFC规定,根域名实际上只能注册一个 CNAME 记录,因此无法直接注册。所以,我们注册 www.soulmingrig.com 的 CNAME 记录,其内容指向 edge.soulminingrig.com.,然后为 edge.soulminingrig.com. 注册两个A记录。
也许有人会问,为什么不直接为根域名指定多个A记录呢?这是为了未来的扩展性,所以将其注册为 CNAME 记录。
我尝试了这样做会发生什么,感觉ConoHa的DNS是不是使用了PowerDNS?我验证了以下几点:
停止服务器 91.98.169.80
只运行 163.44.113.145
如果只是简单的轮询,我以为流量会相应地流向 91.98.169.80,但实际上流量只流向了 163.44.113.145。这让我觉得PowerDNS可能内置了健康检查功能。
※官方只说是轮询,所以请勿以此为准。
GeoDNS,很棘手
GeoDNS旨在从最适合的区域向客户端分发内容,但越是思考,越觉得其便捷实现非常困难。
即使在FreeBSD上,软件包也太少了,甚至 GeoIP.bat 文件中的数据库现在似乎也不再分发了,不过也许在某个地方还在分发?
https://gist.github.com/denji/9487759
在实际操作中,感觉在个人环境中通过Nginx进行分发会更现实。那么,如何才能方便地在Nginx端进行分发呢……?
那么,区域间的速度差异……
这次添加的是位于德国的闲置服务器。
就是 91.98.169.80。从日本访问的话,响应延迟相当严重。
因此,我将通过修改内核参数来尽力优化。添加了包括 TCP Fast Open 在内的以下设置。
TCP BBR 原本在设置时就已启用,但感觉在正确配置 KeepAlive 后,情况有所改善。
net.ipv4.tcp_congestion_control=bbr
net.core.default_qdisc=fq
net.ipv4.tcp_keepalive_time=60
net.ipv4.tcp_keepalive_intvl=10
net.ipv4.tcp_keepalive_probes=5
net.ipv4.tcp_no_metrics_save=1
net.core.rmem_max=16777216
net.core.wmem_max=16777216
net.ipv4.tcp_fastopen=3如果能准确测量的话就没错了……。
看来 GeoIP 的道路还很漫长,这只是一个临时解决方案。
向拥有多个A记录的HTTP服务器分发证书
这个问题让我很头疼。
因为我正在使用 certbot 进行更新,我原以为如果使用 certbot 进行DNS认证,那么两个A记录的服务器都可以更新,但事实并非如此简单。
最终,我采取了一种比较强硬的方式,通过专用用户使用 rsync 同步证书。
0 0 1,15 * * /usr/local/bin/certbot renew --nginx --deploy-hook "/usr/local/bin/rsync -azL --no-perms --no-owner --no-group --omit-dir-times --no-times /usr/local/etc/letsencrypt/live/ certsync@10.1.0.999:/usr/local/etc/letsencrypt/live/"我本不想这样做,但似乎可以使用 --deploy-hook 在更新后执行一个子shell。
因为我原以为,当 certbot 在拥有多个A记录的服务器上进行ACME挑战时,证书会分散到其中一个服务器,导致一个成功一个失败。但不知为何,它只在最初颁发证书的服务器上通过了?(这在规范上有点说不通,感觉有什么特别之处)默认的 certbot 在文件认证时,会短暂放置文件,ACME挑战通过后立即删除临时文件,所以在轮询环境中,它应该会分配到其中一个服务器。
至于 DNS 认证,我放弃了,因为它不能使用 --nginx 选项来自动动态添加 nginx 端的证书文件。但实际上证书路径并不会改变,所以现在回想起来,我当时完全是糊涂了, DNS 认证会更好。
通过ConoHa API可以进行DNS记录的变更通知,所以实际上这就可以解决问题了……。