偶然、これがip rule add from 0.0.0.0/8 unreachable
ネットワークを壊すことを発見しました。同じLANでpingを実行しても機能しません。理由がわからない。
0.0.0.0/8
IPv4アドレスブロックは予約されており、実際のIPを見つけるためにDHCPなどを使用するシステムでのみ使用できることを覚えておいてください。これは私の場合ではなく、すべてのホストが静的に設定されます。住所が表示される行はまったく期待できませんでした0.0.0.0
。 DHCP を使用しても、これらのパケットは現在 LAN に制限され、ルーティングされません。
それでは、このルールが通常のトラフィックを妨げるのはなぜですか?
答え1
ソケットが接続されたとき(例:connect(2)
システムコールを使用して、IPv4宛先として次のことを実行できます。
誰でも
bind(2)
接続する前に特定のアドレスに移動してくださいまたは、バインドされていないことはバインディングと同じです。INADDR_ANY別名0.0.0.0は、使用する実際のソースアドレスが決定されるまでプレースホルダとして使用されます。
多くの場合、さまざまなルーティングエントリがソースアドレスを0.0.0.0に維持できないため、最終的にソースアドレスが何であるかを判断します。ソースコードルートエントリのパラメータ、またはこのルート用に選択されたインターフェイスのベースアドレス。
しかし、追加のルーティングのためルール(from 0.0.0.0/32 unreachable
同じ結果が出ることもあります。)テーブル内の初期パスの検索基本決して起こらない:
$ ip rule
0: from all lookup local
32765: from 0.0.0.0/8 unreachable
32766: from all lookup main
32767: from all lookup default
ルーティングルールの巡回は、エントリ優先度32765で停止し、そのエントリを探す次のエントリには到達しない。基本ルーティングテーブル。このルーティングルールを追加する前に、送信元アドレスが物理アドレスに更新され、進行中のトラフィックがまだ正常に機能していたため、バインドされたソケットなしでバインドされたソケット(設定された接続を含む)のみが開始されました。
たとえば、システムインタフェースのアドレスが192.0.2.2/24であるとします。イーサネット0、5555/tcp でリッスンするサービスから 192.0.2.1 に接続しようとします。
socat tcp4:192.0.2.1:5555 -
これで、このパスの検索が失敗するため失敗します。
$ ip route get to 192.0.2.1
RTNETLINK answers: Network is unreachable
(と同じip route get from 0.0.0.0 to 192.0.2.1
)
偽のルーティングルールにもかかわらず、まず192.0.2.2に明示的にバインドすると成功します。
socat tcp4:192.0.2.1:5555,bind=192.0.2.2 -
同じ理由で、このルート検索はまだ成功します。
$ ip route get from 192.0.2.2 to 192.0.2.1
192.0.2.1 from 192.0.2.2 dev eth0 uid 1000
cache
これ~からソースが追加のルーティングルールと一致しません。
偽のルーティングルールが最初に存在しない場合、最初の例は成功し、後で追加すると、接続されたソケットはもはや偽のルーティングルールの影響を受けません。 0.0.0.0アドレスは、この接続のすべてのルックアップに表示されなくなります。 。
カーネルソースにはいくつかの明確な答えがありますが、それを徹底的に追いつくことは私の能力から少し逸脱しました。connect(2)
そうでない場合は、次のように言うことができますbind(2)
。
connect(2)
やっぱり使うip_route_connect()
(たとえば、カーネルでは:伝送制御プロトコルまたはUDPまたは生場合...) 0.0.0.0をワイルドカードソースアドレスとして使用して、パスと実際のソースを決定します。しかし、偽のルーティングルールを追加した後、
ip_route_connect()
最終的には次のようになります。fib_rules_lookup()
これは0.0.0.0ソースと一致します。アクセスできないルールがconnect(2)
失敗します。