tailscale up のデフォルトは --accept-dns=true。ドキュメントでは MagicDNS を便利機能として紹介している — IP の代わりに短い名前で Tailscale ノードを解決できる、と。あらゆるセットアップガイドが無害だと扱っている。ノート PC ならその通り。サーバーでは、唯一の DNS リゾルバが、起動時に準備できておらずパブリッククエリで断続的に失敗するユーザースペースフォワーダーに置き換えられる。

TL;DR: MagicDNS は /etc/resolv.conf100.100.100.100 に無断で書き換える。サーバーでは、パブリックドメインへの断続的な SERVFAIL と再起動後のクラッシュループを引き起こす。修正:DNS の受け入れを無効化し、自前のリゾルバを設定する。

症状 #

Tailscale をメッシュネットワーキングに使用している複数の Linux サーバーで、不可解な挙動が見られました:

  • 外向きリクエストがランダムにタイムアウト、エラーが返るまで 2-3 秒
  • リロードすると通る。パターンもなく症状が出たり消えたりする
  • サービスログに散発する SERVFAILi/o timeout
  • 再起動後、複数のサービスが同時に起動失敗 — すべて DNS 解決エラーを報告

ネットワーク障害なら全リクエストが失敗するはずです。アプリのバグなら、再起動で無関係な複数サービスが一斉に壊れることはありません。もっと根本的なもの — DNS を指しています。

resolv.conf の確認 #

該当サーバーで:

cat /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 を解決するのも、aptsecurity.debian.org をチェックするのも — すべてここを通ります。

# Verify MagicDNS is active
tailscale debug prefs 2>/dev/null | grep CorpDNS

"CorpDNS": true なら確定です。

フォワーダーは信頼できない #

MagicDNS はクライアントデバイス向けに設計されたものです。サーバーで唯一のリゾルバとして使うと、完全に有効なパブリックドメインに対して断続的に SERVFAIL を返します:

# Check for DNS failures in the last 24 hours (run as root)
journalctl --since "24 hours ago" | grep -i "SERVFAIL\|server misbehaving\|i/o timeout.*:53"

検出されたもの:

ERROR 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 経由にしたことによる巻き添え被害です。

起動時のレースコンディション #

最悪の障害モードです。プロバイダーのメンテナンス再起動後、journalctl から復元したタイムライン:

21: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 が書かれているのに何も解決できません。この間に起動するすべてのサービスがクラッシュループに入ります。

根本原因 #

MagicDNS はクライアントデバイス向けに設計されたもの — ノート PC、スマートフォン。DNS の一時的な不調はそこでは見えません。

サーバーで唯一のリゾルバとして使う場合、設計上の前提が崩れます:

  1. 単一障害点: すべての DNS がユーザースペースプロセスに依存する。クラッシュまたは未準備 → 全 DNS 消失
  2. 断続的な不安定性: パブリッククエリへの散発的な SERVFAIL — DNS が原因とは追跡しにくい
  3. 起動時のレースコンディション: Tailscale の準備が整う前に resolv.conf が Tailscale を指す
  4. 無断の乗っ取り: tailscale up はデフォルトで --accept-dns=true、警告なし

resolv.conf が 1.1.1.18.8.8.8 を指していれば、可用性ははるかに高くなります。Tailscale が完全にクラッシュしても、DNS は動き続けます。

修正 #

サーバーで MagicDNS を無効化する(root で実行):

tailscale set --accept-dns=false

次に自前の DNS を設定します。systemd-resolved を使っていないシステムの場合:

cat > /etc/resolv.conf << 'EOF'
nameserver 1.1.1.1
nameserver 8.8.8.8
EOF

systemd-resolved を使っているシステムでは、/etc/systemd/resolved.conf から設定してください — /etc/resolv.conf に直接書いても上書きされます。

他のプロセスによる resolv.conf の書き換えを防止するには:

chattr +i /etc/resolv.conf

注意:chattr +i は OpenVZ 7 コンテナではファイルシステムの制約により動作しない場合があります。その場合、プロバイダーの DHCP クライアントも resolv.conf を上書きしていないか確認してください。

検証 #

# 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 <other-node>

--accept-dns=false は再起動後も維持されます。

失うもの #

機能影響
Tailscale メッシュネットワーキング影響なし
Tailscale 経由のこのサーバーへの SSH影響なし
tailscale status / tailscale ping影響なし
アプリからの全外向き DNS影響なし(1.1.1.1 を使用)
このサーバー上で Tailscale ノードを短い名前で解決IP を使う必要あり

サーバーでは、最後の項目が必要になることはほぼありません。必要なら /etc/hosts に個別のエントリを追加してください。

サーバーの簡易チェック #

grep -c "100.100.100.100" /etc/resolv.conf

1 が返る? MagicDNS が有効です。すでに被害が出ていないか確認:

journalctl --since "24 hours ago" --no-pager | grep -c "SERVFAIL\|server misbehaving"

ゼロでなければ、MagicDNS がすでにサービスに影響を与えています。

Docker ユーザーへ #

コンテナはネットワークモードによってホストの壊れた DNS を継承する場合があります:

構成リスク
Bridge + 明示的な dns: [1.1.1.1]安全
Bridge + デフォルト DNSホスト DNS を継承する可能性あり
ホストネットワーク完全に露出
# Check all running containers (run as root)
docker inspect --format '{{.Name}} dns={{.HostConfig.Dns}} net={{.HostConfig.NetworkMode}}' \
  $(docker ps -q)

自分のサーバーでは全台 MagicDNS を無効化済み。2 週間、DNS 関連のインシデントはゼロ。以前は週に 2-3 回あった — Tailscale と結びつけていなかっただけだ。