web-dev-qa-db-ja.com

要求されたIPアドレスが別の(無効な)インターフェースに関連付けられている場合、LinuxはARP要求メッセージに応答しません

192.168.1.2/24インターフェースにeth0が設定され、192.168.1.1192.168.1.2も使用するPC(kernel .2.0-23-generic)がありますtun0インターフェースのアドレス:

root@T42:~# ip addr show
1: lo: <LOOPBACK,UP,LOWER_UP> mtu 16436 qdisc noqueue state UNKNOWN
    link/loopback 00:00:00:00:00:00 brd 00:00:00:00:00:00
    inet 127.0.0.1/8 scope Host lo
    inet6 ::1/128 scope Host
       valid_lft forever preferred_lft forever
2: eth0: <BROADCAST,MULTICAST,UP,LOWER_UP> mtu 1500 qdisc pfifo_fast state UP qlen 1000
    link/ether 00:16:41:54:01:93 brd ff:ff:ff:ff:ff:ff
    inet 192.168.1.2/24 scope global eth0
    inet6 fe80::216:41ff:fe54:193/64 scope link
       valid_lft forever preferred_lft forever
3: bond0: <BROADCAST,MULTICAST,MASTER> mtu 1500 qdisc noop state DOWN
    link/ether 00:00:00:00:00:00 brd ff:ff:ff:ff:ff:ff
4: irda0: <NOARP> mtu 2048 qdisc noop state DOWN qlen 8
    link/irda 00:00:00:00 brd ff:ff:ff:ff
5: eth1: <BROADCAST,MULTICAST,UP,LOWER_UP> mtu 1500 qdisc pfifo_fast state UP qlen 1000
    link/ether 00:13:ce:8b:99:3e brd ff:ff:ff:ff:ff:ff
    inet 10.30.51.53/24 brd 10.30.51.255 scope global eth1
    inet6 fe80::213:ceff:fe8b:993e/64 scope link
       valid_lft forever preferred_lft forever
6: tun0: <POINTOPOINT,MULTICAST,NOARP> mtu 1500 qdisc pfifo_fast state DOWN qlen 100
    link/none
    inet 192.168.1.1 peer 192.168.1.2/32 scope global tun0
root@T42:~# ip route show dev eth0
192.168.1.0/24  proto kernel  scope link  src 192.168.1.2 
root@T42:~# 

上記のように、tun0は管理上無効になっています(ip link set dev tun0 down)。 192.168.1.2のARPリクエストを受信して​​も、PCはそれらのリクエストに応答しません。

root@T42:~# tcpdump -nei eth0
tcpdump: verbose output suppressed, use -v or -vv for full protocol decode
listening on eth0, link-type EN10MB (Ethernet), capture size 65535 bytes
15:30:34.875427 00:1a:e2:ae:cb:b7 > ff:ff:ff:ff:ff:ff, ethertype ARP (0x0806), length 60: Request who-has 192.168.1.2 tell 192.168.1.1, length 46
15:30:36.875268 00:1a:e2:ae:cb:b7 > ff:ff:ff:ff:ff:ff, ethertype ARP (0x0806), length 60: Request who-has 192.168.1.2 tell 192.168.1.1, length 46
15:30:39.138651 00:1a:e2:ae:cb:b7 > 00:1a:e2:ae:cb:b7, ethertype Loopback (0x9000), length 60:
^C
3 packets captured
3 packets received by filter
0 packets dropped by kernel
root@T42:~#

tun0インターフェイス(ip link del dev tun0)を削除した後にのみ、PCは192.168.1.2インターフェイス上のeth0のARP要求に応答します。

ルーティングテーブルはip link del dev tun0の前後でまったく同じように見えます。

root@T42:~# netstat -rn
Kernel IP routing table
Destination     Gateway         Genmask         Flags   MSS Window  irtt Iface
0.0.0.0         10.30.51.254    0.0.0.0         UG        0 0          0 eth1
10.30.51.0      0.0.0.0         255.255.255.0   U         0 0          0 eth1
192.168.1.0     192.168.1.2     255.255.255.0   UG        0 0          0 eth0
root@T42:~# ip link del dev tun0
root@T42:~# netstat -rn
Kernel IP routing table
Destination     Gateway         Genmask         Flags   MSS Window  irtt Iface
0.0.0.0         10.30.51.254    0.0.0.0         UG        0 0          0 eth1
10.30.51.0      0.0.0.0         255.255.255.0   U         0 0          0 eth1
192.168.1.0     192.168.1.2     255.255.255.0   UG        0 0          0 eth0
root@T42:~# 

以下のルーティングエントリは、ip link set dev tun0 downコマンドで既に削除されています。

Destination     Gateway         Genmask         Flags   MSS Window  irtt Iface
192.168.1.2     0.0.0.0         255.255.255.255 UH        0 0          0 tun0

ただし、ルーティングテーブルはip link del dev tun0コマンドの前後でまったく同じですが、カーネルが行う実際のルーティング決定は次のとおりではありません。

T42:~# ip route get 192.168.1.1
local 192.168.1.1 dev lo  src 192.168.1.1 
    cache <local> 
T42:~# ip link del dev tun0
T42:~# ip route get 192.168.1.1
192.168.1.1 dev eth0  src 192.168.1.2 
    cache  ipid 0x8390
T42:~# 

これは予想される動作ですか?カーネルがルーティングテーブルを無視するのはなぜですか?

9
Martin

ルーティングテーブルは正確に無視されていません。これは、優先度の高いルーティングテーブルによって却下されています。

どうしたの

_ip route show_を入力したときに表示されるルーティングテーブルは、カーネルが使用する唯一のルーティングテーブルではありません。実際、デフォルトでは3つのルーティングテーブルがあり、_ip rule_コマンドで表示される順序で検索されます。

_# ip rule show
0:      from all lookup local
32766:  from all lookup main
32767:  from all lookup default
_

最もよく知っているテーブルはmainですが、最も優先度の高いルーティングテーブルはlocalです。このテーブルは、ローカルルートとブロードキャストルートを追跡するためにカーネルによって管理されます。つまり、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 192.168.1.0 dev eth0  proto kernel  scope link  src 192.168.1.2
local 192.168.1.1 dev tun0  proto kernel  scope Host  src 192.168.1.1
local 192.168.1.2 dev eth0  proto kernel  scope Host  src 192.168.1.2
broadcast 192.168.1.255 dev eth0  proto kernel  scope link  src 192.168.1.2
_

_tun0_を参照するその行を確認してください。それが_route get_の奇妙な結果の原因です。 192.168.1.1はローカルアドレスです。つまり、ARP応答を192.168.1.1に送信するのは簡単です。私たちはそれを自分に送ります。また、localテーブルでルートを見つけたので、ルートの検索を停止し、mainまたはdefaultテーブルをチェックする手間を省きます。

なぜ複数のテーブルなのですか?

少なくとも、_ip route_と入力して、表示が雑然とする「わかりやすい」ルートをすべて表示できないのはいいことです(Windowsマシンで_route print_と入力してみてください)。また、設定ミスに対する最小限の保護としても機能します。メインのルーティングテーブルが混同された場合でも、カーネルは自分自身と通信する方法を知っています。

(なぜローカルルートを最初にしておくのですか?カーネルはローカルアドレスに対して他のものと同じように同じルックアップコードを使用できます。それは物事を内部的に単純化します。)

この複数テーブルスキームで実行できる他の興味深いことがいくつかあります。特に、独自のテーブルを追加し、それらが検索されるときのルールを指定できます。これは「ポリシールーティング」と呼ばれ、sourceアドレスに基づいてパケットをルーティングしたい場合、これを行う方法は次のとおりです。 Linux。

特にトリッキーまたは実験的なことをしている場合は、_table local_コマンドで_ip route_を指定することにより、localルートを自分で追加または削除できます。しかし、自分が何をしているのかを知らない限り、カーネルを混乱させる可能性があります。そしてもちろん、カーネルは引き続き独自のルートを追加および削除するため、ルートが上書きされないように注意する必要があります。

最後に、すべてのルーティングテーブルを一度に表示する場合:

_# ip route show table all
_

詳細については、 ip-rule(8) のマニュアルページまたは iproute2 docs を確認してください。また、 高度なルーティングとトラフィック制御のHOWTO を試して、何ができるかいくつかの例を確認することもできます。

17
Jander

あなたのリバースパスフィルタリング設定がおそらく問題です。 RFC3704 -セクション2.4

エンタープライズLinuxディストリビューション(RHEL、CentOS、Scientific Linuxなど)では、これを解決する最良の方法は/etc/sysctl.confrp_filter = 2で変更することです。

RHELに複数のIPが構成されている場合、リモートネットワークから到達可能なIPは1つだけです。または、送信トラフィックのルートが受信トラフィックのルートと異なる場合、RHELがパケットを無視するのはなぜですか?

1
0xSheepdog