192.168.1.2/24
インターフェースにeth0
が設定され、192.168.1.1
と192.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:~#
これは予想される動作ですか?カーネルがルーティングテーブルを無視するのはなぜですか?
ルーティングテーブルは正確に無視されていません。これは、優先度の高いルーティングテーブルによって却下されています。
_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 を試して、何ができるかいくつかの例を確認することもできます。
あなたのリバースパスフィルタリング設定がおそらく問題です。 RFC3704 -セクション2.4
エンタープライズLinuxディストリビューション(RHEL、CentOS、Scientific Linuxなど)では、これを解決する最良の方法は/etc/sysctl.conf
をrp_filter = 2
で変更することです。