Назад | Перейти на главную страницу

как мне остановить отправку недоступных пакетов протокола 41?

Я использую туннель Hurricane Electric на одном из моих VPS, и он не работает полностью. Я настроил туннель с помощью сценария, в основном идентичного этому: http://www.cybermilitia.net/2013/07/22/ipv6-tunnel-on-openvz/, с изменениями только для моей конкретной настройки. Я могу проверить связь с сервером и получить с него веб-страницу, но я получаю следующий результат от ping6:

root@unixshell:~# ping6 -c4 2001:470:1f0e:12a7::2
PING 2001:470:1f0e:12a7::2(2001:470:1f0e:12a7::2) 56 data bytes
From 2002:d8da:e02a::1 icmp_seq=1 Destination unreachable: Address unreachable
64 bytes from 2001:470:1f0e:12a7::2: icmp_seq=1 ttl=63 time=96.4 ms
64 bytes from 2001:470:1f0e:12a7::2: icmp_seq=2 ttl=63 time=73.2 ms
From 2002:d8da:e02a::1 icmp_seq=2 Destination unreachable: Address unreachable

--- 2001:470:1f0e:12a7::2 ping statistics ---
2 packets transmitted, 2 received, +2 errors, 0% packet loss, time 1005ms
rtt min/avg/max/mdev = 73.256/84.838/96.420/11.582 ms

на проблемном сервере, запущенном tcpdump, я вижу это одновременно с приведенным выше:

root@tektonic:~# tcpdump -n not port 22
tcpdump: verbose output suppressed, use -v or -vv for full protocol decode
listening on venet0, link-type LINUX_SLL (Linux cooked), capture size 262144 bytes
21:25:44.000024 IP 216.218.224.42 > 207.210.83.205: IP6 2002:cfd2:4a7c::1 > 2001:470:1f0e:12a7::2: ICMP6, echo request, seq 1, length 64
21:25:44.000094 IP 207.210.83.205 > 216.218.224.42: ICMP 207.210.83.205 protocol 41 port 0 unreachable, length 132
21:25:44.000629 IP 207.210.83.205 > 216.218.224.42: IP6 2001:470:1f0e:12a7::2 > 2002:cfd2:4a7c::1: ICMP6, echo reply, seq 1, length 64
21:25:45.020972 IP 216.218.224.42 > 207.210.83.205: IP6 2002:cfd2:4a7c::1 > 2001:470:1f0e:12a7::2: ICMP6, echo request, seq 2, length 64
21:25:45.021059 IP 207.210.83.205 > 216.218.224.42: ICMP 207.210.83.205 protocol 41 port 0 unreachable, length 132
21:25:45.021260 IP 207.210.83.205 > 216.218.224.42: IP6 2001:470:1f0e:12a7::2 > 2002:cfd2:4a7c::1: ICMP6, echo reply, seq 2, length 64
^C
6 packets captured
6 packets received by filter
0 packets dropped by kernel

И вот соответствующая часть моей конфигурации iptables:

root@tektonic:~# iptables --list | egrep '41|ipv6'
ACCEPT     ipv6 --  anywhere             anywhere            
ACCEPT     ipv6 --  anywhere             anywhere

Я понимаю, что могу просто перестать отправлять сообщения о недоступности ICMP с помощью iptables, как упоминалось здесь: Отключить ответы ICMP о недоступности, однако это неоптимальное решение. Есть идеи о том, как устранить настоящую проблему, не копаясь в исходниках ядра?

Часть сообщения об ошибке "порт 0" - отвлекающий маневр. Пакет 6in4 - это просто пакет ipv6 с добавленным заголовком ipv4 и, следовательно, не имеет номера порта на уровне ipv4. Однако отправляемые пакеты ICMP имеют номер типа 3 и номер кода 3, что означает «порт недоступен», а не код 2, «протокол недоступен». Вот один из них:

12:15:51.011697 IP 207.210.83.205 > 216.218.224.42: ICMP 207.210.83.205 protocol 41 port 0 unreachable, length 132
    0x0000:  45c0 0098 8d6c 0000 4001 0f94 cfd2 53cd  E....l..@.....S.
    0x0010:  d8da e02a 0303 62fb 0000 0000 4500 007c  ...*..b.....E..|
    0x0020:  9157 4000 f829 145c d8da e02a cfd2 53cd  .W@..).\...*..S.
    0x0030:  6000 0000 0040 3a3b 2002 cfd2 4a7c 0000  `....@:;....J|..
    0x0040:  0000 0000 0000 0001 2001 0470 1f0e 12a7  ...........p....
    0x0050:  0000 0000 0000 0002 8000 aa6e 1022 0002  ...........n."..
    0x0060:  ad8a c355 ce94 0a00 0809 0a0b 0c0d 0e0f  ...U............
    0x0070:  1011 1213 1415 1617 1819 1a1b 1c1d 1e1f  ................
    0x0080:  2021 2223 2425 2627 2829 2a2b 2c2d 2e2f  .!"#$%&'()*+,-./
    0x0090:  3031 3233 3435 3637                      01234567

[обновление 2015-08-06] tb_userspace обновлен до версии 18, без изменений.

[обновление 2015-08-09] tb_userspace.c строка 163: sockv6 = socket(AF_INET, SOCK_RAW, IPPROTO_IPV6);, и lsof -c tb_userspace показывает, что сокет действительно создан: tb_usersp 6614 root 4u raw 0t0 1559059549 CD53D2CF:0029->00000000:0000 st=07

[обновление 2015-08-09 17:18 PDT] подтвердил, что такая же проблема существует в простом ядре без openvz:

jcomeau@unixshell:~$ ping6 2001:470:66:79d::2
PING 2001:470:66:79d::2(2001:470:66:79d::2) 56 data bytes
64 bytes from 2001:470:66:79d::2: icmp_seq=1 ttl=60 time=86.5 ms
From 2001:470:0:206::2 icmp_seq=1 Destination unreachable: Address unreachable
64 bytes from 2001:470:66:79d::2: icmp_seq=2 ttl=60 time=83.4 ms
From 2001:470:0:206::2 icmp_seq=2 Destination unreachable: Address unreachable
64 bytes from 2001:470:66:79d::2: icmp_seq=3 ttl=60 time=86.1 ms
From 2001:470:0:206::2 icmp_seq=3 Destination unreachable: Address unreachable
^C
--- 2001:470:66:79d::2 ping statistics ---
3 packets transmitted, 3 received, +3 errors, 0% packet loss, time 2012ms
rtt min/avg/max/mdev = 83.429/85.376/86.556/1.427 ms

jcomeau@unixshell:~$ logout
Connection to www closed.
jcomeau@aspire:~$ uname -a
Linux aspire 3.2.0-4-amd64 #1 SMP Debian 3.2.54-2 x86_64 GNU/Linux

также очистил iptables и ip6tables и удалил все модули netfilter. тот же симптом.

[обновление 2015-08-11 01:04] от http://linux.die.net/man/7/raw обнаружил, что после того, как необработанный пакет был отправлен в любые необработанные сокеты, ядро ​​по-прежнему будет передавать его любым модулям, зарегистрированным для этого протокола. модуль на моем собственном нетбуке, который представляет собой "сырое ядро ​​без openvz", на котором я тестировал, был tunnel4. как только я удалил его, сообщения о недоступности места назначения прекратились. Я предполагаю, что тот же модуль встроен в монолитное ядро ​​моего VPS. / proc / kallsyms на нем не существует, поэтому мне придется обратиться в службу поддержки.

[обновление 2015-08-11 01:50] http://www.haifux.org/lectures/217/netLec5.pdf это ресурс, который тоже помог.

как отмечено в обновлениях к вопросу, проблема в том, что после того, как ядро ​​передает пакет любым необработанным сокетам, прослушивающим этот протокол, оно затем передает это любому модули ядра зарегистрирован для того же протокола. поскольку я использовал сидячий туннель на моем нетбуке, модуль tunnel4 все еще был загружен, хотя я временно настроил туннель tb_userspace для тестирования; поэтому, поскольку он был зарегистрирован, но обработчики не были настроены, он отклонял пакеты с сообщением ICMP 3: 3. rmmod sit с последующим rmmod tunnel4 решено который проблема.

на исходном проблемном сервере это было не так просто, поскольку это openvz VPS с монолитным ядром, как это видно «ящикам» клиента. но вооруженный информацией из http://linux.die.net/man/7/raw и http://www.haifux.org/lectures/217/netLec5.pdf Я смог работать с провайдером, чтобы решить проблему. в этом случае они переустановили модуль sit, поэтому мне вообще не пришлось использовать туннельное программное обеспечение tb_userspace. но я подозреваю, что проблема заключалась в том, что там тоже был установлен tunnel4.

Ошибки ICMP отправляются ядром, потому что не существует сокета для приема пакетов протокола 41 с этой конкретной комбинацией IP-адреса источника и назначения.

Если процесс создает необработанный сокет с протоколом 41, то ядро ​​перестанет генерировать ошибки ICMP. Такой сокет по умолчанию будет получать пакеты со всех исходных IP-адресов, отправленных на любой IP-адрес назначения, назначенный локальному компьютеру. Используя системный вызов bind и / или connect, приложение может ограничить, какую комбинацию IP-адреса источника и назначения оно будет получать. Пакеты, не соответствующие ни одному из таких сокетов, по-прежнему будут вызывать ошибки ICMP.

Понятно, что в вашем случае пакеты одновременно принимаются туннелем и вызывают ошибки ICMP. Но согласно моему описанию выше, пакет, полученный сокетом, не может также выдавать сообщение об ошибке ICMP. Но есть и другие способы получения пакета, которые не мешают ядру создавать ошибки ICMP.

Сокет может получать пакеты на более низком уровне протокола, где все пакеты будут видны независимо от номера IP-протокола. Если программное обеспечение туннеля, которое вы используете, использует такой низкоуровневый сокет для приема пакетов протокола 41, то будут возникать ошибки ICMP, как описано в вашем вопросе.

Если это то, что делает программное обеспечение туннеля, я бы счел это недостатком конструкции в программном обеспечении туннеля. В этом случае у вас есть три варианта:

  • Обходите недостаток, фильтруя пакеты (например, используя iptables).
  • Получите исходный код программного обеспечения и исправьте ошибку дизайна.
  • Переключитесь на другое программное обеспечение без этого конструктивного недостатка.

Похоже, что tektonic не имеет адреса 2001: 470: 1f0e: 12a7 :: 2, назначенного его интерфейсу venet0. Он принимает пакеты и отклоняет их, даже если они правильно сформированы.

Следующим шагом необходимо убедиться, что tektonic может устанавливать TCP-соединения с хостами только для IPv6, такими как ipv6.google.com, и что пакеты действительно отправляются на настроенный релейный хост Hurricane Electric через инкапсуляцию IPv4. Если TCP проходит, а ICMP - нет, то это определенно проблема фильтрации конечных точек (то есть правила брандмауэра).