zivot_je_cudo 04.12.2009 13:07

Linux Network AdministrationМеханизм PMTUD

Долго думал, какой блог выбрать, сначала склонялся к "Пятиминутке ненависти", но "Linux Network Administration" победил.

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

Совсем недавно одному удаленному бухгалтеру понадобилось подключаться по RDP к нашему терминальному серверу для работы с 1C. Виндовый админ выделил нужные права, завел учетку, с моей стороны тоже проблем нет: IP клиента статический, а RDP использует TCP порт 3389, который сразу и был проброшен на терминальный сервер:

1
2
iptables -t nat -A PREROUTING -p tcp -s $ext_term_access -d $INET_IP --dport 3389 -j DNAT --to-destination $SRV1C
iptables -A FORWARD -p TCP -s $ext_term_access --dport 3389 -d $SRV1C -j ACCEPT



Проверили конфигурацию с внешнего компьютера, успешно соединились, клиенту сразу был дан ответ «Готово, подключайтесь». Ко всеобщему удивлению клиент не смог соединиться, с его стороны соединение «зависало», не выдавая ошибок.

Мы проверили конфигурацию с еще нескольких внешних компьютеров, и везде соединение шло гладко. Пришлось списаться с их сисадмином, который, вместо того, чтобы подумать вместе, заявил, что проблема явно у нас, и что его клиенты подключаются таким образом ко многим серверам, а его ISA (это, вроде, такой виндовый фаерволл) и вовсе безупречна. Несколько дней я ломал голову над этой проблемой, даже временно частично или полностью отключал фаерволл, после чего выяснилось, что консольный-то доступ к терминалу у клиента работает.

Подозрение сразу пало на некорректный MTU, так как присутствовал самый явный симптом: текстовая информация и прочая мелочь размером до полутора килобайт передавалась успешно, а с более весомой графикой возникали проблемы.

Здесь хотелось бы подробнее остановиться на замечательной технологии определения максимального размера передаваемого сегмента в протоколе TCP — Path Maximum Transmission Unit Discovery или просто PMTUD. Два компьютера (клиент и сервер) начинают сессию передачи данных с SYN и SYN-ACK пакетов, которые содержат информацию о MSSMaximum Segment Size — это характеристика протокола TCP, сообщающая максимально допустимый размер передаваемого сегмента. Так это выглядит:

1
2
IP (0x64, 44702, <df>, TCP, 52) client.com.55679 > server.com.http: S, cksum 0x13ea (correct), 3230584989:3230584989(0) win 5840 <mss 1452,nop,nop,sackOK,nop,wscale 4>
IP (0x63, </df><df>, TCP, 52) server.com.http > client.com.55679: S, cksum 0xb43b (correct), 3776478921:3776478921(0) ack 3230584990 win 5808 <mss 1412,nop,nop,sackOK,nop,wscale 7></df>


Видно, что для одного компьютера MSS равен 1452, для другого 1412. Из этих двух значений выбирается наименьшее. В этой сессии размер любого сегмента обязательно будет меньше либо равен 1412 байт:

1
2
3
4
5
6
7
8
9
IP (0x64, 44703, <df>, TCP, 40) client.com.55679 > server.com.http: ., cksum 0x0a21 (correct), 1:1(0) ack 1 win 365
IP (0x64, 44704, </df><df>, TCP, 857) client.com.55679 > server.com.http: P 1:818(817) ack 1 win 365
IP (0x63, 63163, </df><df>, TCP, 40) server.com.http > client.com.55679: ., cksum 0x0822 (correct), 1:1(0) ack 818 win 59
IP (0x63, 63164, </df><df>, TCP, 1452) server.com.http > client.com.55679: . 1:1413(1412) ack 818 win 59
IP (0x64, 44705, </df><df>, TCP, 40) client.com.55679 > server.com.http: ., cksum 0x00b5 (correct), 818:818(0) ack 1413 win 548
IP (0x63, 63165, </df><df>, TCP, 1452) server.com.http > client.com.55679: . 1413:2825(1412) ack 818 win 59
IP (0x64, 44706, </df><df>, TCP, 40) client.com.55679 > server.com.http: ., cksum 0xfa7a (correct), 818:818(0) ack 2825 win 730
IP (0x63, 63166, </df><df>, TCP, 1452) server.com.http > client.com.55679: P 2825:4237(1412) ack 818 win 59
...</df>



Путать MSS и MTU не стоит, последний — характеристика сетевого интерфейса, а не протокола. Ну, и конечно, MSS напрямую зависит от MTU и вычисляется как MTU — 20 (размер IP-заголовка) — 20 (размер TCP заголовка).

Таким образом, клиент и сервер могут обмениваться между собой информацией, посылая TCP-пакеты определенного размера с установленным битом «DF: Don't Fragment». Но если на пути между ними обнаружится узел, не способный передать пакет размером 1452 байта (1412+40), этот узел отбросит пакет и сформирует отправителю специальный ICMP пакет с типом 3 (Destination Unreachable) и кодом 4 (fragmentation needed and DF set), который, кроме самой ошибки, будет содержать информацию о максимально допустимом сегменте передачи.
Отправитель получает его, меняет свой MSS на еще более меньший и передача успешно продолжается. Это теория.

На практике же где-то между мной и клиентом эти столь необходимые ICMP-пакеты с информацией о фрагментации просто терялись. И передающая сторона, не получая ошибку, повторяла попытки передачи снова и снова, ожидая подтверждения приемной.

Эту проблему помог решить iptables. В таблице mangle он умеет изменять то самое передаваемое значение mss в SYN и SYN-ACK пакетах при помощи цели TCPMSS:

1
iptables -t mangle -A FORWARD -p tcp --tcp-flags SYN,RST SYN -s $ext_term_access -j TCPMSS --set-mss 1452


Это правило берет SYN-пакет, отправленный хостом клиента, и меняет его значение mss на 1452 (определял подбором). После того, как правило было прописано, у клиента все заработало, и все остались довольны.

Случай второй.
Наши плановики начали работать со специальной вебмордой на удаленном сервере. Оформление этого сайта не содержало каких-либо тяжелых объектов или графики, навигация по сайту работала прекрасно. Но среди используемых ими функций была «Формирование отчета в excel», которая просто «зависала» в ожидании ответа от сервера. На удаленной стороне ответили «У всех все работает» и предложили искать проблему у себя.

После некоторых размышлений, решил просто пропинговать их сервер, чтобы проверить присутствие icmp — и да, пинг не шел. Точно таким же образом, в iptables для серверного хоста был прописан еще меньший mss - 1380, после чего плановики смогли работать нормально.

Случай третий. Заметил недавно, что в очереди писем postfix на протяжении нескольких дней стали скапливаться письма на один и тот же домен, с одной о той же необычной причиной отсрочки:

ADC2F308358: from=, size=33628, nrcpt=2 (queue active)
ADC2F308358: enabling PIX workarounds: disable_esmtp delay_dotcrlf for mailserver.com<22.22.22.22>:25
ADC2F308358: to=, relay=mailserver.com<22.22.22.22>:25, delay=333009, delays=332827/0.02/1.5/181, dsn=4.4.2, status=deferred (conversation with mailserver.com<22.22.22.22> timed out while sending message body)


Жизнь, что называется, научила, поэтому первым делом проверил пинг до сервера. И пинга не оказалось.

Выставил наугад значение mss в 1380 байт, флашнул очередь — не помогло. Значения 1024, 768 и даже 512 тоже результата не дали О.о Началось активное гугление по ругани почтовика, и даже нашелся аналогичный случай, решением которого стало отключение tcp_sack (выборочный ACK на пакеты из очереди TCP). Но нашему серверу не помогло. И вот уже, готовый списаться с админами этого почтового сервера, я зачем-то в последний раз попробовал значение mss в 256 байт и это сработало. Я до сих пор не могу понять, какие же узлы могут находиться между нами, и какими извращенными способами где-то происходит инкапсуляция трафика, из-за чего mss в шесть раз ниже нормы.

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

На прошлой неделе списался снова с админом той конторы, откуда подключался клиент RDP:
<Я> а ты сам глушишь icmp или кто-то между нами это делает?
<Админ> у меня isa глушит по-умолчанию
<Я> а мб откроешь? там же icmp type 3 code 4 - необходима фрагментация
<Админ> только с вами, это вообще умолчательная настройка, с нею весь мир живёт, так что не в ней дело


А тем временем весь мир пингуется.

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


Тэги: icmp iptables mtu
+ 16 -
Похожие Поделиться

Username 04.12.2009 13:25 #
я желаю рака яичек

в мемориз!
tumick 04.12.2009 14:09 #
*THUMBS UP*
xtavras 04.12.2009 14:15 #
Мозг напряг хорошенько, но интересно)) Приятно читать, когда вникают как можно глубоко в суть проблемы до последнего байта.
nikebl 04.12.2009 15:49 #
На подобные проблемы постоянно натыкаюсь, спасибо. Кстати, никто не подскажет как в федоре при поднятиии pptp через NetworkManager прописать нужный mtu, тот что прописывает NM слишком большой.
NutipA 04.12.2009 17:14 #
В голову приходит мысль, что NM место на помойке. Я бы попробовал сразу после соединения кастануть обычное:

#ifconfig ppp0 mtu 666
Username 04.12.2009 18:17 #
хуевая плохая мысль.
Вкладка Ethernet, поле MTU в гуевине
nikebl 08.12.2009 17:44 #
угу, только для pptp нельзя указать mtu... только для ethernet.
#ifconfig ppp0 mtu 666

только так и спасаюсь.
VGusev2007 04.12.2009 16:01 #
Класс! Очень полезно! Я начинающий Администратор, и вот было желание зарубить весь ICMP траффик на FreeBSD шлюзах. - СПАСИБО! Ещё раз перечитаю TCP/IP стек.
zivot_je_cudo 04.12.2009 17:57 #
Фуф, от рака ж пронесло!
|xed| 04.12.2009 16:10 #
сам сталкивался с подобными проблемами,куча съеденного мозга и потеряны нервов ...жаль что раньше не встретил вас =)
я желаю рака яичек
- это очень жестко, но забавно !
<Админ> у меня isa глушит по-умолчанию
ISA по умолчанию все глушит =)
lwilis 04.12.2009 17:02 #
Отличная статья.
желаю рака яичек
По крайней мере, икота ему уже обеспечена. )
zivot_je_cudo 04.12.2009 17:06 #
Такие приятные комменты, не ожидал :)
NutipA 04.12.2009 17:07 #
Автор, как же я тебя понимаю! Сам помню пытался понять, отчего же так педалил инет при использовании на шлюзе SNAT, и вот, когда меня более опытные товарищи ткнули носом в то, что необходимо изучить как же работает tcp/ip и, в частности, проблему с MTU/MSS, я наконец достиг просветления. И таких просветлений должно быть немало у любого профессионала, а в нашей профессии именно такого рода тонкости и воспринимаются всеми как "танцы с бубном".
avpme 04.12.2009 17:16 #
Спасибки за статью! Так и боремся :-) К сожалению, довольно частая проблема.
В 2006 как то про это (первый вариант) сделал зарисовочку у себя на сайте :-)
zivot_je_cudo 04.12.2009 17:40 #
Мда, из центральной дирекции пришли новые требования, теперь стандарт почты у нас exchange, а vnp-серваком станет циска. Делать что - не знаю, но если она будет еще и шлюзом, точно уволюсь, к чертям.
zivot_je_cudo 04.12.2009 17:42 #
Это к вопросу о крутых железках.
avpme 05.12.2009 02:28 #
По поводу крутых железок не скажу, ибо у меня в администрировании большое количество кисок, но маленьких :-) 1700-ой серии... с ними проблем не было особых. А вот с провайдерами в разными проблемы постоянно... сервис у нас такой :-( С vpn киски работают хорошо, настройка и обслуживание документированы... и эта инфа доступна.
Относительно exchange - сочувствую, ибо с этим зверьком сталкивался всего пару раз и впечатления далеко не лучшие (но это первые и последние впечатления - в постоянной работе нет их у меня)... из виндовых почтовиков в обслуживании три MDaemon-а лицензионных и работают как часики, странно, почему его не берут на вооружение для систем на базе виндоус :-/
zivot_je_cudo 05.12.2009 13:47 #
Позволю себе еще пожаловаться.. Я работаю на постсоветском предприятии, у управляющего персонала мышление советское. Чем выше уровень власти, тем меньшую роль выполняет здравый смысл. Мнение сисадмина в этом вопросе никого не интересовало, бюджет подписан.
Если администрирование exchange это просто стресс для меня (необходимость миграции, отсутствие подробных логов, пренебрежение стандартами, вирусы..), то покупка циски это торжество дурократии. У нас всего три впн-клиента о.о
snowemo 05.12.2009 11:57 #
Блин, проснулся, а на велинуксе появилась наконец-то отличная статья :)
узнал много нового, спасибо!
freefd 05.12.2009 12:45 #
Вы не думали о публикации данного топика на хабре?
exelens 05.12.2009 13:13 #
О, смотрите кто пришёл!!! Боже я не верю своему счастью!!!
=) Это же очень известный жуйко тролль и глава фанклуба welamers
zivot_je_cudo 05.12.2009 13:32 #
Как-нибудь, с удовольствием, но я несколько раз писал в песочницу, однажды даже получил инвайт, и к моменту моей регистрации он уже был кем-то активирован. Руки опускаются уже туда писать.
Да и на хабре, вроде бы, не очень любят ранее опубликованные статьи и кросспосты.
freefd 06.12.2009 13:34 #
Жду Ваш email.
zivot_je_cudo 06.12.2009 13:36 #
Супер!
zivot_je_cudo 06.12.2009 14:33 #
http://zivot-je-cudo.habrahabr.ru/blog/77435/ - набрался духу и сделал запоздалый кросспост на хабр. Почитал правила - если топик написан своими руками, то все не так страшно :)
zivot_je_cudo 06.12.2009 20:46 #
Почитал правила - если топик написан своими руками, то все не так страшно
Плохо читал, забанили на две недели..
Minoru 05.12.2009 16:25 #
Спасибо огромное за статью!

В сетях не разбираюсь совершенно, так что было очень приятно прочесть простую, но в то же время полезную статью. Листинги обмена трафиком (это же tcpdump'ом делается, да?) и правила iptables я не осилил, но объяснения понял. В очередной раз убедился, что при сетевых проблемах в первую очередь надо пинговать :)

Ещё раз спасибо.
zivot_je_cudo 05.12.2009 16:34 #
Спасибо за отзыв)
Обмен трафиком - логи tcpdump, ага, а правила iptables, в принципе, можно было разобрать подробнее, но общего понимания iptables это все равно не даст. Хоть он и не сложный, но нужно хорошо представлять движение пакетов по его цепочкам, тогда можно легко строить интересные вещи, от портнокинга до l7-матчинга, который больше никакие ОС не умеют, только сверхдорогие железки циско =)
snowemo 05.12.2009 16:52 #
l7 вообще очень интересная тема.Вопросы были, когда писал тырилку паролей, пришлось написать http-прокси на python/twisted.
zivot_je_cudo 05.12.2009 17:01 #
Это чтобы снифать только пакеты авторизации?
snowemo 05.12.2009 17:30 #
ну, там надо было палить сначала путь, потом тырить post, а еще иногда дропать кукисы. :) до сих пор пытаюсь придумать формат для фильтров.
Minoru 05.12.2009 19:27 #
правила iptables, в принципе, можно было разобрать подробнее, но

…но не надо :) Это только отвлекало бы читателя, imho.

Вообще мне хотелось бы узнать о iptables чуток больше — здесь написал подробнее.