ノート PC は Ethernet でオフィスの /24 に接続し、同時に同じ /24 に存在する OpenVPN サーバーにも参加しています。同僚がトンネルのアドレスに ping を送ると、要求は確かに届きますが、何も返ってきません。トンネルのログはきれいで、ブラウジングもまだ動くので、トンネルは誤った容疑者です。受信側マシンの IPv4 送信元検証が、何かが読む前にパケットを捨てています。

破棄は、何かがパケットを読む前に起きる

送信元検証は、入ってくるすべてのパケットに、このホストがその送信元に応答するなら応答はパケットが今到着したインターフェースから出るかという一つの問いを立てます。答えがいいえなら、カーネルは到着時にパケットを捨てます。ソケットも転送経路もそれを見ることはなく、だからこそトンネルでのキャプチャには、アプリケーションが決して受け取らない要求が記録されます。

ここのクライアントはトンネル上に 10.66.0.9 を持ち、OpenVPN サーバーはオフィスのプレフィックス内の 192.168.80.10 で応答します。192.168.80.25 の同僚がトンネルのアドレスに ping を送るので、要求は LAN を渡り、サーバーがトンネルへ送り、オフィスの送信元アドレスを載せてクライアントのトンネルインターフェースに届きます。そのマシンのルーティングテーブルでは、オフィスのプレフィックスは Ethernet デバイスに属し、トンネルには属しません。検証は到着インターフェースと経路を比べ、不一致を見つけてパケットを捨てるので、両端が健全なトンネルを報告する一方で、同僚には完全な損失が見えます。

鏡の方向も同じ形で、クライアントがオフィスへ向けて始めると、同じ理由でオフィス側で応答が捨てられることがあります。片方向だけで検証した修正は、たいてい二枚目のチケットとして戻ってきます。

sysctl に触る前に、有効なモードを証明する

インターフェースごとの設定は判断の半分にすぎないので、ディストリビューションの既定値を信じるのではなく実際の値を読み取ってください。有効なモードはインターフェースの値と all の値の高いほうなので、all が一である間はトンネルインターフェースのゼロに意味はありません。厳格モードの判断はルーティングの判断なので、カーネルが実行する検索を実行し、その答えをパケットが実際に到着したインターフェースと比べてください。

tcpdump -ni tun0 icmp and host 192.168.80.25
ip route get 192.168.80.25
sysctl net.ipv4.conf.all.rp_filter net.ipv4.conf.tun0.rp_filter

次に、エラーカウンターを見ながら ping を繰り返します。キャプチャがすでに示している要求の横で増える数は、この破棄の署名であり、欠けた経路のものではありません。そこにいる間に火星パケットのログを有効にすると、カーネルが拒否した送信元とインターフェースを名指しします。合わせて、暗号、ファイアウォール、欠けた iroute を説明から除外できます。

何かを変える前に、両方の値、検索が選んだデバイス、そして見ていたカウンターを基準線として書き留めてください。その記録が、あとで変更が思ったとおりになったかどうかを教えてくれます。

各 rp_filter モードが実際に何を受け入れるか

カーネルはインターフェースごとに三つの値を示し、それらは一つの規則の三つの濃淡ではありません。ゼロは検査を無効にします。一は厳格で、送信元が到着インターフェースから戻る経路を持つことを要求します。二は緩く、テーブルに送信元への経路がどこかへ向かって存在することだけを要求します。

ValueNameAcceptsStill rejects
0offany source at allnothing on this check
1stricta source routed back out the arrival interfacea source whose route points elsewhere
2loosea source with any route in the tablea source with no route at all

ここで重要な行は緩いほうであり、それが依然として拒むものです。テーブルのどこへでも経路のある偽の送信元は通り、経路がまったくない送信元は依然として拒まれます。ノート PC では狭い譲歩ですが、他人のトラフィックを転送するルーターでは広い譲歩です。モードはホストに属するので、同じ数が二つの場所で異なる重みを持ちます。

この構成がどの行を必要とするかは、習慣ではなくテーブルから決まります。パケットは正当で送信元に経路があるので、緩いほうは受け入れ、厳格なほうは受け入れません。この件でゼロを要するものはなく、ゼロを選べばここで何のコストもかからない検査を外すことになります。

曖昧さを取り除く最小の変更を選ぶ

緩いモードは適合する最小の変更であり、無害なスイッチではなく厳格さの実際の低下です。構成が許すならより良い選択肢があり、重なりを取り除けば曖昧さは消えます。

オフィスのプレフィックスが Ethernet 経由でしか要らないなら、プロファイルが引く経路から外せば、アドレスは一本の経路で到達可能になります。二つの経路が本当に共存しなければならないときは、すべてのインターフェースで検証を緩めるのではなく、ポリシールールで送信元とデバイスを固定してください。そうすればマシンの他のすべてには厳格なフィルタリングが残り、例外は次の技術者が探す場所に記録されます。

どの経路を選んでも、生きたコマンドではなく sysctl の drop-in に記録してください。all と default のキーを一緒に設定し、再接続が厳格モードを静かに戻せないようにします。

# /etc/sysctl.d/99-rp-filter.conf
net.ipv4.conf.default.rp_filter = 2
net.ipv4.conf.all.rp_filter = 2
sysctl --system

緩いモードが手放すもの、そしてその場所

緩いモードは、どの経路も届かない送信元を依然として拒み、たまたま経路のある偽の送信元を拒むのをやめます。ノート PC では狭い譲歩です。自分のものでないトラフィックを転送するデバイスでは、同じ選択ははるかに広い譲歩です。したがって同じ設定が、動く場所によって二つの非常に異なる意味を持ちます。

他人のためにトラフィックを転送するホストで検査を完全に切ることは、避けるべき唯一の修理です。ゼロは、緩いモードが注意深く保つ検証を捨てます。ホストが他人のために転送するなら、代わりに前の節のポリシールールの選択肢を主張してください。

二つのインターフェース、重なっているプレフィックス、そして今成功する正確な検査を名指ししたメモを残してください。それは、フィルタリングを調整したという一行よりも、次の技術者に役立ちます。

関連記事