現象
EDNS Client Subnet のアドレスが prefix でマスクされていない。dig はホスト部を 0 にして送るが、tdig は元のアドレスをそのまま送る。
# Tdig.CLI.parse_subnet_option("192.0.2.1/24")
{:edns_client_subnet,
%{family: 1, client_subnet: {192, 0, 2, 1}, source_prefix: 24, scope_prefix: 0}}
# ^^^^^^^^^^^^^ 第 4 オクテットが残っている
dig 9.20.26 の実測(+qr で送信パケットを表示)。
$ dig +qr +subnet=192.0.2.1/24 ... example.com
; CLIENT-SUBNET: 192.0.2.0/24/0
^ 0 にマスクされている
問題
RFC 7871 §6 は ADDRESS について、SOURCE PREFIX-LENGTH を超えるビットを 0 にすることを求めている。
Bits beyond the SOURCE PREFIX-LENGTH ... MUST be set to 0.
ECS は「上流の権威サーバに、応答の最適化に必要な最小限の位置情報だけを渡す」ための仕組みで、prefix を短く指定することが精度を落とす手段になっている。ホスト部を残して送ると、利用者が /24 と書いて隠したつもりの下位ビットがそのまま上流に渡る。プロトコル違反であると同時に、機能の目的そのものを損なう。
対応案
parse_subnet_option/1 で、クランプ後の source_prefix を使ってアドレスをマスクする。
- IPv4: 4 オクテット、上位
source_prefix ビットを残して以降を 0
- IPv6: 8 グループ(16 bit 単位)、同様
source_prefix が 0 の場合はアドレス全体が 0 になる(RFC 7871 が「位置情報を渡さない」意思表示として定めている形)。
検証観点
192.0.2.1/24 → {192, 0, 2, 0}
192.0.2.1/25 → {192, 0, 2, 0}(境界がオクテットに揃わない場合)
192.0.2.129/25 → {192, 0, 2, 128}
192.0.2.1/0 → {0, 0, 0, 0}
2001:db8::1/32 → {0x2001, 0x0db8, 0, 0, 0, 0, 0, 0}
- クランプとの組み合わせ(
/999 は 32 に丸めた後にマスク=実質マスク無し)
dig +qr の出力と突き合わせて確認するのが確実。
経緯
#86(prefix 長の検証)の作業中に dig の送信パケットを実測して判明した。prefix の検証とは独立した別の不具合なので、PR #87 のスコープからは外した。
https://claude.ai/code/session_01YAjSJR67tWTvYDJLcQThbQ
現象
EDNS Client Subnet のアドレスが prefix でマスクされていない。
digはホスト部を 0 にして送るが、tdig は元のアドレスをそのまま送る。dig9.20.26 の実測(+qrで送信パケットを表示)。問題
RFC 7871 §6 は ADDRESS について、SOURCE PREFIX-LENGTH を超えるビットを 0 にすることを求めている。
ECS は「上流の権威サーバに、応答の最適化に必要な最小限の位置情報だけを渡す」ための仕組みで、prefix を短く指定することが精度を落とす手段になっている。ホスト部を残して送ると、利用者が
/24と書いて隠したつもりの下位ビットがそのまま上流に渡る。プロトコル違反であると同時に、機能の目的そのものを損なう。対応案
parse_subnet_option/1で、クランプ後のsource_prefixを使ってアドレスをマスクする。source_prefixビットを残して以降を 0source_prefixが 0 の場合はアドレス全体が 0 になる(RFC 7871 が「位置情報を渡さない」意思表示として定めている形)。検証観点
192.0.2.1/24→{192, 0, 2, 0}192.0.2.1/25→{192, 0, 2, 0}(境界がオクテットに揃わない場合)192.0.2.129/25→{192, 0, 2, 128}192.0.2.1/0→{0, 0, 0, 0}2001:db8::1/32→{0x2001, 0x0db8, 0, 0, 0, 0, 0, 0}/999は 32 に丸めた後にマスク=実質マスク無し)dig +qrの出力と突き合わせて確認するのが確実。経緯
#86(prefix 長の検証)の作業中に
digの送信パケットを実測して判明した。prefix の検証とは独立した別の不具合なので、PR #87 のスコープからは外した。https://claude.ai/code/session_01YAjSJR67tWTvYDJLcQThbQ