自前EdgeDNSみたいなことをしようとしていることの調査

5 min

language: ja bn en es hi pt ru zh-cn zh-tw

こんにちは、無能です。

最近ConoHaの障害があるのはもちろんなのですが、バックエンド側サーバが気づいたら死んだり(ちなみにホストマシン移行で解消)悩ましいので自前Edge DNSをどうやったら作れるので試してます。

CNAMEに登録しているレコードにAレコード2つ登録

こうします

$ 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 1つしか登録できないので実質的には登録出来ません。そのため www.soulmingrig.comCNAME を登録して中身は edge.soulminingrig.com. として、 edge.soulminingrig.com. のAレコードを2つ登録します。

そもそも、ルートに対して複数のAレコードを指定すればいいじゃないか、となるかもしれませんが今後の拡張性のために CNAME に登録しています。

こうなるとどうなるか試したのですがなんかConoHaのDNSってPowerDNS使っているんじゃないか?って思ったのですが以下を検証しました。

  • 91.98.169.80をサーバーストップ

  • 163.44.113.145だけ稼働

こうなればただのラウンドロビンだったらそれなりに 91.98.169.80 に対してトラフィックが流れると思ったんですがきれいに 163.44.113.145 にしか流れていかないんですよね。ヘルスチェック入ってそうな感じがPowerDNSワンちゃん使っていたりしないのかなと思った次第です。

※公式ではラウンドロビンとだけなので宛にしないでください

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レコード2つとものサーバで更新が出来るじゃないか、と思ったのですがそんな甘くはありませんでした。

結論的には結構ゴリ押しで専用ユーザから証明書を 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 で更新後に稼働させるサブシェルみたいなのを実行出来るみたいです。

というのもそもそも certbot が複数Aレコードを持つサーバーでACMEチャレンジするときの証明書の場合どっちかに分散されるからどっちかが成功してどっちか失敗するんだろうと思っていたら何故か元々発行していたサーバー側でしか通らず?(ちょっと仕様的には筋が通らないのでなにかある気がする)でデフォルトの certbot の場合はファイル認証で一瞬ファイルを配置してACMEチャレンジが通ったら、一時ファイルをいらんくなったらすぐ消すような仕様なので実際にはラウンドロビンな環境だったらどっちかに割り振られるような仕様になるはずである。

そしてDNS 認証に関しては自動で nginx 側の証明書ファイルも動的に追加してくれる --nginx オプション使えないからやめたけど実際証明書パスって変わるものじゃないから今になってから DNS 認証のほうがよかったなと思うのは完全に寝ぼけていたな・・・。

ConoHa API経由でDNSレコードの変更通知は出来るので実際それで済む話なんだけれど・・・。

Related Posts