TCP, или Transmission Control Protocol (протокол управления передачей), – это сетевой протокол, ориентированный на поток, который был создан десятилетия назад. Сейчас он используется практически везде, подчеркивая, что иногда старые технологии все еще актуальны или даже необходимы сегодня. Потоково-ориентированный протокол абстрагирует детали и сложности отправки и получения сетевых пакетов. Он обрабатывает обнаружение потерянных, дублированных и неупорядоченных пакетов, чтобы обеспечить прикладной уровень плавным потоком байтов, отсюда и название “потоково-ориентированный протокол”.
В заголовке протокола TCP использует флаги для управления соединениями и потоками трафика. Краткое описание флагов TCP и их значений можно найти в следующей таблице:
Сокращение | Имя | Значение |
---|---|---|
SYN | Synchronization | Используется для создания TCP-соединения |
ACK | Acknowledgment | Используется для подтверждения приема данных или пакетов синхронизации |
PSH | Push | Проинструктируйте сетевые стеки обходить буферизацию |
URG | Urgent | Указывает на данные вне диапазона, которые должны быть обработаны сетевыми стеками перед обычными данными |
FIN | Finish | Корректное завершение TCP-соединения |
ПЕРВОЕ | Reset | Немедленно разорвите соединение и удалите все передаваемые данные |
В этом посте вы получите краткий обзор флагов TCP и объясните некоторые из их применений.
Обзор TCP
TCP построен поверх IP, или интернет-протокола. IP предназначен для отправки пакетов туда и обратно. IP-пакеты состоят из заголовка и полезной нагрузки. Заголовок содержит такую информацию, как исходный IP-адрес, IP-адрес назначения и протокол, используемый в полезной нагрузке (например, ICMP, UDP или TCP).
IP не обрабатывает вышедшие из строя, потерянные или дублирующиеся пакеты. В нем также нет понятия “соединения” в том смысле, что стек IP не способен логически группировать отправленные или принятые пакеты в соответствии с определенными критериями (например, логической конструкцией, которая является “соединением”, видимым прикладным уровнем). Таким образом, TCP строится поверх IP для обеспечения протокола, ориентированного на поток.
Для этого TCP устанавливает соединение между двумя одноранговыми узлами, используя флаги для установления такого соединения. Эта концепция соединения необходима для представления потока данных в виде непрерывного потока на обоих концах. После завершения связи соединение может быть закрыто с помощью флагов в заголовках пакетов TCP.
Поскольку протокол TCP требуется для обработки пакетов, которые вышли из строя, дублируются или потеряны, ему необходимо обнаруживать и переупорядочивать пакеты, а также повторно передавать пакеты. Управление этим потоком данных снова осуществляется с помощью флагов в заголовках TCP, а также счетчиков, которые мы обсудим более подробно в следующем разделе.
Установление соединения традиционным способом
TCP-соединение инициируется клиентом и проходит трехстороннее подтверждение связи, как показано ниже:
Вот типичная последовательность, где флаг TCP SYN означает “synchronize”, а ACK указывает на “acknowledgment”.:
- Клиент отправляет TCP-пакет на сервер с установленным флагом SYN.
- Сервер получает пакет, создает TBC (блок управления передачей) в своей памяти и отвечает TCP-пакетом с установленными флагами SYN и ACK.
- Клиент отвечает TCP-пакетом с установленным флагом ACK.
После этого обе стороны могут отправлять данные.
Следует отметить, что на шаге (2) выше серверу необходимо сохранить некоторую информацию о текущем соединении, чтобы иметь возможность обрабатывать пакет, который клиент отправляет на шаге (3). Это называется блоком управления передачей, и это делает сервер уязвимым для DoS-атаки (отказа в обслуживании).
Если злоумышленник отправляет SYN-пакет, сервер должен сохранять состояние этого соединения до тех пор, пока он либо не получит пакет подтверждения от клиента, либо не сочтет попытку подключения устаревшей и не удалит состояние. Следовательно, злоумышленник может отправить множество пакетов SYN для инициирования соединения, но никогда не отправит окончательный пакет ACK. Сервер будет накапливать огромное количество состояний, связанных с этими притворными соединениями, которые могут заполнить память сервера, приводя к отказу в законных соединениях. Эту атаку также иногда называют атакой SYN flood.
Установление соединения во избежание атаки syn flood
Есть способ смягчить эти атаки SYN flood.
Вместо сохранения состояния соединения в памяти сервер отправит свой пакет SYN + ACK со специально созданным порядковым номером N, который представляет необходимую ему информацию о соединении. Затем клиент ответит своим пакетом подтверждения, используя порядковый номер N + 1, и сервер сможет восстановить состояние соединения, используя этот порядковый номер:
Информация о состоянии, встроенная в порядковый номер, также называется “SYN cookie”, потому что ответ клиента содержит этот cookie, аналогичный HTTP cookies.
Поток данных после установления соединения
Флаг ACK
После установления соединения данные отправляются и подтверждаются обеими сторонами. Каждый одноранговый узел в соединении поддерживает пару счетчиков:
- Счетчик последовательности, который подсчитывает количество отправленных байтов
- Счетчик подтверждения, который подсчитывает количество полученных байт
Следующая схема последовательности действий иллюстрирует, как это работает:
Количество байтов, которые были отправлены, но еще не подтверждены, называется “окном TCP”. На самом деле существует два окна TCP, по одному для каждого однорангового узла в TCP-соединении. На диаграмме выше окно TCP перед последним пакетом с правой стороны составляет 90 байт. Размер окон TCP ограничен 65 535 байтами в исходной спецификации TCP, но его можно увеличить с помощью расширений TCP.
Пакет с установленным флагом ACK используется для подтверждения байтов, полученных одноранговым узлом. Он используется в сочетании со счетчиком подтверждения для информирования другого однорангового узла о последних полученных байтах. Затем эта информация используется для определения, были ли потеряны некоторые пакеты, и в этом случае отправляющий узел повторно передаст потерянные пакеты.
Флаги PSH и URG
При отправке данных любая сторона в TCP-соединении может дополнительно использовать флаги PSH и URG (которые соответственно означают ”push“ и “urgent”). Флаги PSH предписывают операционной системе немедленно отправлять (для отправляющей стороны) и получать (для принимающей стороны) данные. Другими словами, этот флаг предписывает сетевому стеку операционной системы немедленно отправлять/получать все содержимое своих буферов.
Без этого флага операционная система может решить подождать, прежде чем отправлять или передавать полученные данные приложению, потому что она хочет дождаться отправки или получения большего количества данных, чтобы максимально использовать ресурсы хоста и сети. Однако некоторые приложения хотели бы, чтобы данные отправлялись и принимались как можно скорее, например, с помощью сеанса SSH или в конце HTTP-запроса или ответа.
Флаг URG используется для сигнализации о “urgent” данных, которым следует отдать приоритет перед несрочными данными. Это используется для отправки так называемых “внеполосных данных”, которые особым образом обрабатываются операционной системой и обычно сигнализируют о каком-либо исключении в прикладном протоколе. Обратите внимание, что на практике эта функция TCP используется редко.
Завершение соединения
Изящное завершение
Один одноранговый узел TCP-соединения может сигнализировать другому, что он хочет разорвать соединение, отправляя пакет с флагом FIN. Затем другая сторона подтверждает это, отправляя пакет с установленными флагами FIN и ACK, и может продолжить прерывание соединения на своей стороне.
Когда соединение прерывается, любые буферизованные или транзитные данные по-прежнему будут обрабатываться. Фактически, любому одноранговому узлу, который не отправил пакет FIN, по-прежнему разрешено отправлять данные. На практике это встречается редко, поскольку протокол более высокого уровня (например, HTTP) обычно имеет свой собственный механизм, сигнализирующий о завершении соединения и о том, что ни одна из сторон больше не нуждается в отправке данных.
Прерывание соединения
Любая сторона TCP-соединения может принять решение прервать соединение. Это делается, когда рассматриваемый одноранговый узел считает, что соединение не должно существовать по какой-либо причине. В таком случае один одноранговый узел отправляет пакет с установленным флагом RST. Другой одноранговый узел, получив пакет RST, должен немедленно прекратить отправку любых данных.
Когда соединение прерывается таким образом, данные в пути и буферизованные данные теряются. Таким образом, существует вероятность потери данных, но это не должно быть проблемой, если это соединение изначально было недействительным. Пакеты RST редки в реальной жизни и, вероятно, используются скорее для неблаговидных целей, чем для законных.
Краткое описание таблицы
Различия между FIN и RST сведены в таблицу ниже:
FIN | RST | |
---|---|---|
Завершение соединения | Graceful | Abortion |
Процесс завершения | 4-стороннее рукопожатие | Немедленно закрывает соединение |
Буферизованные данные | Transmitted | Dropped |
Типичное использование | Обычные TCP-соединения | Ошибки, атаки или необычные события, происходящие в соединении |
Анализируйте флаги TCP в командной строке с помощью Tcpdump
Большинство сетевых инженеров знают о tcpdump, инструменте командной строки для сбора сетевого трафика. Он универсален и, фактически, не ограничивается TCP, несмотря на его вводящее в заблуждение название.
Вот команда, которую мы можем использовать для генерации некоторого сетевого трафика:
$ curl http://google.com
Команда tcpdump, выполняемая в отдельном терминале, выдаст следующий результат:
$ sudo tcpdump -i any host google.com tcpdump: verbose output suppressed, use -v or -vv for full protocol decode listening on any, link-type LINUX_SLL (Linux cooked v1), capture size 262144 bytes 07:23:41.829027 IP thinkpad.58400 > lhr48s09-in-f14.1e100.net.http: Flags [S], seq 479485488, win 64240, options [mss 1460,sackOK,TS val 2441158056 ecr 0,nop,wscale 7], length 0 07:23:41.846135 IP lhr48s09-in-f14.1e100.net.http > thinkpad.58400: Flags [S.], seq 1617638117, ack 479485489, win 65160, options [mss 1357,sackOK,TS val 2779514051 ecr 2441158056,nop,wscale 8], length 0 07:23:41.846163 IP thinkpad.58400 > lhr48s09-in-f14.1e100.net.http: Flags [.], ack 1, win 502, options [nop,nop,TS val 2441158073 ecr 2779514051], length 0 07:23:41.846234 IP thinkpad.58400 > lhr48s09-in-f14.1e100.net.http: Flags [P.], seq 1:75, ack 1, win 502, options [nop,nop,TS val 2441158073 ecr 2779514051], length 74: HTTP: GET / HTTP/1.1 07:23:41.860886 IP lhr48s09-in-f14.1e100.net.http > thinkpad.58400: Flags [.], ack 75, win 255, options [nop,nop,TS val 2779514067 ecr 2441158073], length 0 07:23:41.884595 IP lhr48s09-in-f14.1e100.net.http > thinkpad.58400: Flags [P.], seq 1:529, ack 75, win 255, options [nop,nop,TS val 2779514090 ecr 2441158073], length 528: HTTP: HTTP/1.1 301 Moved Permanently 07:23:41.884616 IP thinkpad.58400 > lhr48s09-in-f14.1e100.net.http: Flags [.], ack 529, win 501, options [nop,nop,TS val 2441158112 ecr 2779514090], length 0 07:23:41.884782 IP thinkpad.58400 > lhr48s09-in-f14.1e100.net.http: Flags [F.], seq 75, ack 529, win 501, options [nop,nop,TS val 2441158112 ecr 2779514090], length 0 07:23:41.906850 IP lhr48s09-in-f14.1e100.net.http > thinkpad.58400: Flags [F.], seq 529, ack 76, win 255, options [nop,nop,TS val 2779514112 ecr 2441158112], length 0 07:23:41.906877 IP thinkpad.58400 > lhr48s09-in-f14.1e100.net.http: Flags [.], ack 530, win 501, options [nop,nop,TS val 2441158134 ecr 2779514112], length 0 07:23:41.922266 IP lhr48s09-in-f14.1e100.net.http > thinkpad.58400: Flags [R], seq 1617638647, win 0, length 0 ^C 11 packets captured 19 packets received by filter 0 packets dropped by kernel
Tcpdump показывает флаги TCP в скобках после ключевого слова “Flags”. Tcpdump дает только сокращения, которые являются:
- “S” для SYN
- ”.” (одна точка) для ACK
- “P” для PSH
- “F” для FIN
- “R” для RST
Мы можем видеть, что первые три пакета представляют собой последовательность SYN, SYN/ACK, ACK, используемую для установления соединения. Следующий пакет отправляет некоторые HTTP-данные на сервер Google, и для него установлен флаг PSH, указывающий операционной системе немедленно отправить данные.
Затем Google отвечает пустым пакетом с установленным флагом подтверждения, за которым следует другой пакет с фактическим HTTP-ответом. Это кажется немного расточительным, поскольку сервер мог отправить только один пакет. Затем клиентская сторона отвечает пакетом с установленным флагом подтверждения, но без данных, что и ожидалось.
Наконец, мы можем увидеть четырехстороннее подтверждение связи FIN/ACK для завершения соединения. Интересно, что сервер Google также отправляет пакет RST после корректного завершения работы, что, вероятно, сделано для того, чтобы гарантировать, что плохо написанные клиенты действительно отключат соединение на своем конце.
Заключение
Сетевые инженеры и эксперты по безопасности должны хорошо разбираться в флагах TCP и в том, как они используются. Это неотъемлемая часть понимания и анализа сетевого трафика.