2026年6月14日
2026年6月14日
DoT (DNS over TLS) が動作しない場合のトラブルシューティング|853番の到達性・証明書・クライアント設定の順に切り分ける
DoT(DNS over TLS)が動かないときの原因は、ほとんどが「TCP 853 番に届いていない」「TLS の証明書検証で失敗している」「クライアントの設定が意図どおりに使われていない」の3つのどれかです。この記事では、症状とログの読み方を確認したうえで、起きやすい順に原因を挙げ、それぞれの確かめ方と直し方を説明します。DoT のリゾルバーを自分で運用している場合のサーバー側の確認点も扱います。
これから DoT を使い始める手順は「切り替え手順」の記事、DNSSEC と組み合わせる構成は「DNSSEC と併用する設定」の記事で扱っているため、ここでは「設定したのに動かない」状態からの切り分けに絞ります。
まず症状を分ける
DoT の不具合は、見え方によって疑う場所が変わります。最初にどれに当てはまるかを決めておくと、調べる範囲を狭められます。
- 名前解決がまったくできない(タイムアウト・SERVFAIL)。 厳格(strict)な設定で DoT がつながらないと、平文に戻らず失敗します。到達性か証明書の問題であることが多いです。
- 名前は引けるが、DoT が使われていない。 日和見(opportunistic)の設定では、TLS が通らないと黙って平文の 53 番に戻ります。動いているように見えるため気付きにくい状態です。
- ときどき失敗する・遅い。 接続数の上限、アイドル時の切断、一部のネットワークでの遮断など、サーバー側や経路の問題が多くなります。
- 特定のネットワークでだけ失敗する。 公衆無線 LAN や一部の企業網では、外向きの TCP 853 番を閉じていることがあります。
ログで手がかりを集める
Linux で systemd-resolved を使っている場合は、ジャーナルに TLS の失敗理由が出ます。詳しく見たいときは一時的にログの詳細度を上げます。
# 現在の DNS サーバーと DoT の設定を確認
resolvectl status
# 一時的にデバッグログを有効にして、問い合わせを再現する
sudo resolvectl log-level debug
resolvectl query wordpress.org
sudo journalctl -u systemd-resolved --since "5 min ago" | grep -iE 'tls|certificate|853'
# 確認が終わったら元に戻す
sudo resolvectl log-level info
証明書の検証失敗、接続のタイムアウト、サーバーが DoT に対応していない、といった理由が読み取れれば、下の該当する原因に進みます。ログの文言は systemd のバージョンによって異なります。
Android でプライベート DNS に「接続できません」と表示される場合は、端末側に詳しい理由が出ないことが多いため、同じホスト名に対して PC から下の手順で確かめると早く片付きます。
原因1:TCP 853 番に届いていない
最も多い原因です。DoT は TCP の 853 番を使うため、53 番が通っていても 853 番が閉じていればつながりません。
# 853 番に TCP で接続できるか(Connected / succeeded と出れば届いている)
nc -vz 1.1.1.1 853
nc -vz dns.example.com 853
公開リゾルバーには届くのに自前のサーバーには届かない場合はサーバー側、どこにも届かない場合は手元のネットワークを疑います。
- 手元のネットワーク: 社内のファイアウォールやプロキシ、クラウドのセキュリティグループで外向きの 853 番を許可しているかを確かめます。家庭用ルーターや公衆無線 LAN で遮断されている場合は、そのネットワークでは DoH(443 番)を使う、などの代わりの手段を検討します。
- サーバー側:
sudo ss -lntp | grep ':853'で 853 番を待ち受けているか、受信側のファイアウォールで許可しているかを確かめます。待ち受けていなければ、DNS ソフトウェアの設定で 853 番のインターフェースが有効になっていません(原因4)。
原因2:証明書の検証に失敗している
853 番に届いていても、TLS の接続で証明書を検証できなければ厳格な設定では失敗します。openssl s_client で、クライアントと同じ条件の接続を再現できます。
# -servername は SNI、-verify_hostname は照合するホスト名
openssl s_client -connect 192.0.2.53:853 \
-servername dns.example.com -verify_hostname dns.example.com </dev/null 2>/dev/null \
| grep -E 'subject=|issuer=|Verify return code'
# 有効期限を見る
openssl s_client -connect 192.0.2.53:853 -servername dns.example.com </dev/null 2>/dev/null \
| openssl x509 -noout -dates
Verify return code: 0 (ok) 以外が出たら、コードの内容で原因を絞ります。
- ホスト名が合わない。 クライアントに設定したホスト名(systemd-resolved の
IP#ホスト名、Unbound のforward-addrの#以降、Android のプライベート DNS の値)が、証明書の名前と一致しているかを見ます。IP アドレスだけを指定していると、名前の照合ができずに失敗する実装があります。 - 中間証明書が欠けている。 サーバーがサーバー証明書だけを送っていると、
unable to get local issuer certificateのような結果になります。サーバー側の設定で、中間証明書を含むファイル(fullchain)を指定します。 - 期限切れ。 自動更新は動いているのに DNS ソフトウェアが古い証明書を読み込んだまま、ということがあります。更新後に DNS ソフトウェアを再起動または再読み込みしているかを確かめます。
- 時刻のずれ。 クライアントの時計が大きくずれていると、正しい証明書でも有効期間外と判定されます。
timedatectlで NTP の同期を確認します。
原因3:クライアントの設定が使われていない
設定は正しく書いたのに、別の DNS サーバーへ問い合わせが流れているケースです。
- リンクごとの DNS が残っている。 systemd-resolved は、DHCP などで受け取ったインターフェースごとの DNS サーバーも併用します。
resolvectl statusで、意図しないサーバーがリンク側に並んでいないかを見ます。netplan なら DHCP の DNS を使わない設定に変えます。 - **
/etc/resolv.confが置き換わっている。** スタブ(127.0.0.53)以外を指していると、systemd-resolved の設定自体が使われません。ls -l /etc/resolv.confで参照先を確かめます。 - 日和見で平文に戻っている。
DNSOverTLS=opportunisticでは、TLS が通らないと平文に戻ります。次のコマンドで外向きの 53 番を数分観察し、平文の問い合わせが出ていれば DoT は使われていません。
sudo tcpdump -ni any '(udp port 53 or tcp port 53) and not host 127.0.0.1 and not host 127.0.0.53'
- アプリが独自の DNS を使っている。 ブラウザの DoH 設定や、コンテナの DNS 設定は OS の設定とは別です。OS の DoT が効いていても、アプリの問い合わせは別経路を通ることがあります。
原因4:サーバーが DoT で応答できない(自前のリゾルバー)
自分で DoT のリゾルバーを動かしている場合は、サーバー側の設定とログも見ます。Unbound の例で挙げます。
- 証明書や鍵を読めない。
tls-service-pemとtls-service-keyのパス、ファイルの読み取り権限を確かめます。ディストリビューションによっては AppArmor などで読めるパスが制限されており、権限が正しくても読めないことがあります。起動時のログに理由が出ます。 - 853 番のインターフェースが無い。
interface: 0.0.0.0@853のように、ポートを付けた待ち受けを書いているかを確かめます。tls-portの値と合っていないと、そのインターフェースは TLS になりません。 - REFUSED が返る。 TLS はつながるのに
REFUSEDが返る場合は、access-controlで接続元を許可していません。DoT の前段に別のプロキシを置いている構成では、リゾルバーから見た接続元がプロキシのアドレスになる点にも注意します。
sudo unbound-checkconf
sudo journalctl -u unbound --since "10 min ago"
# サーバー上で、平文と DoT の両方を試す(kdig は knot-dnsutils に含まれる)
dig @127.0.0.1 wordpress.org +short
kdig @127.0.0.1 -p 853 +tls wordpress.org
平文では引けて DoT だけ失敗するなら TLS の設定、両方失敗するならリゾルバー本体の問題です。
原因5:ときどき失敗する・遅い
TCP と TLS は接続を張る分だけ負荷がかかり、接続数の上限に当たりやすくなります。Unbound では、1スレッドあたりの TCP 接続数の上限 incoming-num-tcp の既定値が小さめで、利用者が増えると接続を受け付けられなくなることがあります。ログに接続の拒否やタイムアウトが増えていないかを見て、利用者の数に合わせて値を見直します。
クライアントとサーバーのどちらかが早めにアイドル接続を切ると、問い合わせのたびに TLS の接続をやり直すことになり、遅く感じます。Unbound の tcp-idle-timeout や edns-tcp-keepalive などの値、前段のロードバランサーのアイドルタイムアウトを確かめます。値の意味と既定値は、手元のバージョンの man unbound.conf で確認してください(2026年10月現在)。
直したあとに確かめること
openssl s_clientの検証結果が0 (ok)になっている。resolvectl queryなどで名前が引け、DoT 経由で取得したことが表示される(表示内容は systemd のバージョンにより異なります)。tcpdumpで外向きの平文 53 番が出ていない。- 日和見で様子を見ていた場合は、問題がなければ厳格(
DNSOverTLS=yesなど)に戻す。
名前解決が止まると SSH の接続やパッケージの更新にも影響します。リモートのサーバーで設定を変えるときは、コンソール接続など別の経路を確保し、変更前の設定ファイルを控えてから作業してください。
まとめ
- DoT の不具合は「853 番に届かない」「証明書の検証失敗」「クライアントの設定が使われていない」の順に疑うと早く片付きます。
- 到達性は
nc -vzで、証明書はopenssl s_client -servername -verify_hostnameで、クライアントと同じ条件を再現して確かめます。 - 日和見の設定では失敗しても平文に戻るため、
tcpdumpで外向きの 53 番を観察して実際に DoT が使われているかを見ます。 - 自前のリゾルバーでは、証明書の読み取り権限、853 番のインターフェース、
access-control、TCP の接続数の上限を確認します。