Помню, когда после окончания университета я проходил собеседование при приеме на работу, меня часто спрашивали: «Знаешь ли ты «3 рукопожатия и 4 волны»? В это время я "с уверенностью" продекламирую" подготовленные на предыдущем этапе "ответы". Что получилось в первый раз, во второй раз... После ответа текста больше нет, и интервьюер не вроде есть намерение идти дальше.. буду углубляться.. не знаю, все довольны!
Как программист, вы должны иметь дух «докопаться до сути вещей». Если вы это знаете, вы должны знать, почему. В этой статье мы надеемся раздеть кокон и восстановить лежащий в его основе принцип. [ссылка]
Что такое «3 рукопожатия, 4 волны»
TCP — это протокол одноадресной рассылки, ориентированный на установление соединения.Перед отправкой данных обе стороны должны установить соединение друг с другом. Так называемое «соединение» на самом деле представляет собой часть информации друг о друге, хранящуюся в памяти клиента и сервера, такую как IP-адрес, номер порта и т. д.
TCP можно рассматривать как поток байтов, который обрабатывает потерю пакетов, дублирование и ошибки на уровне IP или ниже. В процессе установления соединения обе стороны должны обменяться некоторыми параметрами соединения. Эти параметры могут быть помещены в заголовок TCP.
TCP предоставляет надежную, ориентированную на соединение службу транспортного уровня с потоком байтов, которая использует трехстороннее рукопожатие для установления соединения. Используйте 4 волны, чтобы закрыть соединение.
Сервисная модель TCP
После понимания установлено соединение, закройте подключение «трехстороннего рукопожатия и четыре размахивания», мы посмотрим на вещами, связанные с TCP.
TCP-соединение состоит из четырех кортежей, состоящих из двух IP-адресов и двух номеров портов. TCP-соединение обычно делится на три фазы: инициация, передача данных и выход (закрытие).
Когда TCP получает данные с другого конца, он отправляет подтверждение, но это подтверждение отправляется не сразу, обычно с задержкой. ACK являются кумулятивными, ACK, подтверждающий байт с номером N, указывает, что все байты до N (исключая N) были успешно получены. Преимущество этого заключается в том, что если ACK будет потерян, вполне вероятно, что последующих ACK будет достаточно для подтверждения предыдущих сегментов.
Полное TCP-соединение является двунаправленным и симметричным, и данные могут передаваться одинаково в обоих направлениях. Предоставьте приложению верхнего уровня双工服务
. Как только соединение установлено, каждый сегмент TCP в одном направлении соединения содержит ACK для сегмента в противоположном направлении.
Назначение порядкового номера — позволить получателю TCP отбрасывать повторяющиеся сегменты и записывать сегменты, поступающие в случайном порядке. Потому что TCP использует IP для передачи сегментов, а IP не обеспечивает устранение дублирования и не гарантирует правильную функцию порядка. С другой стороны, TCP представляет собой протокол потока байтов и никогда не отправляет данные программам верхнего уровня в случайном порядке. Поэтому получатель TCP вынужден удерживать данные с большими порядковыми номерами от приложения до тех пор, пока не будут заполнены недостающие сегменты с маленькими порядковыми номерами.
TCP-заголовок
Исходный порт и порт назначения определяют оба процесса на слое TCP. Номер последовательности указывает на первый номер байта в данных сегмента, и ACK указывает номер подтверждения. Отправитель номера подтверждения ожидает получить следующий порядковый номер, что Количество последовательностей последнего успешно полученного байта данных увеличивается на 1. Это поле действители только при включении бита ACK.
Когда создается новое соединение, активируется бит SYN первого сегмента, отправленного клиентом на сервер.Это называется сегментом SYN.В это время поле порядкового номера содержит информацию, которая будет использоваться в этом направлении соединения. соединения Первый серийный номер , начальный серийный номерISN
, данные, отправляемые после этого, представляют собой ISN плюс 1, поэтому битовое поле SYN будет消耗
Порядковый номер, означающий надежную передачу с использованием повторной передачи. ACK, которые не используют порядковый номер, не являются таковыми.
Длина заголовка (смещение данных на рисунке) указана в единицах 32-битных слов, то есть в единицах по 4 байта.У него всего 4 бита и максимум 15. Следовательно, максимальная длина заголовка равна 60 байт, а минимальный 5. То есть минимальный заголовок 20 байт (опции переменной пустые).
ACK - Подтверждение, делающее номер подтверждения действительным. RST - соединение сброса (часто встречающееся сбросом узлом) является тенью этого поля. SYN — серийный номер, используемый для инициализации соединения. FIN — отправитель этого сегмента завершил отправку данных другой стороне.
Когда соединение устанавливается или разрывается, обмениваемые сегменты содержат только заголовки TCP, но не данные.
Переход состояния
Переход состояния трехэтапного рукопожатия и четырехэтапной волны показан на рисунке ниже.
Почему «Три рукопожатия, четыре волны»
трехстороннее рукопожатие
Еще один простой для понимания взгляд на то, почему существует трехстороннее рукопожатие.
Клиент и сервер должны быть соединены перед общением.Функция «3-стороннего рукопожатия» заключается в双方都能明确自己和对方的收、发能力是正常的
.
第一次握手
: клиент отправляет сетевой пакет, а сервер его получает. Таким образом, сервер может прийти к выводу, что возможности клиента по отправке и возможности сервера по приему являются нормальными.
第二次握手
: сервер отправляет пакет, а клиент его получает. Таким образом, клиент может прийти к выводу, что возможности приема и отправки сервера и возможности приема и отправки клиента являются нормальными.
С точки зрения клиента я получил ответный пакет, отправленный сервером, что указывает на то, что сервер получил сетевой пакет, который я отправил во время первого рукопожатия, и успешно отправил ответный пакет, что означает, что возможности сервера по приему и отправке нормальный. С другой стороны, я получил ответный пакет от сервера, указывающий, что сетевой пакет, который я отправил в первый раз, успешно прибыл на сервер Таким образом, мои собственные возможности отправки и получения также в норме.
第三次握手
: клиент отправляет пакет, а сервер его получает. Таким образом, сервер может сделать вывод, что возможности приема и отправки клиента и возможности отправки и получения сервера являются нормальными.
После первого и второго рукопожатия сервер не знает, являются ли нормальными возможности клиента по приему и его собственные возможности по отправке. Во время третьего рукопожатия сервер получает ответ клиента на второе рукопожатие. С точки зрения сервера данные ответа, которые я отправил во время второго рукопожатия, были отправлены, и клиент их получил. Итак, моя способность посылать в норме. Принимающая способность клиента также в норме.
После описанного выше процесса трехэтапного рукопожатия и клиент, и сервер подтвердили, что их возможности приема и отправки в норме. Тогда вы сможете нормально общаться.
Каждый раз, когда сторона, получающая пакет данных, может сделать какие-то выводы, отправляющая сторона на самом деле понятия не имеет. Хотя у меня есть действие по отправке пакета, как я узнаю, отправил ли я его и получил ли его другая сторона?
Как видно из приведенного выше процесса, требуется как минимум трехсторонний процесс рукопожатия. Эти двое не смогли прийти к выводу, что их собственные и чужие возможности приема и отправки в норме. На самом деле каждый раз сторона, которая получает сетевой пакет, может, по крайней мере, получить его: отправка другой стороны и наше получение в норме. И каждый шаг связан, следующий «ответ» инициируется первым «запросом», так что каждое рукопожатие фактически может получить дополнительные выводы. Например, во время третьего рукопожатия сервер получает пакет данных, что указывает на то, что сервер может получить только возможность отправки клиента, а возможность получения сервера нормальная, но в сочетании со вторым разом это указывает на отправленный ответ. сервером во второй раз.Клиент принимает и отвечает на пакет, чтобы получить дополнительный вывод: прием клиентом и передача сервером в норме.
Резюмируя с таблицей:
перспектива | квитанция клиента | Гостевые волосы | плата за обслуживание | обслуживание волос |
---|---|---|---|---|
объективная перспектива | два | один + два | один + два | два |
Перспектива обслуживания | два + три | один | один | два + три |
помахал четыре раза
TCP-соединение — это одноранговый режим двунаправленной передачи, что означает, что обе стороны могут отправлять или получать данные друг другу одновременно. Когда одна сторона хочет закрыть соединение, она отправляет инструкции, чтобы сообщить другой стороне, что я хочу закрыть соединение. В это время другая сторона вернет ACK, и в это время соединение в одном направлении будет закрыто. Тем не менее, другое направление все еще может продолжать передавать данные.После того, как все данные будут отправлены, будет отправлен сегмент FIN, чтобы закрыть соединение в этом направлении. Получатель отправляет ACK для подтверждения закрытия соединения. Обратите внимание, что сторона, получающая сообщение FIN, может ответить только ACK, она не может немедленно вернуть сегмент сообщения FIN другой стороне, потому что «команда» на прекращение передачи данных дается верхним прикладным уровнем, я просто "носильщик" ", я не могу понять“上层的意志”
.
Как сделать "Три рукопожатия, четыре волны"?
На самом деле цель 3-стороннего рукопожатия состоит не только в том, чтобы сообщить обеим сторонам, что соединение устанавливается, но и в том, чтобы использовать опции пакета данных для передачи специальной информации и обмена начальным порядковым номером ISN.
3-стороннее рукопожатие означает, что отправляются 3 сегмента, а 4-стороннее рукопожатие означает, что отправляются 4 сегмента. Обратите внимание, что сегменты SYN и FIN надежно передаются с использованием повторных передач.
трехстороннее рукопожатие
- Клиент отправляет сегмент SYN, указывающий начальный номер последовательности клиента, который является ISN (C).
- Сервер отправляет свой собственный сегмент SYN в качестве ответа, также указывая свои собственные ISN. Чтобы подтвердить SYN клиента, используйте ISN(c)+1 в качестве значения ACK. Таким образом, каждый раз при отправке SYN порядковый номер будет увеличиваться на 1. В случае потери он будет передан повторно.
- Чтобы подтвердить SYN на стороне сервера, клиент использует ISN(s)+1 в качестве возвращаемого значения ACK.
помахал четыре раза
- Клиент отправляет сегмент FIN и содержит текущий порядковый номер K, который хочет видеть получатель, а также ACK для подтверждения последних данных, отправленных другой стороной.
- Сервер добавляет 1 к значению K в качестве значения порядкового номера ACK, указывая, что предыдущий пакет был получен. В это время приложение верхнего уровня будет проинформировано о том, что другой конец инициировал операцию закрытия, что обычно заставляет приложение инициировать собственную операцию закрытия.
- Сервер инициирует свой собственный сегмент FIN, ACK=K+1, Seq=L
- Клиент подтверждает. ПОДТВЕРЖДЕНИЕ=L+1
Почему для установления соединения требуется трехстороннее рукопожатие, а для закрытия — четырехстороннее?
Это связано с тем, что сервер в состоянии LISTEN после получения сообщения SYN для запроса на установление соединения отправляет ACK и SYN в одном сообщении клиенту. Когда соединение закрыто, когда получено сообщение FIN от другой стороны, это означает только то, что другая сторона больше не отправляет данные, но все еще может получать данные.Закрывает ли сторона канал отправки данных, теперь должно быть определено верхним -уровня приложения, поэтому ACK и FIN другой стороны обычно отправляются отдельно.
«Три рукопожатия, четыре волны» продвинутый
ISN
Важная функция трехэтапного рукопожатия заключается в том, что клиент и сервер обмениваются ISN (начальным порядковым номером), чтобы другая сторона знала, как собрать данные в соответствии с порядковым номером при следующем получении данных.
Если ISN фиксирован, злоумышленнику легко угадать последующие номера подтверждения.
ISN = M + F(localhost, localport, remotehost, remoteport)
M - таймер, плюс 1 каждые 4 миллисекунда. F - это хеш-алгоритм, в соответствии с исходным IP, назначения IP, Source Port, порт назначения генерирует значение случайного числа. Для обеспечения того, чтобы хеш-алгоритм нельзя легко экстраполировать снаружи.
Серийный номер перемотки
Поскольку ISN является случайным, серийный номер легко превысит 2 ^ 31-1. Оценка tcp для таких проблем, как потеря пакетов и беспорядок, зависит от сравнения серийного номера. В этот момент возникает так называемая проблема переноса порядкового номера tcp. Как с этим бороться?
/*
* The next routines deal with comparing 32 bit unsigned ints
* and worry about wraparound (automatic with unsigned arithmetic).
*/
static inline int before(__u32 seq1, __u32 seq2)
{
return (__s32)(seq1-seq2) < 0;
}
#define after(seq2, seq1) before(seq1, seq2)
Приведенный выше код — это код в ядре для решения проблемы циклического переноса. __s32 означает целое число со знаком, а __u32 означает целое число без знака. После переноса серийного номера серийный номер становится меньше.После вычитания результат становится числом со знаком, поэтому результат становится отрицательным числом.
假设seq1=255, seq2=1(发生了回绕)。
seq1 = 1111 1111 seq2 = 0000 0001
我们希望比较结果是
seq1 - seq2=
1111 1111
-0000 0001
-----------
1111 1110
由于我们将结果转化成了有符号数,由于最高位是1,因此结果是一个负数,负数的绝对值为
0000 0001 + 1 = 0000 0010 = 2
因此seq1 - seq2 < 0
син-флуд атака
Самая простая атака DoS заключается в использовании разумных запросов на обслуживание, чтобы занять слишком много ресурсов службы, чтобы законные пользователи не могли получить ответы службы. Synflood — это разновидность Dos-атаки.
Если большое количество SYN-пакетов злонамеренно отправлено на порт сервера, сервер может открыть большое количество полуоткрытых соединений и выделить TCB (блок управления передачей), тем самым потребляя большое количество ресурсов сервера и выполняя обычные запросы на соединение. невозможно ответить.. Когда порт TCP открыт, порт находится в состоянии прослушивания, и сообщение Syn, отправляемое на порт, постоянно отслеживается.После получения сообщения Syn, отправленного клиентом, для запроса необходимо выделить TCB, обычно TCB.TCB требуется не менее 280 байт, а в некоторых операционных системах для TCB требуется даже 1300 байт, и он возвращает команду SYN ACK, которая немедленно переходит в SYN-RECEIVED, то есть полуоткрытое состояние соединения. В системе закончатся ресурсы для этого.
Общие методы защиты от атак включают:
Выпуск монитора для недопустимых подключений
Контролируйте систему на наличие полуоткрытых и неактивных соединений и разрывайте эти соединения при достижении определенного порога, тем самым высвобождая системные ресурсы. Этот метод обрабатывает все соединения одинаково, и из-за большого количества полуоткрытых соединений, вызванных SYN Flood, обычные запросы на соединение также погружаются и освобождаются таким образом по ошибке, поэтому этот метод относится к методу SYN Flood начального уровня.
Метод отложенного распределения TCB
Основная причина потребления ресурсов сервера заключается в том, что при поступлении пакета данных SYN система сразу же выделяет TCB, тем самым занимая ресурсы. Однако, поскольку SYN Flood сложно установить нормальное соединение, он может эффективно снизить потребление ресурсов сервера за счет выделения TCB после установления обычного соединения. Распространенным методом является использование технологий Syn Cache и Syn Cookie.
Технология кэширования синхронизации
Когда система получает сообщение SYN, она сохраняет эту информацию о полусоединении в специальной таблице HASH до тех пор, пока не получит правильный ответ на сообщение ACK, а затем выделяет TCB. Эти накладные расходы намного меньше, чем у TCB. Конечно, вам также необходимо сохранить серийный номер.
Технология Syn Cookie
Технология Syn Cookie вообще не использует ресурсы хранения, этот метод более умный, он использует специальный алгоритм для генерации Sequence Number, который учитывает фиксированную информацию об IP-адресе другой стороны, порте, собственном IP-адресе, порте и другая сторона не может. Зная некоторую относительно фиксированную информацию, такую как MSS (максимальный размер сегмента, максимальный размер сегмента, относится к максимальной длине дейтаграммы пакета TCP, которая не включает длину заголовка TCP.), время и т. д., после получения другой стороны. После получения сообщения ACK пересчитайте его снова, чтобы увидеть, совпадает ли оно с (Порядковый номер-1) в ответном сообщении другой стороны, чтобы решить, следует ли выделять Ресурсы УТС.
Использование SYN-прокси-брандмауэра
Один из способов — предотвратить действительность соединения dqywb до того, как брандмауэр инициирует запрос SYN на внутренний сервер. Серийный номер, используемый пакетом SYN ACK, отправленным брандмауэром от имени сервера, равен c, а серийный номер, полученный реальным сервером, — c'. Таким образом, серийный номер изменяется, когда каждый пакет данных проходит через брандмауэр. Другой способ заключается в том, что после того, как брандмауэр определит безопасность соединения, он выдаст команду безопасного сброса, клиент повторно подключится, а появившееся в это время сообщение о синхронизации будет выпущено напрямую. Таким образом, нет необходимости менять серийный номер. Однако клиент должен инициировать процесс двустороннего рукопожатия, поэтому время установления соединения будет увеличено.
очередь соединений
Когда поступает внешний запрос, соединение может находиться в состоянии SYN_RCVD или в состоянии ESTABLISHED, но не быть принятым приложением до тех пор, пока оно окончательно не будет воспринято сервером.
Соответственно, сервер также поддерживает два вида очередей, очередей Syn_RCVD Queue Semijoins, но еще не в установленном состоянии не принимает приложения для всей очереди соединения. Если после того, как две очереди заполнены, будет множество ситуаций потери пакета.
查看是否有连接溢出
netstat -s | grep LISTEN
Очередь полусоединений заполнена
В протоколе трехстороннего рукопожатия сервер поддерживает очередь полусоединения, которая открывает запись для каждого SYN-пакета клиента (когда сервер получает SYN-пакет, структура request_sock создается и сохраняется в очереди полусоединения) , эта запись указывает, что сервер получил пакет SYN и отправил подтверждение клиенту, ожидая пакета подтверждения от клиента. Соединение, идентифицируемое этими записями, находится на сервере в состоянии Syn_RECV.Когда сервер получает пакет подтверждения от клиента, запись удаляется, и сервер переходит в состояние ESTABLISHED.
В настоящее время Linux по умолчанию повторно передает пакет SYN-ACK 5 раз, интервал повтора начинается с 1 с, следующий интервал повтора удваивается по сравнению с предыдущим, а интервал 5 повторов составляет 1 с, 2 с, 4 с, 8 с, 16 с, 31 с в Всего, называется
指数退避
, потребуется 32 с, чтобы узнать, что 5-й раз также истек после 5-го раза, поэтому требуется всего 1 с + 2 с + 4 с + 8 с + 16 с + 32 с = 63 с, прежде чем TCP разорвет соединение. Поскольку тайм-аут SYN занимает 63 секунды, злоумышленник получает возможность атаковать сервер.Атакующий отправляет большое количество SYN-пакетов на сервер за короткое время (широко известная как SYN-атака), чтобы исчерпать очередь SYN сервера. . Чтобы решить проблему слишком большого количества SYN, linux предоставляет несколько параметров TCP: tcp_syncookies, tcp_synack_retries, tcp_max_syn_backlog, tcp_abort_on_overflow для настройки ответа.
параметр | эффект |
---|---|
tcp_syncookies | Информация о соединении, закодированная с помощью SYNcookie, возвращается клиенту в ISN (initialsequencenumber), сервер половины времени не должен храниться в очереди соединений, а путем сокращения информации о соединении ISN для клиента, а затем отправляется обратно ACK для завершения установленного соединения, избегая атаки semijoin Очередь пакетов SYN заполнена. |
tcp_syncookies | Номер пакета SYN отправляется до того, как ядро будет отброшено. |
tcp_synack_retries | Количество пакетов SYN+ACK, отправленных ядром перед разрывом соединения |
tcp_max_syn_backlog | По умолчанию 1000. Это представляет собой длину очереди полуобъединения, если она превышает текущее соединение, оно будет отброшено. |
tcp_abort_on_overflow | Если этот пункт установлен, сбросьте его напрямую, в противном случае ничего не делайте, чтобы, когда очередь полусоединений сервера опустеет, соединение было принято повторно.Linux坚持在能力许可范围内不忽略进入的连接 . В течение этого периода клиент будет повторно отправлять sys-пакет, когда количество повторных попыток достигнет верхнего предела, он получитconnection time out отклик. |
Полная очередь соединений заполнена
Во время третьего рукопожатия, когда сервер получает пакет ACK, он войдет в новую очередь с именем accept.
Когда очередь принятия заполнена, даже если клиент продолжает отправлять ACK-пакеты на сервер, он не будет отвечать.В это время ListenOverflows+1, и сервер решает, как вернуться через tcp_abort_on_overflow.0 означает прямое отбрасывание пакета. ACK, 1 означает отправить клиенту уведомление RST, соответственно клиент вернетread timeout
илиconnection reset by peer
. Кроме того, если tcp_abort_on_overflow равен 0, сервер снова отправляет синхронизацию клиенту через некоторое время (то есть снова второй шаг рукопожатия). аномальный. Когда клиент получает несколько пакетов SYN ACK, он считает, что предыдущие пакеты ACK потеряны. Таким образом, клиенту предлагается снова отправить ACK, и соединение окончательно завершается, когда очередь приема освобождается. Если очередь принятия всегда заполнена, конечный клиент получает RST-пакет (в это время количество раз, когда сервер отправляет syn+ack, превышает tcp_synack_retries).
Сервер просто создает таймер для повторной передачи синхронизации и подтверждения на сервер через фиксированные промежутки времени.
параметр | эффект |
---|---|
tcp_abort_on_overflow | Если этот пункт установлен, сбросьте его напрямую, в противном случае ничего не делайте, чтобы, когда очередь полусоединений сервера опустеет, соединение было принято повторно.Linux坚持在能力许可范围内不忽略进入的连接 . В течение этого периода клиент будет повторно отправлять sys-пакет, когда количество повторных попыток достигнет верхнего предела, он получитconnection time out отклик. |
min(backlog, somaxconn) | Длина полностью подключенной очереди. |
Заказ
команда netstat -s
[root@server ~]# netstat -s | egrep "listen|LISTEN"
667399 times the listen queue of a socket overflowed
667399 SYNs to LISTEN sockets ignored
667399 раз, показанные выше, представляют собой количество раз, когда полная очередь соединений переполняется. Это выполняется каждые несколько секунд. Если это число продолжает увеличиваться, полная очередь соединений должна время от времени заполняться.
[root@server ~]# netstat -s | grep TCPBacklogDrop
Проверьте, не переполнена ли очередь принятия
СС команда
[root@server ~]# ss -lnt
State Recv-Q Send-Q Local Address:Port Peer Address:Port
LISTEN 0 128 *:6379 *:*
LISTEN 0 128 *:22 *:*
Если состояние находится в состоянии прослушивания, Send-Q указывает, что максимальное количество полностью подключенных очередей на порту прослушивания в третьем столбце равно 50, а первый столбец, Recv-Q, указывает, сколько в настоящее время полностью подключенной очереди. с использованием. В состоянии non-LISTEN Recv-Q представляет количество байтов в очереди приема, Send-Q представляет количество байтов в очереди отправки.
резюме
При поступлении запроса на внешнее соединение модуль TCP сначала проверяет max_syn_backlog, если количество соединений в состоянии SYN_RCVD превышает этот порог, входящее соединение будет отклонено. В соответствии с полем tcp_abort_on_overflow решите, сбрасывать или сбрасывать напрямую.
Со стороны сервера, в трехстороннем рукопожатии, на первом этапе, после того, как сервер получает синхронизацию клиента, он помещает соответствующую информацию в полусвязанную очередь и одновременно отвечает на синхронизацию + подтверждение клиенту. Соединение добавляется в очередь полного соединения.
Как правило, полностью подключенная очередь относительно мала и заполняется первой, в то время как полусвязная очередь еще не заполнена. Если в это время будет получено сообщение синхронизации, оно войдет в полусвязанную очередь, и проблем не возникнет. Однако, если получен третий шаг (ACK) в трехстороннем рукопожатии, он будет решать, следует ли отказаться или сбросить, непосредственно в соответствии с полем tcp_abort_on_overflow.В это время клиент отправляет ACK, тогда клиент считает, что три -способ рукопожатия завершен, и он считает, что служба готова к приему данных. Но в это время сервер, возможно, не сможет установить соединение, потому что полная очередь соединений заполнена, и повторно отправит синхронизацию с шагом 2. Если данные поступят в это время, модуль TCP сервера сохранит данные. в очереди. По истечении определенного периода времени, если клиент не получает ответа, время ожидания соединения истекает или соединение ненормальное, клиент активно закрывает соединение.
«Три рукопожатия, четыре волны» redis анализ экземпляра
- Я развертываю службу Redis на машине DEV, номер порта 6379,
- Получите пакет данных с помощью инструмента tcpdump, используя следующую команду
tcpdump -w /tmp/a.cap port 6379 -s0
-w把数据写入文件,-s0设置每个数据包的大小默认为68字节,如果用-S 0则会抓到完整数据包
- Используйте redis-cli для доступа к dev:6379 на машине dev2, отправьте ping и получите ответ pong
- Остановите захват пакетов и используйте tcpdump для чтения захваченных пакетов.
tcpdump -r /tmp/a.cap -n -nn -A -x| vim -
(-x 以16进制形式展示,便于后面分析)
Всего было получено 7 посылок.
Захваченный пакет данных IP делится на заголовок IP и часть данных IP, а часть данных IP представляет собой заголовок TCP плюс часть данных TCP.
Формат IP-данных:
Он состоит из фиксированной длины 20В + переменной длины.10:55:45.662077 IP dev2.39070 > dev.6379: Flags [S], seq 4133153791, win 29200, options [mss 1460,sackOK,TS val 2959270704 ecr 0,nop,wscale 7], length 0
0x0000: 4500 003c 08cf 4000 3606 14a5 0ab3 b561
0x0010: 0a60 5cd4 989e 18eb f65a ebff 0000 0000
0x0020: a002 7210 872f 0000 0204 05b4 0402 080a
0x0030: b062 e330 0000 0000 0103 0307
Для формата заголовка IP, чтобы разобрать конкретное значение пакета данных.
значение байта | Значение байта |
---|---|
0x4 | IP версия ipv4 |
0x5 | Длина заголовка 5 * 4 байта = 20 байт. |
0x00 | Тип службы, теперь в основном установлен на 0 |
0x003c | Общая длина 3 * 16 + 12 = 60 байт, вся вышеуказанная длина 60 байт |
0x08cf | логотип. Уникальный идентификатор той же дейтаграммы. Когда дейтаграмма IP разделена, она копируется в каждую дейтаграмму. |
0x4000 |
3bit 标志 + 13bit 片偏移 . Трехбитные флаги соответствуют R, DF и MF. В настоящее время действительны только последние два бита, бит DF: 1 означает отсутствие фрагментации, 0 означает фрагментацию. MF: 1 означает «больше фрагментов», 0 означает, что это последний фрагмент. 13-битное смещение фрагмента: бит смещения этого фрагмента относительно первой позиции в исходном пакете данных. (нужно умножить на 8) |
0x36 | Время жить TTL. Максимальное количество маршрутизаторов, через которые разрешено проходить IP-пакетам. Каждый раз, когда маршрутизатор проходит, значение TTL уменьшается на 1. Когда оно равно 0, маршрутизатор отбрасывает дейтаграмму. Поле TTL представляет собой 8-битное поле, первоначально установленное отправителем.Рекомендуемое начальное значение указано в RFC Assign Numbers. Эхо-ответы ICMP часто отправляются с максимальным значением TTL, равным 255. TTL предотвращает застревание дейтаграмм в петлях маршрутизации. 54 здесь. |
0x06 | тип соглашения. Укажите, какой протокол используется для данных, переносимых IP-пакетом, чтобы уровень IP узла назначения мог знать, какому процессу отправить пакет данных. Номер протокола TCP — 6, номер протокола UDP — 17. Номер протокола ICMP — 1, номер протокола IGMP — 2. Данные, переносимые в IP-пакете, используют протокол TCP и были проверены. |
0x14a5 | 16-битная контрольная сумма заголовка IP. |
0x0ab3 b561 | 32-битный IP-адрес источника. |
0x0a60 5cd4 | 32-битный IP-адрес назначения. |
Оставшаяся часть данных относится к протоколу TCP. TCP также имеет фиксированную длину 20 байт + часть переменной длины.
значение байта | Значение байта |
---|---|
0x989e | 16-битный исходный порт. 1161616+81616+1416+11=39070 |
0x18eb | 16-битный порт назначения 6379 |
0xf65a ebff | 32-битный серийный номер. 4133153791 |
0x0000 0000 | 32-битный номер подтверждения. |
0xa | Длина заголовка 4 бита, в блоках по 4 байта. Всего 10*4=40 байт. Следовательно, необязательная длина TCP-пакета составляет 40-20=20. |
0b000000 | 6-битные зарезервированные биты. В настоящее время установлено значение 0. |
0b000010 | Бит флага 6bitTCP. Слева направо: Emergency URG, Acknowledge ACK, Push PSH, Reset RST, Synchronize SYN, Terminate FIN. |
0x7210 | Размер скользящего окна, скользящее окно — это размер буфера приема tcp, который используется для управления перегрузкой tcp. 29200 |
0x872f | 16-битная контрольная сумма. |
0x0000 | Аварийный указатель. Имеет значение, только если URG = 1, указывает количество байтов срочных данных в этом сегменте. Когда URG = 1, TCP отправителя вставляет срочные данные в начало данных в этом сегменте, а данные после срочных данных остаются обычными данными. |
Часть переменной длины, следующий протокол:
значение байта | Значение байта |
---|---|
0x0204 05b4 | Максимальная длина пакета: 05b4 = 1460. Максимальная длина пакета, которую можно получить, обычно MTU минус 40 байт, заголовок IP и заголовок TCP по 20 байт. |
0x0402 | Указывает на поддержку SACK |
0x080a b062 e330 0000 0000 | метка времени. Тс знач=b062 e330=2959270704, экр=0 |
0x01 | бездействие |
0x03 0307 | Коэффициент расширения окна составляет 7. Смейте 7, умноженный на 128 |
Вот и закончился первый пакетный анализ. DEV2 отправляет запросы SYN на DEV.也就是三次握手中的第一次了。
SYN seq(c)=4133153791
Второй пакет, dev отвечает на соединение, ack=4133153792, указывает на то, что dev готов принять пакет с этим порядковым номером в следующий раз, который используется для контроля последовательности байта tcp note. Начальный серийный номер dev (то есть серверной части) — seq=4264776963, syn=1.SYN ack=seq(c)+1 seq(s)=4264776963
Третий пакет, подтверждение пакета клиента, использует здесь ответ относительного значения. seq=4133153792, что соответствует подтверждению второго пакета.ack=4264776964.ack=seq(s)+1, seq=seq(c)+1
На этом трехстороннее рукопожатие завершено. Следующим шагом является отправка данных ping и pong.
Потом четвертый пакет.
10:55:48.090073 IP dev2.39070 > dev.6379: Flags [P.], seq 1:15, ack 1, win 229, options [nop,nop,TS val 2959273132 ecr 3132256230], length 14
0x0000: 4500 0042 08d1 4000 3606 149d 0ab3 b561
0x0010: 0a60 5cd4 989e 18eb f65a ec00 fe33 5504
0x0020: 8018 00e5 4b5f 0000 0101 080a b062 ecac
0x0030: bab2 6fe6 2a31 0d0a 2434 0d0a 7069 6e67
0x0040: 0d0a
Длина заголовка tcp составляет 32 Б, необязательная длина — 12 Б. Общая длина IP-пакета — 66 Б, длина заголовка — 20 Б, поэтому длина части данных TCP — 14 Б. seq=0xf65a ec00 =4133153792 ACK, PSH, часть данных 2a31 0d0a 2434 0d0a 7069 6e67 0d0a
0x2a31 -> *1
0x0d0a -> \r\n
0x2434 -> $4
0x0d0a -> \r\n
0x7069 0x6e67 -> ping
0x0d0a -> \r\n
Dev2 отправляет ping-данные dev, и четвертый пакет готов.
Пятый пакет, dev2, отправляет ответ подтверждения на dev. Серийный номер — 0xfe33 5504=4264776964, а номер подтверждения подтверждения — 0xf65a ec0e=4133153806=(4133153792+14).
Шестой пакет, dev отвечает на сообщение pong для dev2. Серийный номер — fe33 5504, номер подтверждения — f65a ec0e, необязательная длина заголовка TCP — 12 байт, общая длина дейтаграммы IP — 59 байт, длина заголовка — 20 байт, поэтому длина данных TCP это 7Б.
Часть данных 2b50 4f4e 470d 0a, перевод есть+PONG\r\n
.
На этом анализ процесса трехэтапного рукопожатия между клиентом Redis и сервером завершен.
Суммировать
«Три рукопожатия, четыре волны» могут показаться простыми, но если вы пойдете глубже, вы все равно сможете расширить свои знания. Например, полусвязные очереди, полносвязные очереди и т. д. Предыдущий процесс установления соединения и закрытия соединения с TCP легко забыть, может быть потому, что я просто запомнил несколько процессов наизусть и не изучал принципы, лежащие в их основе.
Итак, "Три рукопожатия, четыре волны" вы действительно понимаете? Добро пожаловать, чтобы общаться и обсуждать вместе.
использованная литература
【Редис】сегмент fault.com/ah/119000001…
【опция TCP】blog.CSDN.net/ Район Удан 1234 / ах ...
【Раздвижное окно】Ууху. Call.com/question/32…
[Полная очередь соединения]Jumei.Taobao.org/2017/05/25/…
【обман клиентов】GitHub.com/Tor val all/Li…
【отставание RECV_Q】blog.51CTO.com/59090939/19…
【Таймер】Блог Woohoo.cn на.com/Dreamcoin ах…
【Значок очереди】Woohoo. IT код monkey.com/article/583…
【Атака TCP-флуда】Блог Woohoo.cn на.com/hub avindustry/afraid/4…
【MSS MTU】blog.csdn.net/lose it Wain / ...