Трёхстороннее рукопожатие
Трёхстороннее рукопожатие (англ. three-way handshake) — это процедура установления соединения в протоколах, работающих на транспортном уровне модели OSI, в частности в протоколе управления передачей (TCP, Transmission Control Protocol). Данный механизм обеспечивает синхронизацию порядковых номеров (sequence numbers) и подтверждение готовности к обмену данными между двумя узлами сети перед началом передачи полезной нагрузки. Трёхстороннее рукопожатие является обязательным этапом для установления надёжного, ориентированного на соединение канала связи в TCP.
История и происхождение
Протокол TCP был разработан в 1970-х годах в рамках проекта ARPANET (США) группой инженеров под руководством Винтона Серфа и Роберта Кана. Спецификация протокола была опубликована в 1981 году в документе RFC 793 (Transmission Control Protocol). В этом документе впервые детально описан механизм трёхстороннего рукопожатия как способ установления соединения с гарантированной доставкой данных.
Необходимость в таком механизме возникла из-за особенностей работы сетей с коммутацией пакетов, где пакеты могут приходить в произвольном порядке, задерживаться или дублироваться. Трёхстороннее рукопожатие позволяет двум сторонам согласовать начальные значения счётчиков последовательности (ISN, Initial Sequence Number), что критически важно для последующей сборки данных в правильном порядке и обнаружения потерь.
Принцип работы
Процесс трёхстороннего рукопожатия состоит из трёх последовательных шагов, в ходе которых клиент (инициатор соединения) и сервер (принимающая сторона) обмениваются сегментами с определёнными флагами в заголовке TCP. Основные используемые флаги: SYN (synchronize — синхронизация) и ACK (acknowledgement — подтверждение).
Шаг 1: SYN (Client → Server)
Клиент отправляет серверу сегмент TCP с установленным флагом SYN. В этом сегменте клиент указывает свой начальный порядковый номер (ISN_c), который выбирается случайным образом. Этот номер служит точкой отсчёта для всех последующих байтов данных, отправляемых клиентом. Поле «Порядковый номер» (Sequence Number) в заголовке устанавливается равным ISN_c.
Шаг 2: SYN-ACK (Server → Client)
Сервер, получив SYN-сегмент, отвечает клиенту сегментом, в котором установлены одновременно два флага: SYN и ACK. Этот сегмент выполняет две функции:
- Подтверждает получение SYN-сегмента от клиента. Для этого в поле «Номер подтверждения» (Acknowledgment Number) сервер указывает значение, равное ISN_c + 1.
- Передаёт собственный начальный порядковый номер (ISN_s), который также выбирается случайным образом. Поле «Порядковый номер» в этом сегменте устанавливается равным ISN_s.
Шаг 3: ACK (Client → Server)
Клиент, получив SYN-ACK-сегмент, отправляет серверу финальный сегмент с установленным флагом ACK. В этом сегменте:
- Поле «Номер подтверждения» устанавливается равным ISN_s + 1, что подтверждает получение SYN-сегмента от сервера.
- Поле «Порядковый номер» устанавливается равным ISN_c + 1 (так как первый байт данных уже был «потрачен» на SYN-сегмент).
После этого соединение считается установленным, и обе стороны могут начинать обмен данными. В некоторых реализациях клиент может сразу включить в этот сегмент первые данные прикладного уровня (например, HTTP-запрос), что называется «включением данных в ACK» (data in ACK).
Начальные порядковые номера (ISN)
Выбор начальных порядковых номеров (ISN) является критически важным для безопасности и надёжности соединения. В ранних реализациях TCP ISN выбирались по предсказуемому алгоритму (например, на основе времени), что делало протокол уязвимым для атак типа «предсказание порядкового номера» (TCP sequence prediction attack). В современных ОС (Linux, Windows, macOS) ISN генерируются с использованием криптостойких генераторов псевдослучайных чисел, что затрудняет их угадывание.
Роль в протоколах и приложениях
Трёхстороннее рукопожатие является основой для работы большинства интернет-протоколов прикладного уровня, работающих поверх TCP:
- HTTP/HTTPS: Каждый запрос к веб-серверу (за исключением HTTP/2 и HTTP/3 с мультиплексированием) требует установления нового TCP-соединения через трёхстороннее рукопожатие.
- SMTP: Отправка электронной почты.
- FTP: Передача файлов.
- SSH: Удалённое управление серверами.
- Telnet: Устаревший протокол удалённого доступа.
Влияние на производительность
Трёхстороннее рукопожатие вносит задержку (latency) перед началом передачи данных, равную одному полному времени кругового обхода (RTT, Round-Trip Time). Для коротких транзакций (например, загрузка небольшого изображения) эта задержка может составлять значительную часть общего времени соединения. Для снижения этого эффекта используются следующие методы:
- HTTP Keep-Alive: Повторное использование одного TCP-соединения для нескольких HTTP-запросов.
- TCP Fast Open (TFO): Механизм, позволяющий отправлять данные вместе с SYN-сегментом при повторном соединении с сервером, сокращая количество шагов до двух.
- Протокол QUIC: Работает поверх UDP и не требует трёхстороннего рукопожатия, что снижает задержку до 0 RTT при повторных соединениях.
Безопасность и уязвимости
Несмотря на свою надёжность, трёхстороннее рукопожатие может быть подвержено атакам:
- SYN-flood: Атака типа «отказ в обслуживании» (DoS), при которой злоумышленник отправляет большое количество SYN-сегментов с поддельными IP-адресами, не завершая рукопожатие. Сервер выделяет ресурсы на каждое полуоткрытое соединение, что может привести к исчерпанию памяти и отказу в обслуживании легитимных клиентов. Для защиты используются SYN-куки (SYN cookies), которые позволяют серверу не выделять ресурсы до получения третьего ACK-сегмента.
- TCP Reset attack: Атака, при которой злоумышленник отправляет поддельный RST-сегмент (reset — сброс) для разрыва существующего соединения.
- Предсказание порядковых номеров: Устаревшая атака, позволяющая злоумышленнику перехватывать или подменять сегменты.
Альтернативы и эволюция
В современных сетях, особенно в мобильных и высокоскоростных, трёхстороннее рукопожатие TCP считается избыточным. Протокол QUIC, разработанный компанией Google и стандартизированный IETF, использует UDP и устанавливает соединение за 1 RTT (или 0 RTT при повторном соединении). QUIC также включает в себя шифрование на уровне транспортного протокола, что делает его более безопасным и быстрым. Однако трёхстороннее рукопожатие остаётся основой для подавляющего большинства интернет-соединений, работающих по протоколу TCP.
Источники
- RFC 793 — Transmission Control Protocol (1981)
- RFC 7323 — TCP Extensions for High Performance
- RFC 7413 — TCP Fast Open
- Компьютерные сети. Принципы, технологии, протоколы (Олифер В.Г., Олифер Н.А.)
- TCP/IP Illustrated, Volume 1: The Protocols (W. Richard Stevens)
BFOmetr — база данных и аналитика по компаниям России.
На главную BFOmetr →