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

Зависание TCP-сессий с Debian и iptables

До сих пор я использовал компьютер CentOS 5.x с двумя сетевыми адаптерами, на которых запущен iptables, в качестве маршрутизатора для моей сети. Он работал отлично, но недавно я решил получить DreamPlug, который запускает Debian 5.0.3 / kernel 2.6.33.6, и использовать его для замены моего маршрутизатора CentOS. Я скопировал конфигурацию iptables и настроил интерфейсы таким же образом, а затем отключил их.

Казалось, все работает нормально, но потом я заметил, что мои сеансы tcp постоянно зависали от 1 до 10 секунд после инициализации соединения. Это приводило к тому, что сайты, которые не могли загрузиться почти сразу, зависали при загрузке. Загрузка файлов длилась пару секунд, а затем остановилась на неопределенное время. Несколько раз передача возобновлялась, но всего на пару секунд, а затем снова останавливалась.

На этом этапе я заменил свою конфигурацию iptables новой простой конфигурацией NAT ( http://pastebin.com/raw.php?i=bhLHk2wh ), чтобы исключить любые проблемы с настройкой брандмауэра. Я провел тест с wget на десятках разных веб-сайтов (GET /), а также загрузил файлы iso с нескольких разных зеркал. Проблема постоянно воспроизводилась независимо от того, откуда я скачивал. Я записал tcpdump для каждого из трех интерфейсов, через которые прошли данные, прежде чем покинуть мою сеть: внутренний сетевой адаптер хоста, внутренний сетевой адаптер межсетевого экрана, внешний сетевой адаптер межсетевого экрана. Не было никаких различий между пакетами на каждом интерфейсе (что я мог сказать). Ни один из пакетов не был заблокирован брандмауэром, что подтверждается журналами iptables.

Вот результат этого теста wget: http://pastebin.com/raw.php?i=qyXtE2rJ

Я не эксперт по tcp, поэтому мой анализ может оказаться элементарным, но я обнаружил, что сеанс tcp настроен правильно. Некоторые P-пакеты отправляются и подтверждаются, и внезапно пакеты начинают пропадать.

Вот дамп внешнего интерфейса (eth0) на межсетевом экране: http://pastebin.com/raw.php?i=q73b1rXZ

Есть несколько дублирующихся ACK для seq 3655108323, в то время как удаленный хост, похоже, все еще отправляет данные, которые не подтверждаются. Затем отправляется флаг R, и соединение зависает на пять минут в 16: 30: 32.310469, прежде чем я завершу сеанс, прервав wget. Также стоит отметить, что во время тестирования я наблюдал, как такое зависание начинается двумя разными способами.

  1. Флаг R будет отправлен с брандмауэра, и тогда больше пакетов с удаленного хоста не будет.
  2. Подтверждение без флага будет отправлено от брандмауэра, а затем больше пакетов от удаленного хоста не будет.

Единственная другая потенциальная проблема, которую я вижу, - это 272 пакета, которые были отброшены внешним интерфейсом fw. Я немного озадачен этим, потому что брандмауэр загружал файлы со скоростью 100 Мбит / с (внутренне), не беспокоясь. Эти небольшие соединения тривиальны, не должно быть отброшенных пакетов. Кроме того, я жестяная банка загружать файлы очень быстро при запуске wget из самого брандмауэра. Я получаю стабильную скорость более 1 Мбит / с (через Интернет). Вот сокращенная версия дампа: http://pastebin.com/raw.php?i=Fb9zhqh4

Вот дамп внутреннего интерфейса (eth1) на межсетевом экране: http://pastebin.com/raw.php?i=TuM4sTxB

Кажется, что ничего не изменилось во внутреннем интерфейсе и нет отброшенных пакетов.

Вот дамп интерфейса (en0) на моем внутреннем хосте (OS X): http://pastebin.com/raw.php?i=SSXHFqVf

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

В заключение, похоже, что происходит какой-то PL, но я не могу точно определить причину. Внешний дамп fw заставляет меня думать, что проблема существует на eth0, но тогда я могу легко wget файлы на самом брандмауэре (трафик проходит только через eth0), так что это не может быть. Есть ли у кого-нибудь предложения по дополнительным действиям по устранению неполадок, которые я могу предпринять, чтобы сузить потенциальные причины здесь?

Зависание TCP-соединений может означать, что у вас возникла проблема с MTU. Скорее всего, где-то на вашем пути есть устройство, которое блокирует фрагментацию ICMP необходимых пакетов.

Вы можете найти инструкции, как обойти это здесь: http://www.netfilter.org/documentation/HOWTO/netfilter-extensions-HOWTO-4.html#ss4.7.

Я бы рекомендовал определить максимальный MTU, который вы можете использовать

ping -M do -s MTU REMOTE_IP

(измените MTU с 1500 на меньшее, пока не найдете подходящее значение), а затем

iptables -I FORWARD -p tcp --tcp-flags SYN,RST SYN -j TCPMSS --set-mss MTU