Грешен ICMP redirect при ping — защо и как се оправя
Когато на един физически интерфейс има вдигнати две мрежи и се изпълни ping от едната към другата, ICMP показва грешен redirect message — ping връща следващ хоп, който няма как да е верен:
$ ping 192.168.0.1
PING 192.168.0.1 (192.168.0.1) 56(84) bytes of data.
64 bytes from 192.168.0.1: icmp_seq=1 ttl=254 time=3.41 ms
From 192.168.85.1 icmp_seq=2 Redirect Host(New nexthop: 44.85.168.192)
64 bytes from 192.168.0.1: icmp_seq=2 ttl=254 time=3.75 ms
Адресът 44.85.168.192 не съществува никъде в мрежата. Забележете обаче кое е: това са същите байтове като 192.168.85.44, само в обратен ред.
Какво всъщност се случва
ICMP redirect е нормално и полезно съобщение. Рутерът казва: „за този адрес не минавай през мен, съседът ти е по-пряк път“. Получава се точно в тази ситуация — пакетът влиза и излиза през същия интерфейс, значи има по-къс маршрут.
Грешното число не идва от мрежата, а от ping. В съвременните дистрибуции непривилегированият ping вече не е SUID и не отваря RAW сокет, а ползва ICMP datagram сокет. При този режим адресът в тялото на redirect съобщението се чете с грешен ред на байтовете и се отпечатва обърнат. Самият redirect е верен — сбъркан е само изходът на екрана.
Поправката
Ключът ping_group_range определя кои групи могат да ползват ICMP datagram сокети. Стойност 1 0 е празен диапазон — тоест никоя група не може, и ping се връща към стария начин с RAW сокет:
sudo sysctl -w net.ipv4.ping_group_range='1 0'
Или направо:
sudo su
echo '1 0' > /proc/sys/net/ipv4/ping_group_range
Резултатът веднага е с правилния адрес:
$ sudo ping 192.168.0.1
PING 192.168.0.1 (192.168.0.1) 56(84) bytes of data.
64 bytes from 192.168.0.1: icmp_seq=1 ttl=254 time=3.17 ms
From 192.168.85.1: icmp_seq=2 Redirect Host(New nexthop: 192.168.85.44)
64 bytes from 192.168.0.1: icmp_seq=2 ttl=254 time=3.79 ms
За да важи след рестарт, редът net.ipv4.ping_group_range = 1 0 се добавя в /etc/sysctl.conf и се презарежда със sudo sysctl -p.
⚠️ Странична последица: след тази промяна ping иска права. Ако в момента работи за обикновен потребител без sudo, ще спре да работи — освен ако двоичният файл няма cap_net_raw. Проверява се с getcap $(which ping).
По-важният въпрос: приемате ли изобщо redirect-и
Косметиката на изхода е едно, а поведението — друго. ICMP redirect променя маршрутната таблица на машината по нареждане отвън. В локална мрежа, на която се доверявате, това е удобство. На сървър с публичен адрес е вектор за атака: подправено redirect съобщение пренасочва трафика ви през чужда машина.
Затова на сървър се изключва изцяло:
net.ipv4.conf.all.accept_redirects = 0
net.ipv4.conf.default.accept_redirects = 0
net.ipv4.conf.all.secure_redirects = 0
А ако машината е рутер, се спира и изпращането им:
net.ipv4.conf.all.send_redirects = 0
Текущото състояние се проверява така:
sysctl -a 2>/dev/null | grep redirect
Тоест: ако виждате redirect съобщения при ping в собствената си мрежа — това е нормално и говори за две мрежи на един интерфейс. Ако ги виждате на сървър, изложен към интернет, въпросът не е защо адресът се показва обърнат, а защо машината изобщо ги приема.