Skip to content

fix(adguardhome): 外からの平文 DNS(53)を Cilium のポリシーで捨てる - #644

Merged
5ym merged 1 commit into
mainfrom
adguard-close-53
Oct 31, 2026
Merged

5ym merged 1 commit into
mainfrom
adguard-close-53

Conversation

@5ym

@5ym 5ym commented Oct 31, 2026

Copy link
Copy Markdown
Collaborator

なぜ

AdGuard Home の 53 番が DMZ で外に出ていて、DNS の増幅攻撃の踏み台に使われていた。

  • 全問い合わせ 約 103 万件のうち 91.5 万件(89%)が xxx.heimaoip.com の TXT(返事は数 KB)
  • 送信元は 91.108.9.x(Telegram)・T-Mobile・Verizon などで、偽装された攻撃先
  • すべて平文の DNS。正規の平文の問い合わせは 10.x(家の LAN)と Pod(fd42::)からだけ。外の端末は DoT・DoH を使っている

何を変えたか

  • apps/adguardhome/network-policy.yaml: プライベートのアドレス(10/8・172.16/12・192.168/16・NetBird の 100.64/10・fc00::/7・fe80::/10)以外からの 53 番を ingressDeny で捨てる。拒否だけだと Pod が既定拒否になるので、全部を通す ingress と組にしている。CIDR の規則はクラスタの中(Pod・ノード)には当たらない
  • DoT(853)と DoH は絞らない。allowed_clients で絞らないのは、DoT・DoH にも効いて外の端末が使えなくなるため
  • docs/router.md の「53 番は外にも開けている(意図して)」を「53 番は外に出さない」に書き換えた

確かめること(マージ後)

  • AdGuard のクエリログで heimaoip が止まり、10.x からの問い合わせは答えが返っている
  • 外の端末の DoT・DoH が使える

🤖 Generated with Claude Code

https://claude.ai/code/session_01T9PbUfqG4pPxus99UeLiJs

DMZ で外に出ていた 53 番が、送信元を偽装した DNS の増幅攻撃の踏み台に
使われていた(`xxx.heimaoip.com` の TXT が 1 日 90 万件、全問い合わせの 89%)。
平文の DNS を使うのは家の LAN・Pod・NetBird だけなので、プライベートの
アドレス以外からの 53 番を Pod の手前で捨てる。DoT(853)と DoH は外から
使っているので絞らない。

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01T9PbUfqG4pPxus99UeLiJs
@claude

claude Bot commented Oct 31, 2026 •

Copy link
Copy Markdown

Claude finished @5ym's task in 24s —— View job


レビュー結果

方針(53 番だけを Cilium の ingressDeny で絞り、853/DoH は残す)と、allowed_clients を使わない理由は妥当です。ingress: fromEntities: all と ingressDeny を組にする構成も、deny が allow に勝つ Cilium の仕様に沿っています。docs/router.md の書き換えも実装と合っています。

指摘は 1 件だけです。

要確認: LAN 端末が IPv6 のグローバルアドレスで 53 番に来るケース (apps/adguardhome/network-policy.yaml の ::/0 の except)

  • IPv6 側で許可しているのは fc00::/7 と fe80::/10 だけです。
  • docs/router.md を見ると、LAN は J:COM の 240f:6d:842b:1::/64 を RA で配られています。端末は SLAAC のグローバルアドレスを持ちます。
  • ルーターや端末が AdGuard を IPv6 のアドレスで引いている場合、その送信元は 240f: のグローバルアドレスです。ULA でもリンクローカルでもないので、家の LAN の端末の DNS まで捨てられます。
  • ノード自身の 240f:6d:842b:1::2 は、クラスタの内側として扱われるなら当たりません。ただ、LAN の他端末は当たります。
  • PR の説明は「正規の平文は 10.x と Pod(fd42::)から」としています。IPv6 でも引いている端末が無いかは、クエリログで確認してください。
  • あれば 240f:6d:842b:1::/64 を except に足す必要があります。プレフィックスは RA 由来で変わりうる(docs/decisions.md:154)ので、足すなら変わる前提で扱ってください。
  • もし IPv4 だけで引いているなら、現状のままで問題ありません。

補足(指摘ではありません)

  • hostPort 経由でも送信元 IP が保たれる(deployment.yaml:245)ので、CIDR の判定は機能する想定です。マージ後の確認項目(heimaoip が止まる、10.x に答えが返る)がそのまま検証になります。
  • 同じ確認項目に「LAN の IPv6 端末の DNS が引けること」を足すと安全です。
  • マニフェストを実機やクラスタで適用して試してはいません。静的に読んだ範囲のレビューです。
  • テストの仕組みはこのリポジトリに無く、確認項目で代替しているので、追加の指摘はありません。

@5ym
5ym merged commit 10d6189 into main Oct 31, 2026
4 checks passed
@5ym
5ym deleted the adguard-close-53 branch October 31, 2026 03:32
@AEP20

AEP20 commented Oct 31, 2026

Copy link
Copy Markdown

Hi! I'm independently investigating the xxx.heimaoip.com/TXT traffic observed across several DNS sensors and came across your PR.

I was wondering about a few details:

  1. Were the several-KB DNS responses actually measured (e.g. packet capture or logs), or was that an estimate?
  2. Was source-IP spoofing directly confirmed, or inferred from the reported source networks?
  3. Do you happen to know the approximate UTC time window of the ~915k queries?

No sensitive data needed, of course. Even a small anonymized measurement would be very helpful.

Thanks for documenting this!

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants