web-dev-qa-db-ja.com

netcatがIPに関連付けられた適切なインターフェースを使用しないのはなぜですか?

  • 2つのネットワークインターフェースA 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
...
4
Alexis_FR_JP

アプリケーションに特定の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インターフェースを通過しなくなります。

11
Patrick

ネットワークインターフェイスは、自分ではなくネットワーク上の他のノードにパケットを送信するように設計されているため、ローカルアドレスへのアクセスには常にループバックインターフェイスが使用されます。

1
psusi

netcat-openbsd debianおよびopensdでは、使用するルーティングテーブルを選択できます。

オプションは-V

通常のnetcatでは、これは不可能だと思います。

Socatを使用すると、呼び出し時にそれを宣言する特定のインターフェースを使用できます。

0
cabonamigo