Mam komputer (jądro 3.2.0-23-generic ), który 192.168.1.2/24
skonfigurował eth0
interfejs, a także używa 192.168.1.1
i 192.168.1.2
adresy tun0
interfejsu:
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:~#
Jak widać powyżej, tun0
administracyjnie jest wyłączony ( ip link set dev tun0 down
). Teraz, gdy otrzymuję żądania ARP 192.168.1.2
, komputer nie odpowiada na te żądania:
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:~#
Dopiero po usunięciu tun0
interfejsu ( ip link del dev tun0
) komputer odpowie na żądanie ARP 192.168.1.2
dotyczące eth0
interfejsu.
Tabela routingu wygląda dokładnie tak samo przed i po 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:~#
Poniższy wpis routingu został już usunięty za pomocą ip link set dev tun0 down
polecenia:
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
Jednak, chociaż tabele routingu są dokładnie takie same przed i po ip link del dev tun0
komendzie, rzeczywiste decyzje dotyczące routingu podejmowane przez jądro nie są:
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:~#
Czy to jest oczekiwane zachowanie? Dlaczego jądro ignoruje tablicę routingu?
źródło
tun0
interfejs jest wyłączony, ale obecny. Zobacz wynikiip route get
poleceń w moim zaktualizowanym początkowym poście. Dlaczego jednak jądro tak się zachowuje?Odpowiedzi:
Twoja tabela routingu nie jest dokładnie ignorowana. Zostaje zastąpione przez tablicę routingu o wyższym priorytecie.
Co się dzieje
Tabela routingu widoczna podczas pisania
ip route show
nie jest jedyną tabelą routingu używaną przez jądro. W rzeczywistości istnieją domyślnie trzy tabele routingu, które są przeszukiwane w kolejności pokazanej przezip rule
polecenie:Tabela, którą najbardziej znasz, to
main
tabela routingu o najwyższym priorytecielocal
. Tą tabelą zarządza jądro, aby śledzić trasy lokalne i rozgłaszania: innymi słowy,local
tabela informuje jądro, w jaki sposób należy kierować do adresów własnych interfejsów. Wygląda to mniej więcej tak:Sprawdź tę linię odniesienia
tun0
. To właśnie powoduje twoje dziwne wynikiroute get
. Mówi, że 192.168.1.1 to adres lokalny, co oznacza, że jeśli chcemy wysłać odpowiedź ARP na 192.168.1.1, jest to łatwe; wysyłamy to do siebie. A ponieważ znaleźliśmy trasę wlocal
tabeli, przestajemy szukać trasy i nie zawracamy sobie głowy sprawdzaniem tabelmain
lubdefault
.Dlaczego wiele stołów?
Przynajmniej miło jest móc pisać
ip route
i nie widzieć wszystkich tych „oczywistych” tras zaśmiecających ekran (spróbuj pisaćroute print
na komputerze z systemem Windows). Może również służyć jako minimalna ochrona przed błędną konfiguracją: nawet jeśli główna tablica routingu uległa pomyłce, jądro nadal wie, jak rozmawiać z samym sobą.(Po co przede wszystkim utrzymywać trasy lokalne? Jądro może używać tego samego kodu wyszukiwania dla adresów lokalnych, jak robi to we wszystkich innych przypadkach. Ułatwia to wewnętrznie).
Istnieją inne ciekawe rzeczy, które możesz zrobić z tym schematem wielu tabel. W szczególności możesz dodawać własne tabele i określać zasady ich przeszukiwania. Nazywa się to „routingiem zasad”, a jeśli kiedykolwiek chciałeś skierować pakiet na podstawie jego adresu źródłowego , oto jak to zrobić w Linuksie.
Jeśli robisz szczególnie trudne lub eksperymentalne rzeczy, możesz
local
samodzielnie dodawać lub usuwać trasy, określająctable local
wip route
poleceniu. Jeśli nie wiesz, co robisz, prawdopodobnie pomylisz jądro. I oczywiście jądro nadal będzie dodawać i usuwać własne trasy, więc musisz uważać, aby się nie nadpisać.Wreszcie, jeśli chcesz zobaczyć wszystkie tabele routingu na raz:
Aby uzyskać więcej informacji, sprawdź
ip-rule(8)
stronę podręcznika lub dokumenty iproute2 . Możesz także wypróbować Advanced Routing and Traffic Control HOWTO, aby uzyskać przykłady tego, co możesz zrobić.źródło
ip link set dev tun0 down
tym, jaklocal 192.168.1.1 dev tun0 proto kernel scope host src 192.168.1.1
reguła rzeczywiście była nadal obecna wlocal
tablicy routingu. Po wykonaniuip link del dev tun0
wspomniana reguła została usunięta. Nadal jedno pytanie - czy mam rację, że wszystkie współczesne jądra Linuksa (2.6.x, 3.x, 4.x) używają RPDB do wyszukiwania tras, a tym samym wielu tabel?ip(8)
: „ip
zostało napisane przez Alexeya N. Kuznetsofa i dodane w Linuksie 2.2.”Twój odwrotnego filtrowania ścieżka config jest chyba problem. RFC3704 - sekcja 2.4
W dystrybucjach Enterprise Linux (RHEL, CentOS, Scientific Linux i in.) Prawdopodobnie najlepszym sposobem na rozwiązanie tego problemu jest modyfikacja za
/etc/sysctl.conf
pomocąrp_filter = 2
https://access.redhat.com/solutions/53031
źródło
for rp_filter_file in /proc/sys/net/ipv4/conf/*/rp_filter; do echo 0 > "$rp_filter_file"; done
jądrem nie używameth0
interfejsu do routingu pakietów do 192.168.1.1. Dopiero gdy usunętun0
interfejs zip link del dev tun0
jądrem, zacznie korzystać zeth0
interfejsu.