Как всё на самом деле работает в этом вашем TCP/IP и зачем ему столько уровней. Разбираем на простых примерах.
Пётр Емельянов — эксперт по информационным технологиям в Skillbox. Для комьюнити Skillbox Code Experts он провёл эфир о сетевых протоколах и моделях OSI или Open Systems Interconnection model. Речь про модель взаимодействия открытых систем, которая описывает, по каким правилам взаимодействуют разные устройства в компьютерных сетях. Основные мысли и объяснения из эфира Пётр рассказал в этой статье. До карьеры в машинном обучении Пётр около 10 лет проработал системным программистом в компании, которая специализировалась на анализе сетевого трафика. Занимался тарификацией и разводил потоки трафика. В статье Пётр рассмотрит, как появилась модель OSI, кому и зачем она нужна, какие у неё уровни и как ей пользоваться.
Комьюнити экспертов «Программирования» в Skillbox — это сообщество для взаимодействия авторов, спикеров, амбассадоров и кураторов образовательных программ направления. Сообщество включает порядка 200 участников из Сбера, Яндекса, Авито и других компаний с экспертизой в разных ИТ-сферах. Специалисты общаются на профессиональные темы, обмениваются опытом, получают помощь в развитии личного бренда, выступают с докладами по hard- и soft-скиллам на внутренних мероприятиях и внешних конференциях, публикуют свои материалы в медиа.
Как появилась модель OSI
В 1957 году СССР запустил первый искусственный спутник Земли. Это стало отправной точкой развития сетевых технологий и интернета. Поэтому за интернет мы должны благодарить, как ни странно, Сергея Павловича Королёва.
Когда спутник взлетел, вышел на орбиту и заработал, другие державы не на шутку обеспокоились, потому что СССР приобрёл практически исчерпывающее и полное превосходство в космосе — ни одной другой страны на тот момент в космосе не было.
Тогда, в 1958 году, США создали специальное исследовательское агентство DARPA (Defense Advanced Research Projects Agency), которое занималось перспективными разработками, R&D в области национальной обороны. Одна из первых задач агентства – построить сеть, которая позволит удалённым друг от друга географически юнитам связываться между собой. Одним из амбициозных требований было, чтобы сеть могла пережить ядерный взрыв. Потому что ядерное оружие, спасибо Оппенгеймеру, в те годы уже было, как и понимание, что это такое и какие последствия несёт.
Так появился ARPANET. Это был довольно простой и надёжный прототип сети, из которого впоследствии и развился интернет. Отмечу любопытную деталь: практически любая инициатива, которая приводит к технологической революции, начинается из вооруженных сил, а потом постепенно приходит в бизнес частных корпораций.
ARPANET была довольно кустарной сетью, но работала. В дальнейшем к развитию сети подключились и другие страны, в частности, Великобритания и Франция.
В какой-то момент создатели обнаружили, что сеть вышла за границы Соединенных Штатов и позволяет общаться межконтинентально. Но при этом каждый вовлечённый в её функционирование делал кто во что горазд, ведь не было ни стандартов, ни единого понимания. Сеть росла и распространялась по миру, но её дальнейшее развитие и применение ещё никому не было понятно. Великобритания, Франция и Соединенные Штаты выступали со своими стандартами. Советский Союз в этой инициативе не участвовал, потому что его не позвали, но тоже исследовал это направление.
В конце концов, Великобритания, Франция и Соединенные Штаты создали комитет по стандартизации технологических решений. Решили придумать некую модель, согласно которой и предполагалось строить сеть дальше, то есть будущий интернет. Слова «интернет» тогда ещё не было, строили интернациональную вычислительную сеть и её модель, которую как раз назвали OSI.
Семь уровней OSI
Модель OSI появилась в 1983 году и состояла из семи уровней:
Физический — это сигналы, электричество, свет, радиоволны, звук, да хотя бы два спичечных коробка, соединенные капроновой нитью, это неважно. То есть передавать сигнал можно было совершенно по-разному. Это самый низкий уровень абстракции. Для остальных уровней способ передачи сигнала — не важен.
Канальный — уровень физической адресации, поскольку сеть — это устройства, которые соединяются друг с другом. Сейчас они могут соединяться и радиоволнами, но в те годы — только проводами. И по этим проводам, благодаря физическому уровню, передавался сигнал, преобразуемый в биты. Этот поток битов нужно было разделить на более или менее автономные части, так называемые фреймы. А ещё устройства должны были знать друг друга, как-то друг к другу обращаться, то есть адресоваться. Эта адресация между устройствами называется «физическая», к ней относятся MAC-адреса. Производитель вшивает в устройство шесть байт с этим адресом ещё при изготовлении. Считается, что MAC-адрес нельзя менять, и это практически так и есть. Один из вариантов устройств реализации канального уровня — протокол Ethernet.
Сетевой — уровень логической адресации. Со временем стало понятно, что сеть — большая, интернациональная, соединяет разные страны. Поэтому пакет будет перемещаться от устройства к устройству и каждое из них будет видеть другое по MAC-адресу. Но если нужно отправить пакет из Москвы в Санкт-Петербург, то как это сделать? Стало понятно, что нужен ещё один логический уровень. Представьте, фельдъегерь в красивом мундире и с кожаной сумкой скачет на лошади из Москвы в Санкт-Петербург. В среднем лошадь с всадником может проскакать километров 25, так что егерь вынужден останавливаться и менять лошадей на почтовых станциях. Получается, егерь скачет от станции к станции, пока не прибудет в Санкт-Петербург. В компьютерных сетях все похоже: почтовые станции – это устройства канального уровня (коммутаторы, они же – свитчи), а маршрут, заложенный в голове егеря, то есть последовательность станций на пути из Москвы в Питер – это логическая адресация. Понятно, что логическая адресация в принципе не должна зависеть от физической. То есть, если, например, изменится протокол физического уровня и вместо MAC-адресов будут какие-то другие, то уровень логической адресации измениться не должен. И, наоборот, логической адресации совершенно безразлично, как обстоят дела на уровне физической адресации, и как устройства находят друг друга.
Транспортный — предполагалось, что устройств много, сеть — разветвлённая, и должно быть что-то, что будет давать «гарантии» доставки пакета из точки А в точку Б, через большую цепочку разных устройств по логической адресации сетевого уровня. Представьте, что егерей на лошадях много, и каждый везёт кусочек одного большого письма. Нужен механизм, позволяющий получателю собрать большое письмо из кусочков, которые могут прийти в разном порядке (егеря скачут разными маршрутами и лошади у них разные), вообще не прийти (егерь на станции выпил лишнего, и всё проспал) или прийти несколько раз (отправитель, чтобы подстраховаться отправил несколько егерей с одним и тем же кусочком). А ещё важно отличать кусочки одного большого письма от кусочков другого большого письма. Эти задачи решают протоколы транспортного уровня, самый заметный представитель которых – конечно же – TCP. А последовательность кусочков, на которые разбито большое письмо, называется TCP-сессией.
Сеансовый — предполагалось, что на этом уровне будет происходить магия, которая выстроит логический канал связи между двумя пользователями в точке А и точке Б. Пусть например, существует длительная переписка между Чеховым и Буниным. Они пишут друг другу объёмные письма, которые не помещаются в сумку одного егеря, поэтому письмо разбивается на фрагменты, каждый из которых везёт отдельный фельдъегерь. Протоколы транспортного уровня позволяют Чехову и Бунину собирать письма из кусочков. Однако сами письма могут объединяться одной темой. Например, писатели обсуждают новое сочинение Ивана Алексеевича. Антон Павлович критикует и даёт советы, Бунин к ним прислушивается или как-то оппонирует. Вот такая переписка – это целая группа писем, или сеанс. Сеанс живет дольше, чем TCP-сессия, поэтому в модели OSI сеансами управляют протоколы пятого, сеансового уровня. Например, L2TP или PPTP.
Представления — этот уровень определял преобразования, которым могут подвергаться данные, передаваемые из точки А в точку Б — например, форматы данных. Ведь можно передавать картинку или текст, стримить видео, архивировать то, что передаёте, шифровать с помощью криптографии и так далее. Например, если Бунин с Чеховым обсуждают что-то очень личное, и не хотят, чтобы их письма прочитал кто-нибудь другой. А вредный начальник крупной почтовой станции просматривает содержимое кожаных сумок всех фельдъегерей, останавливающихся на этой станции. Писатели могут договориться о некоторой схеме шифрования, известной только им двоим. Это подразумевает, что письма должны как-то видоизменяться. Вот за это преобразование информации в OSI отвечает уровень её представления.
Приложения — то, что мы наблюдаем, когда пользуемся сетью — браузеры, мессенджеры, разные сервисы, криптовалютные кошельки. Что угодно, что мы сегодня используем на своих компьютерах, соединённых друг с другом через глобальную сеть Интернет. А наши друзья-писатели могли читать свои письма с помощью специальных приспособлений. Например, Антон Павлович использовал своё знаменитое пенсне. И вот если предположить, что существует некоторая форма писем, в которой их удобнее всего читать через пенсне Чехова, то это и будет задачей уровня приложений.
На момент запуска модели OSI ещё не было единого понимания, как сеть должна развиваться дальше, и как будет в итоге выглядеть. Поэтому уровней добавили чуть больше, чем нужно. Но, тем не менее, эталонная модель именно такая. Предполагалось, что все будут на неё ориентироваться — и разработчики ПО, и инженеры, разрабатывающие устройства. То есть каждое устройство должно работать на своём уровне. И устройству, работающему, например, на третьем уровне должно быть более или менее всё равно, что происходит на других.
Зачем нужен стандарт
Стандарт — это всегда хорошо. Благодаря ему у производителей оборудования и программистов, разрабатывающих ПО, есть чёткая инструкция. Они ей следуют и благодаря этому делают совместимые устройства, где бы те не находились физически. Это упростило работу программистов и инженеров, которые разрабатывали устройства и приложения.
Например, если вы делаете свитч-устройство, которое работает на втором, канальном уровне модели OSI, то вам не важно, какой провод в этот свитч вставлен: витая пара, оптоволокно или ещё что-нибудь. Не важно и то, какую полезную нагрузку содержит L2-фрейм, который вы на этом свитче получили. Всё, что вам нужно сделать — пойти в конкретные места этого фрейма, достать из них конкретные последовательности, два MAC-адреса, и посмотреть, на каком порту какой находится. А затем переложить пакет из одного порта в другой.
Аналогично это работает и на уровне L3. Если человек делает маршрутизатор, он не смотрит на второй уровень — только на третий. Берет IP-адреса, заходит в таблицу маршрутов и определяет, в какой порт ему этот пакет приложить согласно таблице маршрутизации. То же можно сказать и про программное обеспечение.
TCP/IP вместо семиуровневой OSI
Но семь уровней модели — это действительно много. Например, несмотря на длительный опыт работы с сетевыми протоколами, я, не подглядывая в википедию, не назову ни одного, работающего на уровне L5 или L6.
Реальность внесла свои коррективы и эту модель упростила. Сегодня повсеместно используется сетевая модель TCP/IP, в которой вместо семи уровней всего четыре.
Первые два уровня TCP/IP объединяются в «Уровень доступа к сети», затем следует «Сетевой» и «Транспортный», то есть L3 и L4 остаются без изменений, а последние три — объединяются в один, который называется «Уровень приложений». В остальном назначение практически не меняется.
Модель TCP/IP не интересует разница между средой передачи данных и принципами физической адресации (которая почти всегда – MAC-адресация b Ethernet). Всё низкоуровневое происходит на «Уровне доступа к сети», это достаточная детализация.
Кроме того, TCP/IP делегирует задачи сеансового уровня и уровня представлений уровню «Приложений». Передаёте вы картинку, звук или текст — неважно. Шифруете что-то – тоже неважно. Логика тут примерно такая: задача сети – доставка сообщений, разбитых на пакеты, а всё остальное, например, длительные сеансы или криптографическая защита – это задача конкретных приложений, пусть программисты и возятся. На самом деле это правильно, потому что перераспределяет ответственность. Производители оборудования могут не заморачиваться на конкретных алгоритмах шифрования, а программисты не зажаты в узкие рамки стандартов и правил.
В результате современная сеть делится на четыре уровня модели стека TCP/IP.
Виды протоколов: L2, IP, TCP
В компьютерных науках протокол — это набор правил, которые регулируют взаимодействие разных программ и устройств. Если два устройства взаимодействуют, следуя протоколу, они понимают друг друга, и всё работает. В нецифровом мире всё похоже: например, если дипломаты разных стран соблюдают дипломатические протоколы, им проще понять друг друга и договориться. Протоколов существует много. Пройдёмся по основным.
Структура или формат данных Ethernet-фрейма
L2 – Ethernet — протокол канального уровня. На картинке структура фрейма Ethernet. Он состоит из:
Двух MAC-адресов — Destination и Source, то есть адреса отправителя и адреса получателя.
Специальной преамбулы, в конце которой должен быть Interpacket Gap. Это важно, но можно их воспринимать как магические последовательности битов. Оборудование (свитчи, коммутаторы, работающие на уровне L2) эти биты воспринимает как начало и конец Ethernet-фрейма. Оборудование видит преамбулу и считывает последовательность до её окончания. Всё, что между началом и окончанием — Ethernet-фрейм, оборудование его парсит, достаёт MAC-адреса и служебную информацию.
Структура или формат данных заголовка IP-пакета.
IP (L3) (IPv4) — формат заголовка IP-пакета. IP-протокол сложнее, чем Ethernet. Он состоит из:
Двух логических IP-адресов: Source Address и Destination Address.
Версии протокола, в случае IPv4 — это всегда будет четвёртая версия.
IHL – это Internet Header Length, длина заголовка. Эта структура может быть разной длины, потому что в IP-протоколе предусмотрены такие необязательные параметры, как опции, в которые можно вместить всё, что хотите. От количества опций меняется размер этого заголовка. Заголовок нужен, чтобы устройство понимало, откуда читать — где находится полезная информация. Checksum можно воспринимать как хэш от всего, что было до. Благодаря ему устройства могут проверять, что пакет не изменялся по ходу путешествия из пункта А в пункт Б.
TTL — счётчик, который уменьшается, когда происходит маршрутизация. То есть каждый раз, когда пакет, согласно таблице маршрутизации, скачет от роутера к роутеру, TTL уменьшается.
TCP (L3) — это ещё более сложный протокол, чем IP. TCP-порты предоставляют адресацию между приложениями внутри одного компьютера, который принял TCP/IP-пакет. TCP-протокол обеспечивает абстракцию соединения и более или менее постоянный поток данных от одной точки к другой. Внутри этого потока протокол гарантирует определённую последовательность, в которой идут пакеты. Но «гарантирует» — слишком громкое слово. Мы знаем, что гарантировать в нашем мире вообще ничего нельзя, а в случае протокола TCP — уж тем более. Скорее, он делает всё от него зависящее, чтобы сделать доставку пакетов из точки А в точку Б более надежной.
В теории вычислительной техники есть такой мысленный эксперимент — классическая задача двух генералов. Она звучит так: есть две армии, которые находятся по разные стороны горного коридора. По центру этого коридора стоит третья армия, с которой первые две находятся в состоянии войны. По отдельности ни одна из этих двух армий разгромить третью не сможет, их единственный шанс победить — напасть вместе. Первая и вторая армии могут посылать лазутчиков, которые могут пройти через третью армию, а могут попасть в плен или быть убитыми. Задача этих двух армий договориться об одновременном нападении, а договариваться они могут, посылая лазутчиков, которые могут дойти, а могут и нет. Как это сделать? Ответ — никак. То есть эта задача строгого математического решения не имеет. Послав лазутчика, как узнать, дошёл ли он? Допустим, встречная армия пошлёт лазутчика навстречу, но и он может не дойти. Поэтому договориться в математическом смысле не получится, можно только приблизиться к согласованному состоянию, пожертвовав каким-то количеством своих солдат.
Эта задача прекрасно иллюстрирует работу TCP. Вы отправляете пакет и дожидаетесь подтверждения от принимающей стороны. Но ваш пакет может не дойти, и тогда вторая сторона не отправит подтверждения. Или, например, ваш пакет может дойти, но подтверждение от подтверждающей стороны не дойдет, и вы не узнаете, дошел ли ваш пакет.
Количество таких подтверждений регулируется в протоколе TCP с помощью настроек, но их не так много. Отправив пакет вы какое-то время ждёте подтверждения, а если оно не приходит, то считаете, что пакет не дошёл и отправляете дубликат. Затем снова ждёте подтверждения и если оно не пришло — повторяете отправку. А если пришло — отправляете следующий пакет. В настройках вы можете определить, сколько повторных отправок нужно, чтобы сделать вывод, что связь разорвалась и её нужно устанавливать заново.
Часто на собеседованиях спрашивают о таком параметре TCP как Window Size — размер окна. Речь про количество байт, которое вы можете отправить, не дожидаясь подтверждения. Когда на собеседовании этот вопрос задавали, показывали график, напоминающий пилу. И это типичное поведение TCP-протокола — он идёт вверх, падает и затем снова идёт вверх.
Это происходит потому, что когда TCP-соединение только устанавливается, TCP-протокол не знает, насколько оно надёжно. Поэтому отправляет небольшое количество данных и дожидается подтверждения. Получив подтверждение, увеличивает порцию данных, которые можно отправить прежде, чем получишь подтверждение. Этот параметр и называется Window Size. Если соединение относительно надёжно, вы получаете подтверждения, у протокола увеличивается Window Size, а значит скорость растёт, вы отправляете много данных и подтверждаете много данных. А падает она в тот момент, когда с сетью что-то происходит. Если принимающая сторона не отправила подтверждение или передающая сторона это подтверждение не получила, TCP-протокол автоматически сбрасывает размер окна до минимального, и опять начинается разогрев.
Знание работы сетевых протоколов позволяет глубже понимать, как работают ваши приложения и устройства. Это основа для всех, кто работает с устройствами, подключенными к единой сети. Поэтому базовое понимание работы сетей нужно не только SRE- и DevOps-инженерам, но и разработчикам. Надеюсь, что эта статья помогла вам разобраться в этой непростой теме.
Комментарии (11)
Akina
12.08.2024 12:29Часто на собеседованиях спрашивают о таком параметре TCP как Window Size — размер окна. Речь про количество байт, которое вы можете отправить, не дожидаясь подтверждения.
Ну совершенно неоднозначная, а потому непонятная, фраза. Если узел А в заголовке пакета отправил узлу В значение Window = 1024, то попробуйте, опираясь на эту фразу, ответить, кто будет придерживаться этого ограничения при отправке - узел А, узел В или оба узла?
mirwide
12.08.2024 12:29Это сложно. Мне кажется в статье вцелом написано не совсем правильно. Как я это понимаю:
Есть размер окна получателя. Он передается в каждом TCP сегменте. Отправитель может передать данные до значения = полученный ack number + window. Размер окна выставляет получатель. В каждом направлении в сессии свое значение. Это алгоритм скользящего окна, но он служит не для контроля перегрузки сети, а только для контроля перегрузки получателя. Чтобы на приемнике не переполнились буферы. Размер поля 16 бит, те максимум можно разрешить передать 64кб. Для сетей с большим RTT получается очень низкая пропускная способность, поэтому у TCP есть опция window scale, параметр передается в SYN при установке соединения. На него умножается значение заголовка window.
Для контроля перегрузки сети есть алгоритмы congestion control, у которых тоже есть окно. Размером этого окна управляет отправитель. Что логично, так как сеть можно положить не дойдя до получателя, плюс информация о потере пакетов и RTT есть только у отправителя. Медленный старт реализован в congestion control, а не через размер окна в TCP сегменте как написано в статье.
Соответственно отправитель использует наименьшее значение из этих двух окон.
Akina
12.08.2024 12:29Вот и я о том же - надо писать полностью и точно. Или уж лучше вообще ничего на этот счёт не писать.
engson
12.08.2024 12:29+1чего-то из истории выпало что другие страны (по)строили свои сети и норвегия вроде как была ближе по коннекту на arpa - а ешё не дали second рашифровку: Управление новейших исследований и продуктов (Advanced Research Products Agency (ARPA)), агентство, выполняющее контрактные заказы Министерства обороны USA
Vadziku
12.08.2024 12:29Модель OSI потеряла смысл лет 15 тому назад.
Как только появились протоколы типа АТМ, который лежал ниже 2-го уровня, но выше 1-го.
А потом пошли различные инкапсуляции протоколов, трансляции и прочее.
Да и за все время работы этой модели так и не договорились, что же лежит на 6-ом уровне. Точки зрения на списки протоколов этого уровня менялись совершенно кардинально.
Serjio-IT
12.08.2024 12:29Модель OSI важна, так как ее спрашивают на каждом втором собеседовании. ))
Vadziku
12.08.2024 12:29Если работодатель внушает хоть какие-то надежды на разумность, то можно попытаться ему объяснить состояние дел с OSI, но если видно что там безнадежно, и он это всерьез, то лучше с такого собеседования просто уйти.
HarleyKaos
12.08.2024 12:29Цеттатто:
Считается, что MAC-адрес нельзя менять, и это практически так и есть.
Можно. И на физическом, и на логическом уровнях.
dobrostas
Статья хорошая, но кажется, что хаб Developer Relations совсем не форматный для нее (
darovska_online Автор
спасибо, убрали )
Advisers
Наверное..., желательно в таких статьях давать все же ссылки, особенно, когда речь про стандарты:
https://datatracker.ietf.org/doc/html/rfc1180
https://www.rfc-editor.org/rfc/rfc9293.html
https://www.rfc-editor.org/rfc/rfc791.html