По мере накопления опыта troubleshooting’а TCP-соединений вы начинаете замечать, что некоторые паттерны повторяются снова и снова. Поэтому не ленитесь запоминать или записывать свой опыт, это может очень сильно сэкономить время в будущем.
Недавно я столкнулся с одной интересной проблемой установления TCP-соединения.
Посмотрите на рисунок ниже:
Разберем подробно, что происходит. Видим, что клиент (IP 192.168.1.1) успешно выполняет 3-way handshake с FTP-сервером (IP 10.0.0.1), но внезапно, ещё перед тем, как получает хоть какую-то возможность передать команду, сервер ни с того ни с сего закрывает соединение (пакет 4).
Отсюда возникает вопрос: почему сервер позволил успешно завершить 3-way handshake, но не дал клиенту никакой возможности «говорить» дальше?
Давайте подумаем, что могло бы быть причиной:
- Последний АСК-пакет от клиента в 3-way handshake был каким-то образом поврежден, что привело к обрыву соединения.
- FTP сервер достиг порога по количеству подключений и не захотел принять ещё одно.
- FTP-приложение на сервере «упало» сразу же после того, как соединение было принято.
- Серверу не понравился наш (клиента) IP-адрес.
Углубимся в каждое из наших предположений. Итак:
Последний АСК-пакет от клиента в 3-way handshake мог быть поврежденным
Звучит интересно, но это маловероятно. Начнем с того, что 3-way handshake вообще редко когда сбоит, и я никогда не видел, чтобы этот процесс сбоил именно таким образом. Расчет sequence и acknowledgement полей – это не особо высшая математика, по крайней мере для компьютера (когда я провожу занятия по Wireshark, зачастую эта задача невероятно трудна для слушателей), поэтому мы можем предположить, что с этим проблем не было. Действительно, со всеми sequence–полями на скрине вверху все отлично. Но даже если бы и не было отлично, сервер не закрыл бы соединение «мягко» (с помощью FIN-флага), а сбросил бы его RST’ом. Но это не подтверждается.
FTP сервер достиг порога по количеству подключений
Возможно, сервер имел заданный максимум количества одновременных подключений и достиг его как раз на нашем соединении (ну, не повезло). Это возможный сценарий, но обычно FTP-сервер в подобном случае отвечает специальном кодом ошибки FTP 412 «too many connections». Это гораздо «вежливее» со стороны сервера, и при этом пользователь будет знать, в чем была причина ошибки. Ну и также это удержит пользователя от бесконечных попыток как сумасшедший подключаться снова и снова (гарантий, конечно, никаких). То есть, нет, это не наш случай, по крайней мере, в этот раз. Поехали дальше.
FTP-приложение на сервере «упало»
Могло ли случиться так, что приложение на сервере попросту «упало»? В общем, нет. То есть, конежно же, приложение могло упасть, но в нашем случае не похоже. Во-первых, потому, что другие соеднинения на этот же сервер продолжили работать нормально и не сбросились. Мы не видим этого в дампе трафика, но это было видно в логах на самом сервере. Во-вторых, что более важно, когда приложение «падает», оно освобождает сокет, который был открыт в ОС. Ну, и опять же, когда это происходит, мы увидим отправленный TCP-стеком RST, но не FIN. Значит, и не падение.
Серверу не понравился наш IP-адрес
Может, серверу просто не понравился адрес, с которого открыли соединение. Но если бы это было правдой, зачем было разрешать нам полностью завершить 3-way handshake, ведь можно было просто сбросить наш SYN своим RST-пакетом? А вот тут давайте разберемся подробнее о функциях и разнице между ТСР-стеком и самим приложением. Заниматься 3-way handshake’ом – это задача ОС.
А приложение FTP-сервера узнаёт о новом соединении только после того, как TCP стек завершил свою часть работы в установке соединения. То есть, сначала приветствие должно произойти, а уже потом FTP приложение его может увидеть и среагировать реагировать каким-либо образом. И именно в FTP-софте был прописан «белый» список допустимых адресов. Естественно, после установки соединения началась проверка на соответствие списку. И как только сервер увидел, что наш IP не входит в белый список, он показал нам, где находится дверь на выход. Именно поэтому мы и видели FIN – сокет не был внезапно освобожден, как случилось бы в случае падения приложения, он тихо-спокойно закрылся (конечно, нам как пользователю это мало чем помогло, потому что никакого диагностического сообщения не появилось).
Подводим черту: если вы видите TCP-соединение, которое ведет себя как в этом случае, найдите администратора, ответственного за данный сервис, и передайте ему, чтобы проверил, как настроены черные и белые списки.
(Кстати, обратите внимание – всего 6 строчек дампа оказалось достаточно для диагностики проблемы.- прим.перев.)
Статья переведена и опубликована с разрешения автора (Jasper Bongertz) только для сайта packettrain.net
Использование материала статьи без согласования запрещено!
Оригинал статьи находится по адресу: https://blog.packet-foo.com/2014/01/tcp-server-slamming-the-door/
This article has been translated and published with author’s (Jasper Bongertz) permission. For packettrain.net website only.
Original article can be found at: https://blog.packet-foo.com/2014/01/tcp-server-slamming-the-door/
2