2026年6月17日
2026年6月17日
DoQ (DNS over QUIC) の署名チェック手順|QUIC 上の証明書検証・ALPN・ピン留めを kdig や q で確かめる
DoQ(RFC 9250)の署名チェックは、QUIC のハンドシェイクに組み込まれた TLS 1.3 で、サーバー証明書の連鎖とサーバーの署名が正しく検証されているかを確かめる作業です。DoT と考え方は同じですが、UDP の853番を使うため openssl s_client をそのまま当てられない、ALPN の doq が合わないと接続できない、といった DoQ ならではの事情があります。この記事では、DoQ に対応したクライアントで証明書の検証を行い、失敗すべきときに失敗することまで確かめる手順を説明します。
例として、自分で運用する DoQ サーバー dns.example.com(203.0.113.53)を点検する場面を想定します。
DoQ で確かめる署名と、DoT との違い
DoQ でも、確かめる対象は次の3つです。
- 証明書の連鎖:サーバー証明書が中間認証局、中間証明書がルート認証局によって署名され、端末が信頼するルートまでつながっているか。
- ハンドシェイクでの署名:QUIC は TLS 1.3 を内部に持ち、サーバーは証明書に対応する秘密鍵で署名して、本物であることを示します。QUIC では TLS 1.2 以前は使われません。
- 照合の方式:ホスト名で証明書を照合するか、公開鍵のハッシュ(SPKI ピン)で照合するか。
DoT との主な違いは次のとおりです。
- 輸送が UDP:853番の TCP ではなく UDP です。ファイアウォールで UDP 853 が閉じていると、証明書を確かめる前の段階で失敗します。
- **ALPN が
doq**:QUIC では ALPN の値でアプリケーションを区別します。DoQ の標準の値はdoqで、RFC 化前のドラフト段階の実装では別の値やポートが使われていた例があります。古いクライアントやサーバーが混ざると、証明書が正しくてもハンドシェイクが成立しません。 - 0-RTT の扱い:QUIC は再接続時に 0-RTT でデータを送れますが、再送攻撃(リプレイ)の対象になり得るため、RFC 9250 ではその扱いに注意が述べられています。署名の確認とは直接関係しませんが、サーバー側で 0-RTT を許可しているかは記録しておきます。
手順1:UDP 853 番に届くかを先に確かめる
証明書の問題とネットワークの問題を混同しないよう、最初に到達性を見ます。UDP は応答がないと「届いたが無視された」のか「途中で捨てられた」のかが分かりにくいため、サーバー側で待ち受けを確認しておきます。
# サーバー側:UDP 853 で待ち受けているか
sudo ss -ulnp | grep ':853'
# クライアント側:パケットが出ていくか、応答が戻るかを見る
sudo tcpdump -ni any 'udp port 853'
クライアントから問い合わせたときに送信だけが見えて応答が戻らない場合は、クラウドのセキュリティグループやルーターで UDP 853 が閉じていないかを確かめます。
手順2:kdig で証明書を検証しながら問い合わせる
Knot DNS の kdig は、新しい版で +quic による DoQ の問い合わせに対応しています。DoT と同じ +tls-ca・+tls-hostname・+tls-pin で証明書の検証方法を指定できます。
# システムの CA で連鎖を検証し、名前を照合して問い合わせる
kdig @203.0.113.53 +quic +tls-ca +tls-hostname=dns.example.com example.com A
# わざと違う名前で照合する。接続が拒否されれば照合は働いている
kdig @203.0.113.53 +quic +tls-ca +tls-hostname=wrong.example.net example.com A
1つ目で応答が返り、2つ目が失敗すれば、連鎖の検証と名前の照合が機能しています。2つ目も成功してしまう場合は、検証の指定が効いていないか、オプションの綴りが手元の版と合っていません。+quic が使えない場合は版が古い可能性があるため、kdig -h で対応を確認してください(2026年10月現在)。
手順3:別のクライアントでも結果をそろえる
1つの道具だけで確かめると、その道具の既定の挙動に引きずられることがあります。DoQ に対応したクライアントとして、Go で書かれた q や AdGuard の dnslookup などがあります。
# q の例:quic:// で DoQ を指定する
q example.com A @quic://dns.example.com
# dnslookup の例
dnslookup example.com quic://dns.example.com
これらのクライアントにも証明書の検証を省略するオプションがあります。点検の際は、そうしたオプションを付けずに実行し、検証付きで成功することを確かめます。ネット上の手順をそのまま貼り付けると、検証を無効にする指定が紛れ込んでいることがあるので、コマンドを実行する前に読み直してください。各ツールのオプション名は版によって変わるため、ヘルプの表示を基準にします。
手順4:証明書そのものを取り出して確かめる
DoQ の証明書を直接ファイルとして取り出すには、次のどちらかが現実的です。
- 同じ証明書を DoT(TCP 853)や DoH(TCP 443)でも使っている場合:そちらに
openssl s_client -showcertsで接続して取り出し、openssl verifyで連鎖を確かめます。DoQ 側が同じファイルを読み込んでいるかは、サーバーの設定ファイルで確認します。 - サーバー上のファイルを直接見る場合:DoQ のサービスが読み込んでいる証明書ファイルを確認します。
openssl x509 -in /path/to/fullchain.pem -noout \
-subject -issuer -enddate -ext subjectAltName
openssl x509 -in /path/to/fullchain.pem -noout -text | grep "Signature Algorithm"
subjectAltName に端末が照合する名前があるか、署名アルゴリズムが SHA-256 以上か、期限が近づいていないかを見ます。OpenSSL も新しい版で QUIC のクライアント機能を備え、s_client に QUIC で接続するオプションが加わっていますが、版による差が大きいため、使う場合は openssl s_client -help で確認してください。
SPKI ピンの値を計算する
ピンで照合する端末があるなら、公開鍵のハッシュを計算し、手順2の kdig で照合を試します。
openssl x509 -in /path/to/fullchain.pem -pubkey -noout \
| openssl pkey -pubin -outform der \
| openssl dgst -sha256 -binary | openssl enc -base64
# 計算した値で照合(値は例。上の出力に置き換える)
kdig @203.0.113.53 +quic +tls-pin=your-spki-pin-base64 example.com A
ピンは公開鍵から計算するため、鍵を作り直すと値が変わります。自動更新で毎回新しい鍵が作られる設定のままピンを配ると、更新のたびに端末が接続できなくなります。ピンを使うなら、鍵を再利用する設定にするか、次の鍵のピンを事前に配る運用が必要です。
確認の結果と注意点を記録する
点検した結果は、次の項目で記録しておくと、証明書の更新後に差分を比べやすくなります。
- UDP 853 の到達性(IPv4・IPv6)と ALPN が
doqで成立すること - 正しい名前で成功し、違う名前で失敗すること
- 証明書の発行者・subjectAltName・署名アルゴリズム・有効期限
- SPKI ピンの値(現在の鍵と次の鍵)
- DoT・DoH と証明書を共有している場合、どのサービスが同じファイルを読んでいるか
証明書の更新後に、Web サーバーや DoT は新しい証明書を読み込んだのに DoQ のプロセスだけが古い証明書を持ち続ける、という漏れは起きやすいものです。更新の仕組みに DoQ のサービスの再読み込みを含め、更新のたびに手順2を繰り返します。設定や証明書を入れ替える前には、現在の設定ファイルと鍵をバックアップし、ステージング環境で同じ手順を通してから反映してください。
最後に、ここで確かめた署名は通信相手が本物かを保証するもので、DNS の応答データが正しいかは保証しません。応答の正しさは DNSSEC の検証で確かめます。DoQ サーバーが検証を行う設定なら、kdig +quic +dnssec で署名されたドメインを引き、応答のフラグに ad が付くかを見ておきます。
まとめ
- DoQ の署名チェックは、QUIC 内の TLS 1.3 で証明書の連鎖・サーバーの署名・名前またはピンの照合を確かめる作業。
- 最初に UDP 853 の到達性を確かめ、ネットワークの問題と証明書の問題を分ける。
- kdig の
+quicと+tls-ca・+tls-hostname・+tls-pinで検証し、誤った名前やピンで失敗することまで見る。 - 別のクライアントでも検証を省かずに結果をそろえ、証明書ファイルは openssl で直接確かめる。
- 証明書の更新で DoQ だけ古い証明書が残る漏れに注意し、応答データの正しさは DNSSEC で別に確かめる。