Недоступны некоторые сайты. Вечное ожидание ответа. (Статья о Path MTU Discovery Black Hole.)

Обсуждение настройки и работы сервисов, резервирования, сетевых настроек и вопросов безопасности ОС.

Модератор: SLEDopit

Ответить
Аватара пользователя
Alex2ndr
Сообщения: 443
ОС: Debian Lenny

Недоступны некоторые сайты. Вечное ожидание ответа.

Сообщение Alex2ndr »

Я долго собирался и вот наконец-то написал статью об этой проблеме. Она часто встречается на форуме, например тут , тут и тут (и еще много где). Возможно модераторам стоит прикрепить эту тему.

Несколько слов о Path MTU Discovery Black Hole.


Автор: Попов Александр ( popov2al<at>gmail.com )

Вместо вступления
Однажды для каждого настоящего системного администратора (или исполняющего обязанности такового) наступает момент истины. Ему выпадает судьба настроить маршрутизатор на компьютере с установленной ОС GNU/Linux. Те, кто это уже прошел, знают, что ничего сложного в этом нет и можно уложиться в пару команд. И вот наш админ находит эти команды, вбивает их в консоль и гордо идет к пользователям сказать, что уже все работает. Но не тут-то было – пользователи говорят что их любимые сайты не открываются. После траты некоторой части своей жизни на выяснение подробностей обнаруживается, что большая часть сайтов ведет себя следующим образом:
1. При открытии страницы загружается заголовок и больше ничего;
2. В таком состоянии страница висит неопределенно долгое время;
3. Строка статуса браузера все это время показывает что загружает страницу;
4. Пинги и трассировка до данного сайта проходят нормально;
5. Соединение по telnet на 80 порт тоже проходит нормально.
Обескураженный админ звонит в техподдержку провайдера, но там от него быстро избавляются, советуя попробовать настроить маршрутизатор на OC Windows, а если уж и там не работает тогда... - купить аппаратный маршрутизатор :-) .
Я думаю, эта ситуация знакома многим. Некоторые в нее попадали сами, у кого-то с ней сталкивались знакомые, а кто-то встречал таких админов на форумах и прочих конференциях. Итак : если у Вас Такая Ситуация, то - Поздравляю! Вы столкнулись с Path MTU Discovery Black Hole. Данная статья посвящается тому, отчего это бывает, и как решить эту проблему.

Термины, необходимые для понимания содержимого статьи:
MTU (Maximum Transmission Unit) – этот термин используется для определения максимального размера пакета (в байтах), который может быть передан на канальном уровне сетевой модели OSI. Для Ethernet это 1500 байт. Если приходит пакет большего размера (например по Token Ring), то данные пересобираются в пакеты размером не более MTU( т е не более 1500 байт). Операция пересборки пакетов под другой MTU называется фрагментацией(fragmentation) и считается затратной для маршрутизатора.
PMTU (Path MTU) - данный параметр обозначает наименьший MTU любого канала данных, находящегося между источником и приемником.
PMTU discovery – технология определения PMTU разработанная для уменьшения нагрузки на маршрутизаторы. Описана в RFC 1191(http://tools.ietf.org/html/rfc1191) в 1988 году. Суть технологии заключается в том, что при соединении двух хостов устанавливается параметр DF (don’t fragment, не фрагментировать), который запрещает фрагментацию пакетов. Это приводит к тому, что узел, значение MTU которого меньше размера пакета, отклоняет передачу пакета и отправляет сообщение ICMP типа Destination is unreachable (Хост недоступен). К сообщению об ошибке прилагается значение MTU узла. Хост-отправитель уменьшает размер пакета и отсылает его заново. Такая операция происходит до тех пор, пока пакет не будет достаточно мал, чтобы дойти до хоста-получателя без фрагментации.
МSS(Maximum Segment Size) - максимальный размер сегмента, т.е. самая большая порция данных, которую TCP пошлет на удаленный другой конец соединения. Рассчитывается по следующей формуле:
[MTU интерфейса] – [Размер IP заголовка(20 байт)] – [Размер TCP заголовка(20 байт)]. Итого обычно это 1460 байт. Когда соединение устанавливается, каждая сторона может объявить свой MSS. Выбирается наименьшее значение. Подробнее смотреть здесь - http://www.cyberguru.ru/networks/protocols...tion-page3.html
Флаг DF(Don't fragment) – Бит в поле флагов заголовка IP пакета, который будучи установленным в единицу сообщает о том, что данный пакет запрещено фрагментировать. Если пакет с таким флагом больше, чем MTU следующей пересылки, то этот пакет будет отброшен, а отправителю посылается ICMP ошибка "фрагментация необходима, однако установлен бит не фрагментировать" (fragmentation needed but don't fragment bit set).

Для начала посмотрим, что происходит в сети при открытии страницы. Для этого я создал тестовую сеть, изображенную на рис.1

ris_4.jpeg

Рис. 1. Схема тестовой сети.


Это упрощенный вариант глобальной сети. Компьютер с именем deb-serv-03 представляет собой наш маршрутизатор на Linux; deb-serv-05 – клиент в локальной сети(); deb-home – маршрутизатор, расположенный у провайдера; deb-serv – Веб-сервер в Интернете с которым мы хотим обмениваться данными(получаем с www.site.local страничку размером в 5,9Кб). Конечно, в реальности цепочка гораздо больше, но для показательного примера этого хватит. Все компьютеры данной сети работают под управлением Debian GNU/Linux 5.0 Lenny. В разных точках сети я контролирую ситуацию с помощью программы tcpdump.
Внимание – на интерфейсе eth2 компьютера deb-serv-03 размер MTU уменьшен до 1400 байт.

Изучаем, как пойдут пакеты при получении странички с веб-сервера. Смотрим на вывод TCPDUMP#1 (на eth0 deb-serv):

Код: Выделить всё

1    IP 172.16.5.3.48547 > 192.168.0.1.80: Flags [S], seq 2947128725, win 5840, options [mss 1460...], length 0
2    IP 192.168.0.1.80 > 172.16.5.3.48547: Flags [S.], seq 757312786, ack 2947128726, win 5792, options [mss 1460...], length 0
3    IP 172.16.5.3.48547 > 192.168.0.1.80: Flags [.], ack 1, win 1460, options [...], length 0
4    IP 172.16.5.3.48547 > 192.168.0.1.80: Flags [P.], seq 1:118, ack 1, win 1460, options [...], length 117
5    IP 192.168.0.1.80 > 172.16.5.3.48547: Flags [.], ack 118, win 181, options [...], length 0
6    IP 192.168.0.1.80 > 172.16.5.3.48547: Flags [.], seq 1:2897, ack 118, win 181, options [...], length 2896
7    IP 172.16.250.2 > 192.168.0.1: ICMP 172.16.5.3 unreachable - need to frag (mtu 1400), length 556
8    IP 192.168.0.1.80 > 172.16.5.3.48547: Flags [.], seq 1:1349, ack 118, win 181, options [...], length 1348
9    IP 192.168.0.1.80 > 172.16.5.3.48547: Flags [.], seq 1349:2697, ack 118, win 181, options [...], length 1348
10    IP 172.16.250.2 > 192.168.0.1: ICMP 172.16.5.3 unreachable - need to frag (mtu 1400), length 556

Я привожу только первые 10 пакетов и убрал неважные для данного примера опции. Разбираем:
1. В строках с 1-ой по 3-ю мы видим установку tcp соединения. Стороны обмениваются пакетами SYN, SYN-ACK, ACK. Здесь стоит обратить внимание на поле опций, а именно на параметр MSS, которым обмениваются стороны. С обеих сторон это 1460 байт. Значит максимальный размер пакетов, которые стороны будут посылать друг другу, составит 1460(MSS)+20(TCP Заголовок)+20(IP Заголовок)=1500 байт.
2. В строке 4 отправка запроса на получение веб страницы от deb-serv-05. В строке 5 подтверждение получения данного пакета.
3. В строке 6 мы видим отправку ответа на запрос (т.е. отправку куска веб-страницы). Я не знаю почему, но на данном интерфейсе tcpdump видит один пакет размером в 2948 байт, в то время как в сеть уйдут 2 пакета размером 1500 и 1452 байта соответственно. Если посмотреть более подробный вывод tcpdump, то увидим, что на данном пакете(точнее пакетах) стоит флаг DF:

Код: Выделить всё

IP (tos 0x0, ttl 64, id 5177, offset 0, flags [DF], proto TCP (6), length 2948)
192.168.0.1.80 > 172.16.5.3.48547: Flags [.], seq 1:2897, ack 118, win 181, options [nop,nop,TS val 86620459 ecr 4922429], length 2896

4. Когда эти пакеты с данными доходят до deb-serv-03 они отбрасываются, так как не могут пройти по соединению с MTU 1400 и не могут быть фрагментированы(флаг DF), а в ответ генерируется сообщение ICMP тип 3 код 4: ICMP 172.16.5.3 unreachable - need to frag (mtu 1400), которое мы видим в строке 7 ( в строке 10 приходит сообщение для 2-го пакета). В этом сообщении передается нужный MTU.
5. В строках 8 и 9 мы наблюдаем как deb-serv, получив MTU=1400, отправляет тот же самый кусок веб страницы в пакетах размером 1400 байт. Данные пакеты доходят до deb-serv-05, где генерируется подтверждение, и так повторяется до тех пор, пока вся страница не будет передана. Размер всех последующих пакетов будет не больше 1400 байт.
На этом примере демонстрируется процедура определения Транспортного MTU (PMTU), описанная в RCF1911 ( http://tools.ietf.org/html/rfc1191 ). Я представил ее в упрощенном виде на рис 2.

ris_3.jpeg


Рис. 2. Процедура определения PMTU.


А теперь представим, что к провайдеру пришел новый специалист и решил (в целях защиты от icmp флуда) запретить пересылку icmp пакетов через deb-home, который теперь в его ведении. Смотрим что получается:
Вывод TCPDUMP#1 (на eth0 deb-serv):

Код: Выделить всё

1    IP 172.16.5.3.57925 > 192.168.0.1.80: Flags [S], seq 1723325723, win 5840, options [mss 1460...], length 0
2    IP 192.168.0.1.80 > 172.16.5.3.57925: Flags [S.], seq 2482933888, ack 1723325724, win 5792, options [mss 1460...], length 0
3    IP 172.16.5.3.57925 > 192.168.0.1.80: Flags [.], ack 1, win 1460, options [...], length 0
4    IP 172.16.5.3.57925 > 192.168.0.1.80: Flags [P.], seq 1:118, ack 1, win 1460, options [...], length 117
5    IP 192.168.0.1.80 > 172.16.5.3.57925: Flags [.], ack 118, win 181, options [...], length 0
6    IP 192.168.0.1.80 > 172.16.5.3.57925: Flags [.], seq 1:2897, ack 118, win 181, options [...], length 2896
7    IP 192.168.0.1.80 > 172.16.5.3.57925: Flags [.], seq 1:1449, ack 118, win 181, options [...], length 1448
8    IP 192.168.0.1.80 > 172.16.5.3.57925: Flags [.], seq 1:1449, ack 118, win 181, options [...], length 1448
9    IP 192.168.0.1.80 > 172.16.5.3.57925: Flags [.], seq 1:1449, ack 118, win 181, options [...], length 1448
10    IP 192.168.0.1.80 > 172.16.5.3.57925: Flags [.], seq 1:1449, ack 118, win 181, options [...], length 1448
11    IP 192.168.0.1.80 > 172.16.5.3.57925: Flags [.], seq 1:1449, ack 118, win 181, options [...], length 1448
12    IP 192.168.0.1.80 > 172.16.5.3.57925: Flags [.], seq 1:1449, ack 118, win 181, options [...], length 1448

Вывод TCPDUMP#2 (на eth0 deb-serv-03):

Код: Выделить всё

1    IP 172.16.5.3.57925 > 192.168.0.1.80: Flags [S], seq 1723325723, win 5840, options [mss 1460...], length 0
2    IP 192.168.0.1.80 > 172.16.5.3.57925: Flags [S.], seq 2482933888, ack 1723325724, win 5792, options [mss 1460...], length 0
3    IP 172.16.5.3.57925 > 192.168.0.1.80: Flags [.], ack 1, win 1460, options [...], length 0
4    IP 172.16.5.3.57925 > 192.168.0.1.80: Flags [P.], seq 1:118, ack 1, win 1460, options [...], length 117
5    IP 192.168.0.1.80 > 172.16.5.3.57925: Flags [.], ack 118, win 181, options [...], length 0
6    IP 192.168.0.1.80 > 172.16.5.3.57925: Flags [.], seq 1:1449, ack 118, win 181, options [...], length 1448
7    IP 172.16.250.2 > 192.168.0.1: ICMP 172.16.5.3 unreachable - need to frag (mtu 1400), length 556
8    IP 192.168.0.1.80 > 172.16.5.3.57925: Flags [.], seq 1449:2897, ack 118, win 181, options [...], length 1448
9    IP 172.16.250.2 > 192.168.0.1: ICMP 172.16.5.3 unreachable - need to frag (mtu 1400), length 556
10    IP 192.168.0.1.80 > 172.16.5.3.57925: Flags [.], seq 1:1449, ack 118, win 181, options [...], length 1448
11    IP 172.16.250.2 > 192.168.0.1: ICMP 172.16.5.3 unreachable - need to frag (mtu 1400), length 556
12    IP 192.168.0.1.80 > 172.16.5.3.57925: Flags [.], seq 1:1449, ack 118, win 181, options [...], length 1448
13    IP 172.16.250.2 > 192.168.0.1: ICMP 172.16.5.3 unreachable - need to frag (mtu 1400), length 556
14    IP 192.168.0.1.80 > 172.16.5.3.57925: Flags [.], seq 1:1449, ack 118, win 181, options [...], length 1448
15    IP 172.16.250.2 > 192.168.0.1: ICMP 172.16.5.3 unreachable - need to frag (mtu 1400), length 556
16    IP 192.168.0.1.80 > 172.16.5.3.57925: Flags [.], seq 1:1449, ack 118, win 181, options [...], length 1448
17    IP 172.16.250.2 > 192.168.0.1: ICMP 172.16.5.3 unreachable - need to frag (mtu 1400), length 556
18    IP 192.168.0.1.80 > 172.16.5.3.57925: Flags [.], seq 1:1449, ack 118, win 181, options [...], length 1448
19    IP 172.16.250.2 > 192.168.0.1: ICMP 172.16.5.3 unreachable - need to frag (mtu 1400), length 556
20    IP 192.168.0.1.80 > 172.16.5.3.57925: Flags [.], seq 1:1449, ack 118, win 181, options [...], length 1448


Как видите, ситуация вполне ожидаемая. Первые 6 строк в каждом выводе точно такие же, как и при нормальной передаче (см. Описание в предыдущем примере). Но вот дальше начинаются расхождения. ICMP 3:4 точно так же генерируется на deb-serv-03(строки 7, 9 11.13, 15, 17, 19 в TCPDUMP#2), но deb-serv его не получает и продолжает слать пакеты размером в 1500 байт(строки с 6 по 12 в TCPDUMP#1 и 6, 8, 10, 12, 14, 16, 18 и 20 в TCPDUMP#2). С каждым разом время между повторной посылкой все увеличивается (в данных примерах я отбросил временые метки, но на самом деле это так). Никаких данных размером большим, чем PMTU, в таком случае не передать. Но увы, TCP этого не знает и продолжает слать пакеты с MSS, выбранным в момент установки соединения. Именно эта ситуация и называется Path MTU Discovery Black Hole (Черная дыра в определении транспортного MTU). Я постарался представить ее в упрощенном виде на рис. 3.

ris_2.jpeg

Рис. 3. Черная дыра в определении PMTU.


Эта проблема совсем не нова. Она описана в RFC 2923 ( http://tools.ietf.org/html/rfc2923 ) в 2000 году. Но тем не менее, продолжает встречаться с завидным упорством у многих провайдеров. А ведь именно провайдер виноват в данной ситуации: не нужно блокировать ICMP тип 3 код 4. Причем слушаться «голоса разума» ( т. е. клиентов, понимающих в чем проблема) они обычно не хотят. Поэтому не будем обращать на них внимание и попробуем решить проблему, исходя из собственных средств.
Разработчики Linux, тоже знающие об этой проблеме, предусмотрели специальную опцию в iptables. Цитата из man iptables:
TCPMSS
This target allows to alter the MSS value of TCP SYN packets, to control the maximum size for that connection (usually limiting it to your outgoing interface’s MTU minus 40 for IPv4 or 60 for IPv6, respectively). Of course, it can only be used in conjunction with -p tcp. It is only valid in the mangle table. This target is used to overcome criminally braindead ISPs or servers which block "ICMP Fragmentation Needed" or "ICMPv6 Packet Too Big" packets. The symptoms of this problem are that everything works fine from your Linux firewall/router, but machines behind it can never exchange large packets:
1) Web browsers connect, then hang with no data received.
2) Small mail works fine, but large emails hang.
3) ssh works fine, but scp hangs after initial handshaking.
Workaround: activate this option and add a rule to your firewall configuration like:
iptables -t mangle -A FORWARD -p tcp --tcp-flags SYN,RST SYN \
-j TCPMSS --clamp-mss-to-pmtu

--set-mss value
Explicitly set MSS option to specified value.

--clamp-mss-to-pmtu
Automatically clamp MSS value to (path_MTU - 40 for IPv4; -60 for IPv6).

These options are mutually exclusive.

Мой вольный перевод:
TCPMSS
Это действие позволяет изменять значение MSS в TCP SYN пакетах, для контроля максимального размера пакетов в этом соединении (Обычно ограничивая его MTU исходящего интерфейса минус 40 байт для IPv4 или минус 60 для IPv6). Конечно, это действие может использоваться только в сочетании с -p tcp. Разрешено это только в таблице mangle. Это действие используется для преодоления преступной некомпетентности провайдеров и серверов, блокирующих "ICMP Fragmentation Needed" или "ICMPv6 Packet Too Big" пакеты. Симптомы этой проблемы – все прекрасно работает на вашем сетевом экране или роутере, но машины за ним никогда не смогут обмениваться большими пакетами:
1) Веб браузеры связываются, но просто висят без пересылки данных.
2) маленькие электронные письма приходят нормально, но большие висят.
3) ssh работает отлично, но scp висит после начальных рукопожатий(прим пер: процесс установки TCP соединения также называют "тройным рукопожатием").
Решение: активировать эту опцию и добавить правило, подобное нижеприведенному, в конфигурацию своего сетевого экрана:
iptables -t mangle -A FORWARD -p tcp --tcp-flags SYN,RST SYN \
-j TCPMSS --clamp-mss-to-pmtu

--set-mss значение
Явная установка в опции MSS специфического значения.

--clamp-mss-to-pmtu
Автоматическая установка значения MSS в (path_MTU - 40 для IPv4; -60 для IPv6).

Эти опции являются взаимоисключающими.

Как видите, много всего написали, даже описали примерные симптомы проблемы. А такое поведение провайдеров назвали "преступной некомпетентностью(criminally braindead)", в чем я с ними полностью согласен. Давайте исследуем, как же будет работать эта опция в нашем примере. Добавляем на deb-serv-03 рекомендованное правило:

Код: Выделить всё

iptables -t mangle -A FORWARD -p tcp --tcp-flags SYN,RST SYN -j TCPMSS --set-mss 1360

И смотрим что получилось:
Вывод TCPDUMP#1 (на eth0 deb-serv):

Код: Выделить всё

1    ip 172.16.5.3.33792 > 192.168.0.1.80: flags [s], seq 1484543117, win 5840, options [mss 1360...], length 0
2    ip 192.168.0.1.80 > 172.16.5.3.33792: flags [s.], seq 2230206317, ack 1484543118, win 5792, options [mss 1460...], length 0
3    ip 172.16.5.3.33792 > 192.168.0.1.80: flags [.], ack 1, win 1460, options [...], length 0
4    ip 172.16.5.3.33792 > 192.168.0.1.80: flags [p.], seq 1:118, ack 1, win 1460, options [...], length 117
5    ip 192.168.0.1.80 > 172.16.5.3.33792: flags [.], ack 118, win 181, options [...], length 0
6    ip 192.168.0.1.80 > 172.16.5.3.33792: flags [.], seq 1:2697, ack 118, win 181, options [...], length 2696
7    ip 172.16.5.3.33792 > 192.168.0.1.80: flags [.], ack 1349, win 2184, options [...], length 0
8    ip 192.168.0.1.80 > 172.16.5.3.33792: flags [.], seq 2697:5393, ack 118, win 181, options [...], length 2696
9    ip 192.168.0.1.80 > 172.16.5.3.33792: flags [fp.], seq 5393:6380, ack 118, win 181, options [...], length 987
10    ip 172.16.5.3.33792 > 192.168.0.1.80: flags [.], ack 2697, win 2908, options [...], length 0


Вывод TCPDUMP#3 (на eth0 deb-serv-05):

Код: Выделить всё

1    IP 172.16.5.3.33792 > 192.168.0.1.80: Flags [S], seq 1484543117, win 5840, options [mss 1460...], length 0
2    IP 192.168.0.1.80 > 172.16.5.3.33792: Flags [S.], seq 2230206317, ack 1484543118, win 5792, options [mss 1360...], length 0
3    IP 172.16.5.3.33792 > 192.168.0.1.80: Flags [.], ack 1, win 1460, options [...], length 0
4    IP 172.16.5.3.33792 > 192.168.0.1.80: Flags [P.], seq 1:118, ack 1, win 1460, options [...], length 117
5    IP 192.168.0.1.80 > 172.16.5.3.33792: Flags [.], ack 118, win 181, options [...], length 0
6    IP 192.168.0.1.80 > 172.16.5.3.33792: Flags [.], seq 1:1349, ack 118, win 181, options [...], length 1348
7    IP 192.168.0.1.80 > 172.16.5.3.33792: Flags [.], seq 1349:2697, ack 118, win 181, options [...], length 1348
8    IP 172.16.5.3.33792 > 192.168.0.1.80: Flags [.], ack 1349, win 2184, options [...], length 0
9    IP 172.16.5.3.33792 > 192.168.0.1.80: Flags [.], ack 2697, win 2908, options [...], length 0
10    IP 192.168.0.1.80 > 172.16.5.3.33792: Flags [.], seq 2697:4045, ack 118, win 181, options [...], length 1348


Разбираем:
1. В строках 1-3 мы уже привычно наблюдаем установку TCP соединения. Но обратите внимание на значения MSS. В TCPDUMP#1 от deb-serv-05 приходит значение 1360, в то время как в TCDUMP#3 видно, что уходит пакет с MSS=1460. Именно так и работает правило с –set-mss 1360. Оно редактирует значение MSS у пролетающих пакетов. Для SYN пакета, пришедшего в ответ, это значение тоже отредактировано.
2. В строках 4 и 5 обоих выводов мы опять наблюдаем отправку GET запроса и подтверждение получения.
3. В строке 6 для TCPDUMP#1 и строках 6 и7 для TCPDUMP#3 видим отправку пакетов с данными, но теперь размер каждого из пакетов не превышает 1400 байт. Опять происходит странный глюк с TCPDUMP#1, где виден один большой пакет, в то время как в TCPDUMP#3 мы наблюдаем приход 2-х пакетов.
4. Дальнейший обмен пакетами идет в соответствии с правилами протокола TCP. Но ни разу размер пакета на превышал 1400 байт.

В упрощенном виде поведение MSS представлено на рис. 4. Я не стал показывать обмен данными, так как он аналогичен обычному поведению.

ris_1.jpeg

Рис. 4. Изменение MSS на лету.


Хотя в man iptables описаны две опции, но я пока применил только одну. Нужная опция зависит от конкретной ситуации. Все ситуации можно разделить на 2 типа:

1. На вашем маршрутизаторе сайты открываются нормально, у клиентов в локальной сети наблюдаются проблемы.
В этом случае наименьший MTU на всем пути находится именно на вашем сервере. Обычно это некие протоколы инкапсуляции, типа PPPoE, PPtP и тд. Для данной ситуации лучше всего подойдет опция –-clamp-mss-to-pmtu, которая автоматически установит минимальный MSS на все транзитные пакеты.

2. На вашем маршрутизаторе и у клиентов в локальной сети сайты не открываются.
В таком случае наименьший MTU находится где-то у провайдера и вычислить его стандартными средствами сложновато. Специально для этого я написал скрипт на python, который поможет определить необходимый размер MSS для данной ситуации:

Код: Выделить всё

#!/usr/bin/env python
# -*-coding: utf-8 -*-
# vim: sw=4 ts=4 expandtab ai

import socket
import os
import time
import sys

# Полное имя веб сервера на котором проводятся испытания. Следует выбирать из
# сайтов, которые точно не работают.
HOST = 'www.site.local'
# Временной интервал, в течении которого следует ожидать ответа от сайта.
# Слишком маленькое значение может породить ложные срабатывания, слишком
# большое - долгое время работы скрипта.
TIMEOUT = 25.0
# Количество байт, которые надо получить с веб сервера, чтобы убедится что он
# наверняка работает. Рекомендуется устанавливать большим нежели значение MTU
BUF = 3000
# Значение MTU на интерфейсе в интернет.
MTU = 1500
# Значение MSS будет искаться в пределе от MTU-LIM-40 до MTU-40. Запрещено
# ставить значение больше MTU и не рекомендуется ставить значения более чем
# 100-200 - это может привести к большому времени работы скрипта.
LIM = 100
# Задержка между обращениями к сайту. Рекомендуется устанавливать отличной от
# нуля на медленном канале.
TRY_TIME = 0

def set_mss(mss, action='A'):
    return os.system("iptables -t mangle -%s OUTPUT -p tcp --tcp-flags \
            SYN,RST SYN -j TCPMSS --set-mss %d" % (action, mss) )

def check_connection(host):
    s = socket.socket()
    s.connect( (host, 80) )
    s.send('GET / HTTP/1.1\r\nHost: %s\r\n\r\n' % host)
    s.settimeout(TIMEOUT)
    try:
        d = len( s.recv(BUF) )
    except:
        d = 0
    s.close()
    return d

def main():
    mss = MTU - 40
    if not check_connection(HOST):
        mss = MTU - 40 - LIM
        set_mss(mss)
        if not check_connection(HOST):
            set_mss(mss,'D')
            print "Error: Too small LIM"
            sys.exit(1)
        else:
            while check_connection(HOST):
                time.sleep(TRY_TIME)
                set_mss(mss,'D')
                if mss >= MTU-40:
                    print "Error in determining MSS"
                    sys.exit(1)
                mss += 1
                set_mss(mss)
            set_mss(mss,'D')
            mss -= 1
    print 'MSS = %d' % (mss)

if __name__ == '__main__':
    main()
    sys.exit(0)


Запускать скрипт нужно с правами суперпользователя. Алгоритм его работы таков:
1. Пытаемся получить некоторое количество данных с сайта с нормальным значением MSS.
2. Если это не получается, то понижаем MSS на iptables цепочке OUTPUT до MTU - 40 – LIM.
3. Если и после этого мы не можем получить данные, то выдаем ошибку о том, что LIM имеет слишком маленькое значение.
4. Последовательно наращивая MSS, ищем тот момент, когда данные перестанут поступать. После этого выводим последнее рабочее значение MSS.
5. Если мы дошли до MSS=MTU-40, то выводим ошибку о том, что не можем определить MSS. Данная ситуация является ошибочной, т. к. в пункте 1 проводим аналогичную проверку, и, если результаты не совпадают, это повод задуматься.

После получения нужного MSS необходимо вписать его в соответствующее правило (используя --set-mss). Можно обойтись и без скрипта, на глаз понизив значение MSS, но лучше выяснить его точно – меньше накладые расходы на пересылку пакетов.

Внимание! Чтобы использовать эти правила для iptables в ядре должны быть включены две опции - CONFIG_NETFILTER_XT_TARGET_TCPMSS и CONFIG_NETFILTER_XT_MATCH_TCPMSS. Проверить можно например так:

Код: Выделить всё

cat /boot/config-2.6.26-2-686 | grep TCPMSS
CONFIG_NETFILTER_XT_TARGET_TCPMSS=m
CONFIG_NETFILTER_XT_MATCH_TCPMSS=m

Как видите у меня они подключены модулями.

Часто на форумах можно встретить советы понизить MTU на том или ином интерфейсе. Нужно понимать, что это не панацея, и результат зависит от того, на каком интерфейсе понижать. Если понизим на одном из интерфейсов участников TCP соединения, то это принесет эффект, так как заявленная MSS будет соответствовать минимальному размеру пакета. Но если это будут не конечные точки, а один из транзитных маршрутизаторов, то без включения опции –clamp-mss-to-pmtu никакого эффекта не будет.

Надеюсь данная статья поможет Вам решить подобную проблему как у себя, так и у ваших друзей и знакомых. Еще раз обращаюсь к специалистам провайдеров – НЕ БЛОКИРУЙТЕ ICMP ТИП 3 КОД 4 – этим вы создаете проблемы вашим колегам.
Спасибо сказали:
Аватара пользователя
Alex2ndr
Сообщения: 443
ОС: Debian Lenny

Re: Недоступны некоторые сайты. Вечное ожидание ответа.

Сообщение Alex2ndr »

Еще несколько моментов, касающихся не столько статьи, сколько темы.

1. Уважаемый sash-kan! Я пробовал ваш способ, описаный здесь, но к сожалению не смог добиться его работоспособности. Пробовал разные значения window и advmss - в проходящих пакетах ничего не изменяется - ни mss ни размер окна. Я еще покурю маны, но может быть вы знаете какой-то финт, до которого я не додумался? Думаю добавить это к статье как одно из решений, если разберусь.

2. Если на данном форуме есть специалисты, работающие у крупных контент провайдеров, то хочу спросить - а у вас эта проблема актуальна? Если да, то как вы с ней боретесь? Ведь крупным компаниям надавить на провайдеров гораздо проще.

3. Если на данном форуме есть специалисты провайдеров, которые блокируют icmp, то может вы поясните мне зачем? Кроме icmp флуда ничего не придумал...
Спасибо сказали:
Аватара пользователя
KiWi
Бывший модератор
Сообщения: 2521
Статус: статус, статус, статус
Контактная информация:

Re: Недоступны некоторые сайты. Вечное ожидание ответа.

Сообщение KiWi »

Alex2ndr писал(а):
18.10.2010 00:05
Еще несколько моментов, касающихся не столько статьи, сколько темы.

1. Уважаемый sash-kan! Я пробовал ваш способ, описаный здесь, но к сожалению не смог добиться его работоспособности. Пробовал разные значения window и advmss - в проходящих пакетах ничего не изменяется - ни mss ни размер окна. Я еще покурю маны, но может быть вы знаете какой-то финт, до которого я не додумался? Думаю добавить это к статье как одно из решений, если разберусь.

2. Если на данном форуме есть специалисты, работающие у крупных контент провайдеров, то хочу спросить - а у вас эта проблема актуальна? Если да, то как вы с ней боретесь? Ведь крупным компаниям надавить на провайдеров гораздо проще.

3. Если на данном форуме есть специалисты провайдеров, которые блокируют icmp, то может вы поясните мне зачем? Кроме icmp флуда ничего не придумал...

Думаю, наиболее актуальная проблема у людей с домашними роутерами, которые сами же не разрешили форвардинг icmp.
advmss тут не поможет(если, конечно, не знать mtu на всём маршруте) -- он позволяет снизить анонсируемый mss, но это никак не поможет с mtu на транзитных узлах.
Спасибо сказали:
Аватара пользователя
Alex2ndr
Сообщения: 443
ОС: Debian Lenny

Re: Недоступны некоторые сайты. Вечное ожидание ответа.

Сообщение Alex2ndr »

KiWi писал(а):
18.10.2010 00:38
Думаю, наиболее актуальная проблема у людей с домашними роутерами, которые сами же не разрешили форвардинг icmp.

Хммм... Я боюсь, что Вы невнимательно читали мою статью :) Обратите внимание на рис. 3. Там показано движение icmp пакетов в случае этой проблемы. Представьте, что deb-serv-05 это домашний роутер, а за ним собственно сеть. Как вы думаете чем поможет разрешение любого icmp на этом роутере, если нужные нам ICMP тип 3 код 4 ходят где-то в сетях провайдера(между deb-serv-03 и deb-serv)? Кроме того вот вам случаи из практики - на своих серверах я никогда не запрещаю ICMP тип 3(и транзитный и входящий/исходящий), однако от этой проблемы регулярно страдаю. Увы - эта проблема - не проблема пользователя.

KiWi писал(а):
18.10.2010 00:38
advmss тут не поможет(если, конечно, не знать mtu на всём маршруте) -- он позволяет снизить анонсируемый mss, но это никак не поможет с mtu на транзитных узлах.

Вот это-то и странно. Я устанавливаю на дефолтный маршрут advmss=1300, а потом наблюдаю через tcpdump. Никакого снижения mss в syn пакетах я не увидел. В то время как через iptables все нормально снижается... Такое ощущение что снижение mss через таблицу маршрутизации просто не работает... У меня по крайней мере.
Спасибо сказали:
patrius
Сообщения: 337
ОС: Debian (4 & 5) -> Gentoo

Re: Недоступны некоторые сайты. Вечное ожидание ответа.

Сообщение patrius »

Alex2ndr писал(а):
18.10.2010 00:05
3. Если на данном форуме есть специалисты провайдеров, которые блокируют icmp, то может вы поясните мне зачем? Кроме icmp флуда ничего не придумал...

Лично мне очень интересно услышать ответ от админов провайдеров, на вопрос вида:
"На кой леший вы вообще режете FORWARD, решая за пользователя какие ему порты нада*??? Или еще круче... на "не_корпоративных" серверах ставете прокси?"
*Не давно имел удовольствие работать с каналом такого провайдера. Для пользователя открыты только 80, 443, 21, 25, 110. Вот это я понимаю "Инет для дома" :(

Отдельное АРИГАТО Alex2ndr'у за СБАЖ.
Сам как-то наступал на подобное.)
Спасибо сказали:
Аватара пользователя
sash-kan
Администратор
Сообщения: 13939
Статус: oel ngati kameie
ОС: GNU
Контактная информация:

Re: Недоступны некоторые сайты. Вечное ожидание ответа.

Сообщение sash-kan »

Alex2ndr писал(а):
18.10.2010 00:05
1. Уважаемый sash-kan! Я пробовал ваш способ, описаный здесь, но к сожалению не смог добиться его работоспособности. Пробовал разные значения window и advmss - в проходящих пакетах ничего не изменяется - ни mss ни размер окна. Я еще покурю маны, но может быть вы знаете какой-то финт, до которого я не додумался? Думаю добавить это к статье как одно из решений, если разберусь.
во-первых, манипуляции с tcp-window могут понадобиться лишь в случае, если не помогает уменьшение mtu.
во-вторых, не уверен, что тот же tcpdump покажет что-нибудь интересное: чёрт его знает, в какой момент pcap снимает информацию, до того, как пакет будет покорёжен в соответствии с правилом роутинга, или после.
Писать безграмотно - значит посягать на время людей, к которым мы адресуемся, а потому совершенно недопустимо в правильно организованном обществе. © Щерба Л. В., 1957
при сбоях форума см.блог
Спасибо сказали:
Аватара пользователя
Alex2ndr
Сообщения: 443
ОС: Debian Lenny

Re: Недоступны некоторые сайты. Вечное ожидание ответа.

Сообщение Alex2ndr »

sash-kan писал(а):
18.10.2010 15:16
во-вторых, не уверен, что тот же tcpdump покажет что-нибудь интересное: чёрт его знает, в какой момент pcap снимает информацию, до того, как пакет будет покорёжен в соответствии с правилом роутинга, или после.

Ну у меня же цепочка машин(т е больше одной физической). Корежит в середине. Значит в начале/конце цепочки я должен что-то увидеть? Фишка в том что ничего не вижу. Даже если предположить что это "невидимое вмешательство" :) то эффект то должен быть? Т е сайт должен открываться? Ведь не открывается... Я вот думаю может вообще не применилось... или надо какую-то опцию где-нить в ядре включать...
Спасибо сказали:
Аватара пользователя
sash-kan
Администратор
Сообщения: 13939
Статус: oel ngati kameie
ОС: GNU
Контактная информация:

Re: Недоступны некоторые сайты. Вечное ожидание ответа.

Сообщение sash-kan »

на всякий случай перепроверил.
да, изменение window не сразу оказывает эффект. несмотря на очистку кэша маршрутов. но при обращении к новым сайтам — всё нормально. tcp window в исходящих пакетах выставляется в новое значение.

другое дело, что описанный в блоге случай, — достаточно уникален. что и как провайдер резал — неизвестно.
Писать безграмотно - значит посягать на время людей, к которым мы адресуемся, а потому совершенно недопустимо в правильно организованном обществе. © Щерба Л. В., 1957
при сбоях форума см.блог
Спасибо сказали:
Аватара пользователя
Alex2ndr
Сообщения: 443
ОС: Debian Lenny

Re: Недоступны некоторые сайты. Вечное ожидание ответа.

Сообщение Alex2ndr »

sash-kan писал(а):
19.10.2010 11:03
да, изменение window не сразу оказывает эффект. несмотря на очистку кэша маршрутов.

Вот это наверно ключевой момент. Попробую поэкспериментировать с некоторым ожиданием и новыми сайтами.
Спасибо сказали:
Аватара пользователя
44616e
Сообщения: 205
ОС: Debian testing

Re: Недоступны некоторые сайты. Вечное ожидание ответа.

Сообщение 44616e »

Спасибо за статью, очень хорошо разжевано.
Правда царапнули глаз пара опечаток ("симпОтомы", "примеНЕнил") и в строке
MTU_интерфейса – Размер_IP_заголовка(20 байт) – Размер_TCP_заголовка(20 байт)

может имеет смысл выделить переменные скобками? Например
[MTU интерфейса] – [Размер IP заголовка(20 байт)] – [Размер TCP заголовка(20 байт)]
А то минусы и подчеркивания в глазах сливаются, только раза с четвертого удалось понять что к чему
Спасибо сказали:
Аватара пользователя
Alex2ndr
Сообщения: 443
ОС: Debian Lenny

Re: Недоступны некоторые сайты. Вечное ожидание ответа.

Сообщение Alex2ndr »

44616e писал(а):
30.11.2010 14:20
...
Правда царапнули глаз пара опечаток ("симпОтомы", "примеНЕнил")...

Буду рад исправить, если укажите где именно. Вроде давал вычитывать нескольким людям - думал что все нашли...

44616e писал(а):
30.11.2010 14:20
...
MTU_интерфейса – Размер_IP_заголовка(20 байт) – Размер_TCP_заголовка(20 байт)

может имеет смысл выделить переменные скобками? Например
[MTU интерфейса] – [Размер IP заголовка(20 байт)] – [Размер TCP заголовка(20 байт)]
А то минусы и подчеркивания в глазах сливаются, только раза с четвертого удалось понять что к чему

Fixed.
Спасибо сказали:
Аватара пользователя
sash-kan
Администратор
Сообщения: 13939
Статус: oel ngati kameie
ОС: GNU
Контактная информация:

Re: Недоступны некоторые сайты. Вечное ожидание ответа.

Сообщение sash-kan »

Alex2ndr писал(а):
30.11.2010 15:14
44616e писал(а):
30.11.2010 14:20
...
Правда царапнули глаз пара опечаток ("симпОтомы", "примеНЕнил")...

Буду рад исправить, если укажите где именно.
в первом посте.
ваш к.о.
Писать безграмотно - значит посягать на время людей, к которым мы адресуемся, а потому совершенно недопустимо в правильно организованном обществе. © Щерба Л. В., 1957
при сбоях форума см.блог
Спасибо сказали:
patrius
Сообщения: 337
ОС: Debian (4 & 5) -> Gentoo

Re: Недоступны некоторые сайты. Вечное ожидание ответа.

Сообщение patrius »

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

Код: Выделить всё

Claes linux # zcat /proc/config.gz | grep TCPMSS
CONFIG_NETFILTER_XT_TARGET_TCPMSS=y
CONFIG_NETFILTER_XT_MATCH_TCPMSS=y

Спасибо сказали:
pelmen
Сообщения: 1268
ОС: debian

Re: Недоступны некоторые сайты. Вечное ожидание ответа.

Сообщение pelmen »

Молодец, очень хорошая статья!
Я как-то забросил это дело (писать статьи), работа, ребенок маленький...
Спасибо сказали:
Аватара пользователя
Alex2ndr
Сообщения: 443
ОС: Debian Lenny

Re: Недоступны некоторые сайты. Вечное ожидание ответа.

Сообщение Alex2ndr »

patrius писал(а):
09.12.2010 19:03
из разборок и настройки могу отметить, что в ядре должна быть включена TCPMSS в NETFILTER

Верно. И у меня это написано, хоть и неявно :) :
Смотрите вот тут:
(man iptables) писал(а):TCPMSS
...
Workaround: activate this option and add a rule to your firewall configuration like...

подразумевается что активировать эту опцию в ядре.

Вообще в Дебина версий 4,5,6 она включена по умолчанию. В остальных не знаю, но думаю тоже в большинстве включена. Я, конечно, могу добавить это в статью, но имхо гентушники и так должны помнить что они включили/отключили при сборке :D

pelmen писал(а):
14.12.2010 10:56
Молодец, очень хорошая статья!
Я как-то забросил это дело (писать статьи), работа, ребенок маленький...

Спасибо, стараюсь. А насчет времени - вот ребенок подрастет и найдется время :) Я тоже через это прошел.
Спасибо сказали:
patrius
Сообщения: 337
ОС: Debian (4 & 5) -> Gentoo

Re: Недоступны некоторые сайты. Вечное ожидание ответа.

Сообщение patrius »

Alex2ndr, самое пожалуй смешное, это тот факт, что сабж у обычной ВинХР работает без дополнительных телодвижений (
А по поводу добавления в главный пост, имхо, стоит оратить внимание читателей на этот момент.
Спасибо сказали:
Аватара пользователя
Alex2ndr
Сообщения: 443
ОС: Debian Lenny

Re: Недоступны некоторые сайты. Вечное ожидание ответа.

Сообщение Alex2ndr »

patrius писал(а):
15.12.2010 20:22
Alex2ndr, самое пожалуй смешное, это тот факт, что сабж у обычной ВинХР работает без дополнительных телодвижений

Меня тоже забавляет этот момент. Хотя вроде бы я встречал такую траблу на W2K3 при использовании RRAS. Но точно не уверен. Может быть вы хотите сделаеть исследование этого феномена? Собственно это немного осложнено тем, что в комплекте с виндой не идет нормальных сниферов. Нужно перехватывать пакеты и смотреть что именно там меняется. Чуется мне что винда опять нарушает все стандарты. У меня просто сча небольшой напряг со временем.

patrius писал(а):
15.12.2010 20:22
А по поводу добавления в главный пост, имхо, стоит оратить внимание читателей на этот момент.

Добавил. Пусть будет.
Спасибо сказали:
patrius
Сообщения: 337
ОС: Debian (4 & 5) -> Gentoo

Re: Недоступны некоторые сайты. Вечное ожидание ответа.

Сообщение patrius »

Alex2ndr писал(а):
16.12.2010 11:03
patrius писал(а):
15.12.2010 20:22
Alex2ndr, самое пожалуй смешное, это тот факт, что сабж у обычной ВинХР работает без дополнительных телодвижений

Меня тоже забавляет этот момент. Хотя вроде бы я встречал такую траблу на W2K3 при использовании RRAS. Но точно не уверен. Может быть вы хотите сделаеть исследование этого феномена? Собственно это немного осложнено тем, что в комплекте с виндой не идет нормальных сниферов. Нужно перехватывать пакеты и смотреть что именно там меняется. Чуется мне что винда опять нарушает все стандарты. У меня просто сча небольшой напряг со временем.

Желания пока нет... хотя не факт, что не возникнет.
Alex2ndr писал(а):
16.12.2010 11:03
patrius писал(а):
15.12.2010 20:22
А по поводу добавления в главный пост, имхо, стоит оратить внимание читателей на этот момент.

Добавил. Пусть будет.

И пусть мир станет лучше )
Спасибо сказали:
Аватара пользователя
sash-kan
Администратор
Сообщения: 13939
Статус: oel ngati kameie
ОС: GNU
Контактная информация:

Re: Недоступны некоторые сайты. Вечное ожидание ответа.

Сообщение sash-kan »

Alex2ndr писал(а):
16.12.2010 11:03
Чуется мне что винда опять нарушает все стандарты.
в ms/windows на каждом шагу встроены зачатки искусственного интеллекта.
помогающие обойти и (в данном случае) провайдерские «косяки», и локальные конфигурационные.
Писать безграмотно - значит посягать на время людей, к которым мы адресуемся, а потому совершенно недопустимо в правильно организованном обществе. © Щерба Л. В., 1957
при сбоях форума см.блог
Спасибо сказали:
Аватара пользователя
nerve
Сообщения: 280
ОС: OpenBSD

Re: Недоступны некоторые сайты. Вечное ожидание ответа.

Сообщение nerve »

опишу проблему, с которой столкнулся недавно.
как известно в РФ сейчас провайдеры блокируют ИП по письмам счастья из соответствующих огранов.
если ваш адрес попал в такой список, то возможны непонятки в диагностировании проблемы: то хост доступен, то нет. причем с разных сторон света, в зависимости где находится хост и откуда к нему обращаться, он может быть как доступен, так и нет.
вариант решения в лоб - исключение хоста из реестра.
или, если вы не резидент РФ, то просить вашего провайдера изменить маршрут до хоста (если он и вы не в РФ) минуя провадеров РФ.
Спасибо сказали:
Ответить