1.2.3.4
2つのネットワークインターフェイスAと1.2.3.99
Bがあります。 (存在するifconfig
)nc -l 1.2.3.99 20101 -v
Bインターフェースを監視するために走りました。nc -v 1.2.3.99 20101 -s 1.2.3.4 -4
インターフェースを使いたくて走りましたA
。
接続はされていますが確認してみると、から来るパケットwireshark
はなく、ただ…A
B
lo
接続されたIPとインターフェイスを使用しないのはなぜですか?関連インターフェイスを強制的に使用するにはどうすればよいですか?
編集する:
Patrickのアドバイスに従ってください:
ip route add local 1.2.3.99 dev B table main
ip route del local 1.2.3.99 dev B table local
ip route add 1.2.3.99 dev B table local
実行しましたが、nc -l 1.2.3.99 20101
TCPサーバーを作成するとエラーが発生します。Ncat: bind to 1.2.3.99:20101: Cannot assign requested address. QUITTING.
17:10:38 alexis:~ $ ip route list table local
1.2.3.99 dev B scope link
...
17:10:40 alexis:~ $ ip route list table main
default via 10.133.0.1 dev eth0
local 1.2.3.99 dev B scope host
...
答え1
特定のIPアドレスを使用するようにアプリケーションに指示すると、アプリケーションはIPアドレスの使用、インターフェイスではなく。一部のアプリでは特定のインターフェースを使用できますが、これは別の操作です(SO_BINDTODEVICE)。
アプリケーションはインターフェイスではなく IP アドレスにバインドされているため、カーネルは必要なインターフェイスを自由に使用できます。使用するインターフェイスを決定するために、ルーティングテーブルを使用します(たとえば、いくつかあります)。
どのインターフェイス/パストラフィックがかかるかをすばやく判断する方法が必要な場合は、ip route get 1.2.3.99 from 1.2.3.4
次の結果を出力することができます。
# ip route get 1.2.3.99 from 1.2.3.4
local 1.2.3.99 from 1.2.3.4 dev lo
cache <local>
これは、カーネルがインターフェイスlo
を介してトラフィックを送信することを示します。
理由を理解するために、次のコマンドから始めましょうip rule
。
# ip rule
0: from all lookup local
32766: from all lookup main
32767: from all lookup default
これには、カーネルがトラフィックパスを見つけるために使用するすべてのルーティングテーブルが表示されます。一番上から始まり、最初の一致で停止します。from all
ルールがすべての送信元アドレスと一致することを示します。だから最初にテーブルをチェックしてみてくださいlocal
。それから私達はこのテーブルを見ることができます:
# ip route show table local
broadcast 127.0.0.0 dev lo proto kernel scope link src 127.0.0.1
local 127.0.0.0/8 dev lo proto kernel scope host src 127.0.0.1
local 127.0.0.1 dev lo proto kernel scope host src 127.0.0.1
broadcast 127.255.255.255 dev lo proto kernel scope link src 127.0.0.1
broadcast 1.2.3.0 dev eth0 proto kernel scope link src 1.2.3.4
local 1.2.3.4 dev eth0 proto kernel scope host src 1.2.3.4
broadcast 1.2.3.255 dev eth0 proto kernel scope link src 1.2.3.4
local 1.2.3.99 dev eth1 proto kernel scope host src 1.2.3.99
(あなたの姿は異なる場合があります)
次に、宛先が2番目のフィールドと一致することを確認して、宛先アドレス(1.2.3.99)と一致するパスがあることを確認します。上記の出力では、最後の出力が一致します。この行の最初のフィールドはでlocal
あり、そのman ip-route
意味は次のとおりです。
ローカル - 宛先がこのホストに割り当てられます。パケットはループバックされ、ローカルに転送されます。
これは、トラフィックがそのインターフェイスを通過することを意味しますlo
。
A
/インターフェースの使用方法にはB
2つのオプションがあります。
1)アプリケーションは、インターフェースを指定するためのパラメーターを提供する必要があります。 netcatにはさまざまな種類がありますが、私のシステムバージョンにはそのようなオプションはありません。しかし、それは本当です。 (netcatの不一致と移植性は悪夢であるため、socat
個人的にnetcatを使用することをお勧めします。さらに強力です)。socat
2)local
前のパスと一致する非パスを作成しますlocal
。
ip route add local 1.2.3.99 dev B table main
ip route del local 1.2.3.99 dev B table local
ip route add 1.2.3.99 dev B table local
このルールの最初の2つはlocal
パスをテーブルに移動しますmain
。カーネルがそのアドレスへのトラフィックを許可するには、main
ホストにどこかにパスが必要であるため、ルートを最初にテーブルに追加する必要があります。local
パスを2つのテーブルに入れます。その後、指定されていないテーブルに新しいルートをlocal
追加すると、local
トラフィックがそのインターフェイスを通過できなくなりますlo
。
答え2
debianとopensdでは、netcat-openbsd
使用するルーティングテーブルを選択できます。
オプションはです-V
。
日常的なケースではnetcat
これは不可能だと思います。
socatを使用すると、呼び出し時に宣言される特定のインターフェースを使用できます。
答え3
ネットワークインタフェースは、自身ではなく回線上の他のノードにパケットを送信するように設計されているため、ローカルアドレスへのアクセスは常にループバックインタフェースを使用します。
答え4
簡単な答え
Linuxカーネルには2つのパケットキューがあります。 1つはパケット転送用で、もう1つはパケット受信用です。
カーネルが決定します(ルーティングテーブルと宛先アドレスに基づいてどのNICパケットが物理的に到着するか)。
ただし、カーネルが宛先IPアドレスが送信元IPと同じホストにあることを発見した場合、このパケットを1つのNICから物理的に送信し、別のNICから受信することは意味がありません。これは過剰であり、時間とリソースの無駄です。したがって、カーネルは送信キューからパケットを挿入または削除し、それを受信キューに入れます。これはすべて疑似ネットワークカードを使用するカーネルで発生します。 ループバック相互作用lo
。
簡単なスキームで、パケットを受信するための別のキューがあるとしましょう。