[{"content":"Z Cube は格安VPS運用に特化した技術ブログです。\n理論は書かない。実際に踏んだ地雷だけを書く。\n","permalink":"https://zcu.be/ja/pages/about/","summary":"\u003cp\u003eZ Cube は格安VPS運用に特化した技術ブログです。\u003c/p\u003e\n\u003cp\u003e理論は書かない。実際に踏んだ地雷だけを書く。\u003c/p\u003e","title":"About"},{"content":"tailscale up のデフォルトは --accept-dns=true。ドキュメントでは MagicDNS を便利機能として紹介している — IP の代わりに短い名前で Tailscale ノードを解決できる、と。あらゆるセットアップガイドが無害だと扱っている。ノート PC ならその通り。サーバーでは、唯一の DNS リゾルバが、起動時に準備できておらずパブリッククエリで断続的に失敗するユーザースペースフォワーダーに置き換えられる。\nTL;DR: MagicDNS は /etc/resolv.conf を 100.100.100.100 に無断で書き換える。サーバーでは、パブリックドメインへの断続的な SERVFAIL と再起動後のクラッシュループを引き起こす。修正：DNS の受け入れを無効化し、自前のリゾルバを設定する。\n症状 # Tailscale をメッシュネットワーキングに使用している複数の Linux サーバーで、不可解な挙動が見られました：\n外向きリクエストがランダムにタイムアウト、エラーが返るまで 2-3 秒 リロードすると通る。パターンもなく症状が出たり消えたりする サービスログに散発する SERVFAIL と i/o timeout 再起動後、複数のサービスが同時に起動失敗 — すべて DNS 解決エラーを報告 ネットワーク障害なら全リクエストが失敗するはずです。アプリのバグなら、再起動で無関係な複数サービスが一斉に壊れることはありません。もっと根本的なもの — DNS を指しています。\nresolv.conf の確認 # 該当サーバーで：\ncat /etc/resolv.conf # resolv.conf(5) file generated by tailscale # For more info, see https://tailscale.com/s/resolvconf-overwrite # DO NOT EDIT THIS FILE BY HAND -- CHANGES WILL BE OVERWRITTEN nameserver 100.100.100.100 search your-tailnet.ts.net Tailscale のヘッダーとともに 100.100.100.100 が表示されていれば — それが原因です。MagicDNS はデフォルトで有効になっています。/etc/resolv.conf を乗っ取り、Tailscale 内蔵のフォワーダーをシステム全体の唯一の DNS リゾルバにします。アプリが api.example.com を解決するのも、apt が security.debian.org をチェックするのも — すべてここを通ります。\n# Verify MagicDNS is active tailscale debug prefs 2\u0026gt;/dev/null | grep CorpDNS \u0026quot;CorpDNS\u0026quot;: true なら確定です。\nフォワーダーは信頼できない # MagicDNS はクライアントデバイス向けに設計されたものです。サーバーで唯一のリゾルバとして使うと、完全に有効なパブリックドメインに対して断続的に SERVFAIL を返します：\n# Check for DNS failures in the last 24 hours (run as root) journalctl --since \u0026#34;24 hours ago\u0026#34; | grep -i \u0026#34;SERVFAIL\\|server misbehaving\\|i/o timeout.*:53\u0026#34; 検出されたもの：\nERROR lookup app.example.com: (exchange6: SERVFAIL | exchange4: SERVFAIL) [2.17s] ERROR lookup app.example.com: (exchange6: SERVFAIL | exchange4: SERVFAIL) [2.25s] ERROR lookup cdn.example.com: (exchange4: SERVFAIL | exchange6: SERVFAIL) [2.16s] 複数のパブリックドメインが同時に失敗、各 2 秒以上。Tailscale とは無関係の普通のドメインです — すべてを MagicDNS 経由にしたことによる巻き添え被害です。\n起動時のレースコンディション # 最悪の障害モードです。プロバイダーのメンテナンス再起動後、journalctl から復元したタイムライン：\n21:58:44 System boots, tailscaled starts 21:58:44 resolv.conf overwritten → nameserver 100.100.100.100 21:58:44 Other services begin starting 21:58:55 Service A starts, attempts DNS: ERR lookup app.example.com on 100.100.100.100:53: i/o timeout 21:59:00 ERR: server misbehaving → Service A crashes 21:59:05 systemd restarts Service A → DNS fails again → crash 21:59:11 systemd restarts again → DNS fails → crash ... (every 5 seconds for 5 minutes) tailscaled は起動直後に resolv.conf を書き換えますが、MagicDNS フォワーダーの初期化には時間がかかります — Tailscale コントロールプレーンへの接続、設定の取得、上流 DNS の確立。この空白期間中、resolv.conf には 100.100.100.100 が書かれているのに何も解決できません。この間に起動するすべてのサービスがクラッシュループに入ります。\n根本原因 # MagicDNS はクライアントデバイス向けに設計されたもの — ノート PC、スマートフォン。DNS の一時的な不調はそこでは見えません。\nサーバーで唯一のリゾルバとして使う場合、設計上の前提が崩れます：\n単一障害点: すべての DNS がユーザースペースプロセスに依存する。クラッシュまたは未準備 → 全 DNS 消失 断続的な不安定性: パブリッククエリへの散発的な SERVFAIL — DNS が原因とは追跡しにくい 起動時のレースコンディション: Tailscale の準備が整う前に resolv.conf が Tailscale を指す 無断の乗っ取り: tailscale up はデフォルトで --accept-dns=true、警告なし resolv.conf が 1.1.1.1 や 8.8.8.8 を指していれば、可用性ははるかに高くなります。Tailscale が完全にクラッシュしても、DNS は動き続けます。\n修正 # サーバーで MagicDNS を無効化する（root で実行）：\ntailscale set --accept-dns=false 次に自前の DNS を設定します。systemd-resolved を使っていないシステムの場合：\ncat \u0026gt; /etc/resolv.conf \u0026lt;\u0026lt; \u0026#39;EOF\u0026#39; nameserver 1.1.1.1 nameserver 8.8.8.8 EOF systemd-resolved を使っているシステムでは、/etc/systemd/resolved.conf から設定してください — /etc/resolv.conf に直接書いても上書きされます。\n他のプロセスによる resolv.conf の書き換えを防止するには：\nchattr +i /etc/resolv.conf 注意：chattr +i は OpenVZ 7 コンテナではファイルシステムの制約により動作しない場合があります。その場合、プロバイダーの DHCP クライアントも resolv.conf を上書きしていないか確認してください。\n検証 # # DNS no longer goes through Tailscale cat /etc/resolv.conf # Should show 1.1.1.1, not 100.100.100.100 dig +short google.com # Should return instantly # Tailscale itself is unaffected tailscale status tailscale ping \u0026lt;other-node\u0026gt; --accept-dns=false は再起動後も維持されます。\n失うもの # 機能 影響 Tailscale メッシュネットワーキング 影響なし Tailscale 経由のこのサーバーへの SSH 影響なし tailscale status / tailscale ping 影響なし アプリからの全外向き DNS 影響なし（1.1.1.1 を使用） このサーバー上で Tailscale ノードを短い名前で解決 IP を使う必要あり サーバーでは、最後の項目が必要になることはほぼありません。必要なら /etc/hosts に個別のエントリを追加してください。\nサーバーの簡易チェック # grep -c \u0026#34;100.100.100.100\u0026#34; /etc/resolv.conf 1 が返る？ MagicDNS が有効です。すでに被害が出ていないか確認：\njournalctl --since \u0026#34;24 hours ago\u0026#34; --no-pager | grep -c \u0026#34;SERVFAIL\\|server misbehaving\u0026#34; ゼロでなければ、MagicDNS がすでにサービスに影響を与えています。\nDocker ユーザーへ # コンテナはネットワークモードによってホストの壊れた DNS を継承する場合があります：\n構成 リスク Bridge + 明示的な dns: [1.1.1.1] 安全 Bridge + デフォルト DNS ホスト DNS を継承する可能性あり ホストネットワーク 完全に露出 # Check all running containers (run as root) docker inspect --format \u0026#39;{{.Name}} dns={{.HostConfig.Dns}} net={{.HostConfig.NetworkMode}}\u0026#39; \\ $(docker ps -q) 自分のサーバーでは全台 MagicDNS を無効化済み。2 週間、DNS 関連のインシデントはゼロ。以前は週に 2-3 回あった — Tailscale と結びつけていなかっただけだ。\n","permalink":"https://zcu.be/ja/posts/tailscale-magicdns-server-dns-hijack/","summary":"\u003cp\u003e\u003ccode\u003etailscale up\u003c/code\u003e のデフォルトは \u003ccode\u003e--accept-dns=true\u003c/code\u003e。ドキュメントでは MagicDNS を便利機能として紹介している — IP の代わりに短い名前で Tailscale ノードを解決できる、と。あらゆるセットアップガイドが無害だと扱っている。ノート PC ならその通り。サーバーでは、唯一の DNS リゾルバが、起動時に準備できておらずパブリッククエリで断続的に失敗するユーザースペースフォワーダーに置き換えられる。\u003c/p\u003e\n\u003cp\u003e\u003cstrong\u003eTL;DR\u003c/strong\u003e: MagicDNS は \u003ccode\u003e/etc/resolv.conf\u003c/code\u003e を \u003ccode\u003e100.100.100.100\u003c/code\u003e に無断で書き換える。サーバーでは、パブリックドメインへの断続的な SERVFAIL と再起動後のクラッシュループを引き起こす。修正：DNS の受け入れを無効化し、自前のリゾルバを設定する。\u003c/p\u003e\n\u003ch2 id=\"症状\"\u003e症状\n  \u003ca class=\"anchor\" href=\"#%e7%97%87%e7%8a%b6\" aria-label=\"anchor\"\u003e#\u003c/a\u003e\n\u003c/h2\u003e\n\u003cp\u003eTailscale をメッシュネットワーキングに使用している複数の Linux サーバーで、不可解な挙動が見られました：\u003c/p\u003e\n\u003cul\u003e\n\u003cli\u003e外向きリクエストがランダムにタイムアウト、エラーが返るまで 2-3 秒\u003c/li\u003e\n\u003cli\u003eリロードすると通る。パターンもなく症状が出たり消えたりする\u003c/li\u003e\n\u003cli\u003eサービスログに散発する \u003ccode\u003eSERVFAIL\u003c/code\u003e と \u003ccode\u003ei/o timeout\u003c/code\u003e\u003c/li\u003e\n\u003cli\u003e再起動後、複数のサービスが\u003cstrong\u003e同時に\u003c/strong\u003e起動失敗 — すべて DNS 解決エラーを報告\u003c/li\u003e\n\u003c/ul\u003e\n\u003cp\u003eネットワーク障害なら全リクエストが失敗するはずです。アプリのバグなら、再起動で無関係な複数サービスが一斉に壊れることはありません。もっと根本的なもの — DNS を指しています。\u003c/p\u003e\n\u003ch2 id=\"resolvconf-の確認\"\u003eresolv.conf の確認\n  \u003ca class=\"anchor\" href=\"#resolvconf-%e3%81%ae%e7%a2%ba%e8%aa%8d\" aria-label=\"anchor\"\u003e#\u003c/a\u003e\n\u003c/h2\u003e\n\u003cp\u003e該当サーバーで：\u003c/p\u003e\n\u003cdiv class=\"highlight\"\u003e\u003cpre tabindex=\"0\" class=\"chroma\"\u003e\u003ccode class=\"language-bash\" data-lang=\"bash\"\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003ecat /etc/resolv.conf\n\u003c/span\u003e\u003c/span\u003e\u003c/code\u003e\u003c/pre\u003e\u003c/div\u003e\u003cpre tabindex=\"0\"\u003e\u003ccode\u003e# resolv.conf(5) file generated by tailscale\n# For more info, see https://tailscale.com/s/resolvconf-overwrite\n# DO NOT EDIT THIS FILE BY HAND -- CHANGES WILL BE OVERWRITTEN\n\nnameserver 100.100.100.100\nsearch your-tailnet.ts.net\n\u003c/code\u003e\u003c/pre\u003e\u003cp\u003eTailscale のヘッダーとともに \u003ccode\u003e100.100.100.100\u003c/code\u003e が表示されていれば — それが原因です。MagicDNS はデフォルトで有効になっています。\u003ccode\u003e/etc/resolv.conf\u003c/code\u003e を乗っ取り、Tailscale 内蔵のフォワーダーをシステム全体の唯一の DNS リゾルバにします。アプリが \u003ccode\u003eapi.example.com\u003c/code\u003e を解決するのも、\u003ccode\u003eapt\u003c/code\u003e が \u003ccode\u003esecurity.debian.org\u003c/code\u003e をチェックするのも — すべてここを通ります。\u003c/p\u003e","title":"Tailscale MagicDNS はサーバーの DNS を無断で乗っ取る"}]