1.2.3.4
およびB 1.2.3.99
。 (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のインターフェイスを使用しないのはなぜですか?関連するインターフェイスを使用するように強制するにはどうすればよいですか?
編集:
パトリックのアドバイスに従ってください:
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
...
アプリケーションに特定の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がありますが、私のシステムのバージョンにはそのようなオプションはありません。 socat
はそうします(netcatは不整合と移植性の悪夢なので、個人的には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
インターフェースを通過しなくなります。
ネットワークインターフェイスは、自分ではなくネットワーク上の他のノードにパケットを送信するように設計されているため、ローカルアドレスへのアクセスには常にループバックインターフェイスが使用されます。
netcat-openbsd
debianおよびopensdでは、使用するルーティングテーブルを選択できます。
オプションは-V
。
通常のnetcat
では、これは不可能だと思います。
Socatを使用すると、呼び出し時にそれを宣言する特定のインターフェースを使用できます。