VPSを運用していて、「手元からSSH接続はできるのに、サーバー内部から apt update や curl、外部への通信が一切通らなくなった」という経験はありませんか?
今回、Tailscale を導入しているUbuntu VPSでまさにこの現象が発生しました。
結論として、原因は 「TailscaleのMagicDNS」と「Ubuntuのsystemd-resolved(/etc/resolv.conf のシンボリックリンク)」の不整合 による名前解決エラーでした。
同じトラブルでハマっている方のために、どこを見て切り分けるべきか、そして根本原因と復旧手順をまとめました。
1. 症状:何が起きていたか?
- 外部PCからVPSへのSSHログインは問題なく可能。
- VPS内部から外部IP宛の通信(
ping 8.8.8.8)は 1ms台で快調に通る。 - しかし、ドメイン宛(
ping google.comやapt update)を実行すると以下のエラーで即死する。
Plaintextping: www.google.com: Temporary failure in name resolution
「IPは通るのにドメインだけ通らない」= 100% DNS(名前解決)の問題 です。
2. 調査ステップと切り分けのポイント
① /etc/resolv.conf を確認する
まずDNSの設定ファイルを確認しました。
$ cat /etc/resolv.conf
# resolv.conf(5) file generated by tailscale
nameserver 100.100.100.100
nameserver fd7a:115c:a1e0::53
search tailxxxxxx.ts.net ...
DNSサーバーが 100.100.100.100(TailscaleのMagicDNS)に向けられていました。
② Tailscaleのログ(journalctl)を確認する
Tailscaleデーモンのログを見たところ、決定的なエラーが出ていました。
$ sudo journalctl -u tailscaled -n 30 --no-pager
...
tailscaled[3461578]: dns: resolver: forward: no upstream resolver
tailscaled[3461578]: dns: resolver: forward: no upstream resolver
「no upstream resolver(転送先の上位DNSサーバーが1つもない)」。
つまり、Tailscaleは「一般ドメイン(google.comなど)の名前解決リクエストを受け取ったが、それをどこに転送すればいいか分からないためパケットを破棄していた」状態でした。
③ なぜ上位DNSを見失ったのか?(最大の盲点)
さらに調査を進めるため、Tailscaleの内部ステータスとOS側のDNSマネージャー(systemd-resolved)の状態を確認しました。
$ tailscale status --json | grep -i \"failed\"
\"Tailscale failed to fetch the DNS configuration of your device: exit status 1\"
$ ls -l /etc/resolv.conf
-rw-r--r-- 1 root root 268 /etc/resolv.conf # ← シンボリックリンクではなく通常ファイル!
$ resolvectl status
...
resolv.conf mode: foreign # ← ここが最大の異常ポイント!
...
ここで根本原因がすべて繋がりました。
![[Tailscale]DNS名前解決ができない原因と完全復旧](https://mtoy.work/develop/wp-content/uploads/sites/3/2026/04/tailscale-logo-160x90.png)
3. 今回の根本原因
原因は 2重の不整合 にありました。
【破綻した名前解決の図】
アプリ (curl / ping)
│
▼
/etc/resolv.conf (静的ファイル / foreign 状態)
│
▼ nameserver 100.100.100.100 (MagicDNS)
tailscaled デーモン
│
├─► OSのDNS設定を読み取ろうとするが失敗 (\"failed to fetch... exit status 1\")
│ (※ /etc/resolv.conf が正規の symlink でないため連携破壊)
│
▼
転送先(Upstream DNS)が 0 件になりパケット破棄! (\"no upstream resolver\")
- Ubuntuの仕様:
モダンなUbuntuでは、/etc/resolv.confは/run/systemd/resolve/stub-resolv.conf(127.0.0.53を指すスタブリゾルバ)へのシンボリックリンクになっているのが正常な状態です。 - シンボリックリンクの破損(
mode: foreign):
手動編集や過去のネットワークスクリプト等により、リンクが剥がれて「静的な通常ファイル」に置き換わっていました。 - Tailscaleの検知失敗:
Tailscaleは起動時にホストOSのDNS設定を取得して上位DNSを自動構成しようとしますが、ファイルがforeign状態だったため読み取りに失敗(exit status 1)。 - 結果:
Tailscaleの管理画面でいくらNameserverを追加・同期しようとしても、ローカル側でOSとの連携が取れず、no upstream resolverとなって名前解決が全滅していました。
![[Tailscale]DNS名前解決ができない原因と完全復旧](https://mtoy.work/develop/wp-content/themes/cocoon-master/images/no-image-160.png)
4. 解決手順(復旧コマンド)
復旧は、/etc/resolv.conf を本来の systemd-resolved のスタブへのシンボリックリンクに修復し、Tailscaleに再認識させる だけで一発で治ります。
STEP 1: resolv.conf を正規のシンボリックリンクに戻す
# 既存の壊れた静的ファイルをバックアップ退避
sudo mv /etc/resolv.conf /etc/resolv.conf.bak
# systemd-resolved のスタブファイルへシンボリックリンクを再作成
sudo ln -s /run/systemd/resolve/stub-resolv.conf /etc/resolv.conf
STEP 2: 関連デーモンを再起動する
sudo systemctl restart systemd-resolved
sudo systemctl restart tailscaled
STEP 3: 疎通確認
# 外の名前解決ができるか
ping -c 3 www.google.com
# Tailscale内のホスト名が引けるか
ping -c 2 <Tailscaleネットワーク内の端末名>
これで無事に外部ドメインもTailscaleの内部ホスト名(MagicDNS)も両方引けるようになりました!
5. まとめと注意点
- 「IPは届くのに名前解決だけ死ぬ」ときは、まず
journalctl -u tailscaledを疑うべしno upstream resolverが出ていたらTailscaleが名前解決を握りつぶしています。 /etc/resolv.confを手動で編集して通常ファイルにしてはいけない
Ubuntu環境ではls -l /etc/resolv.confを叩いて、/run/systemd/resolve/stub-resolv.confへのシンボリックリンクになっているか必ず確認しましょう。- 一時的に外へ抜けたいだけの緊急回避策:
もしTailscale内の名前解決が不要で、とにかく今すぐaptなどを通したい場合は、以下のコマンドでTailscaleによるDNS乗っ取りを即座に解除できます。
Bashsudo tailscale up --accept-dns=false

コメント