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月現在)。

直したあとに確かめること

  1. openssl s_client の検証結果が 0 (ok) になっている。
  2. resolvectl query などで名前が引け、DoT 経由で取得したことが表示される(表示内容は systemd のバージョンにより異なります)。
  3. tcpdump で外向きの平文 53 番が出ていない。
  4. 日和見で様子を見ていた場合は、問題がなければ厳格(DNSOverTLS=yes など)に戻す。

名前解決が止まると SSH の接続やパッケージの更新にも影響します。リモートのサーバーで設定を変えるときは、コンソール接続など別の経路を確保し、変更前の設定ファイルを控えてから作業してください。

まとめ

  • DoT の不具合は「853 番に届かない」「証明書の検証失敗」「クライアントの設定が使われていない」の順に疑うと早く片付きます。
  • 到達性は nc -vz で、証明書は openssl s_client -servername -verify_hostname で、クライアントと同じ条件を再現して確かめます。
  • 日和見の設定では失敗しても平文に戻るため、tcpdump で外向きの 53 番を観察して実際に DoT が使われているかを見ます。
  • 自前のリゾルバーでは、証明書の読み取り権限、853 番のインターフェース、access-control、TCP の接続数の上限を確認します。

お気軽にご相談ください

お見積りへ お問い合わせへ
▲