Що відбувається, коли ви відкриваєте сайт
Навіщо це
Section titled “Навіщо це”Колега пише: «сайт не відкривається». Ви запускаєте ping до сервера, і він
відповідає. Здавалося б, мережа працює, але ping перевірив лише те, що пакет
ICMP дійшов до сервера й повернувся. Сайт, крім цього, потребує розв’язання
імені, TCP-з’єднання з портом 443, договору про шифрування й коректної
відповіді застосунку. Зламатися може кожен із цих кроків, і кожен ламається
по-своєму.
Цей модуль показує весь ланцюжок від початку до кінця, без подробиць. Кожен крок у ньому має власний модуль, де його розібрано докладно. Тут головне — карта: коли щось не працює, ви вже знаєте, з яких місць складається шлях і чим перевірити кожне.
Передумови. Окремих немає: досить уміти запускати команди в терміналі Linux. Сокети, процеси й системні виклики знадобляться з модуля 3, де ми спираємося на курс «Операційні системи».
Дев’ять кроків до першого байта
Section titled “Дев’ять кроків до першого байта”Ви пишете в адресному рядку https://web.test/ і натискаєте Enter.
Ось що відбувається, поки на екрані не з’явиться перший символ сторінки.
-
Розбір адреси. Браузер бачить схему
https, отже порт 443, а хостweb.test. Спершу він перевіряє власні кеші й налаштування (проксі, HSTS, збережені з’єднання). Якщо відкрите з’єднання з цим сервером уже є, наступні кроки пропускаються. -
Розв’язання імені (DNS). Для з’єднання потрібна IP-адреса, тож браузер просить бібліотеку системи, та зазирає в
/etc/hosts, потім у кеш, і нарешті надсилає UDP-запит на адресу резолвера з/etc/resolv.confабо з налаштувань DHCP. Відповідь містить IP-адресу, наприклад10.0.2.2. Докладно в модулі 13. -
Куди слати: у своїй мережі чи через шлюз. Ядро перевіряє таблицю маршрутів (routing table): чи входить
10.0.2.2у підмережу на одному з інтерфейсів? Якщо ні, пакет піде до шлюзу за замовчуванням (default gateway). Про адреси й підмережі — модуль 6, про вибір маршруту — модуль 7. -
Пошук MAC-адреси наступного вузла. По кабелю чи повітрям пакет іде не на IP-адресу сервера, а на MAC-адресу шлюзу. Її ядро дізнається запитом ARP: «хто має
10.0.1.1?». Це єдиний крок, де кадр широкомовний. Докладно в модулі 5. -
TCP-з’єднання. Клієнт надсилає
SYN, сервер відповідаєSYN+ACK, клієнт підтверджуєACK. Так двоє домовляються про початкові номери байтів і параметри, і на це йде одне повне проходження туди й назад (RTT). Докладно в модулі 11. -
Рукостискання TLS. Поверх готового каналу клієнт і сервер домовляються про шифри, сервер доводить, що він і є
web.test, пред’являючи сертифікат, і обидві сторони отримують спільний ключ. У TLS 1.3 це ще одне проходження туди й назад. Докладно в модулі 15. -
HTTP-запит. Нарешті йде
GET / HTTP/1.1із заголовками. Запит шифрований, тож стороннім видно адресу сервера, розміри й час, а також, найчастіше, ім’я сайту: клієнт відкритим текстом називає його в рукостисканні TLS (SNI). Докладно в модулі 14. -
Дорога через мережу. Пакет проходить кілька маршрутизаторів. Кожен дивиться на IP-адресу призначення, обирає наступний вузол, зменшує TTL на одиницю й пересилає кадр далі, змінюючи в ньому MAC-адреси. Маршрутизатори домовляються між собою про досяжність мереж протоколами на кшталт BGP (модуль 8).
-
Відповідь. Сервер обробляє запит і надсилає відповідь тим самим шляхом назад. Маршрут у зворотний бік не мусить збігатися з прямим.
Усе це відбувається за десятки, а то й одиниці мілісекунд. Порядок величин можна прикинути наперед: до першого байта відповіді на новому з’єднанні мине DNS-запит плюс одне RTT на TCP плюс одне на TLS 1.3 плюс ще одне на сам запит і відповідь. Якщо RTT до сервера 100 мс, то це щонайменше триста мілісекунд тільки мережевого очікування, і жодним потужним сервером його не зменшити. Тому браузери тримають з’єднання відкритими й повторно їх використовують.
Інкапсуляція: чому це шари
Section titled “Інкапсуляція: чому це шари”Шлях вище виглядає як довгий список, але його можна впорядкувати. Кожен крок відповідає на власне питання й не цікавиться відповідями на решту.
- Застосунок (HTTP, DNS) знає, що просити й у кого.
- Транспорт (TCP, UDP) знає, який саме процес на тому кінці має отримати дані, і, якщо треба, домагається надійності.
- Мережа (IP) знає, як довезти пакет до потрібної мережі, і нічого не знає про процеси.
- Канал (Ethernet, Wi-Fi) знає, як передати кадр до сусіднього вузла на тому самому фізичному сегменті, і нічого не знає про те, що лежить за ним.
Вони взаємодіють простим способом: кожен рівень бере дані з вищого й дописує перед ними власний заголовок. Це називають інкапсуляцією (encapsulation). Отримувач знімає заголовки в зворотному порядку.
Модель рівнів зручна для діагностики, бо кожен вузол на шляху читає лише свій набір заголовків. Комутатор дивиться на MAC-адреси, маршрутизатор на IP-адреси, файрвол на порти, а балансувальник, можливо, на HTTP-заголовки. Кожен із них може зламати або дозволити лише те, що бачить, і пошук несправності зводиться до питання: на якому рівні зникає те, що я очікував?
pingвідповідає, а сайт мовчить: мережевий рівень справний, шукайте вище (порт закритий файрволом? служба не слухає? DNS повертає іншу адресу?).pingдо шлюзу не проходить: шукайте нижче (кабель, VLAN, MAC, ARP).- З’єднання TCP встановлюється, але браузер лається на сертифікат: TLS, тут мережа не винна.
Що бачить мережа: реальний запит
Section titled “Що бачить мережа: реальний запит”Перевірмо це на живому трафіку. Нижче ми зберемо мінімальну мережу
з двох хостів і маршрутизатора між ними (у просторах імен, нічого в системі не
ламаючи) і підслухаємо один запит curl. Побудову топології ми докладно
пояснюємо в модулі 3 і лабораторних, тут вона потрібна тільки для картини.
h1 (10.0.1.2) ── r (10.0.1.1 | 10.0.2.1) ── h2 (10.0.2.2, веб-сервер)Ось що tcpdump -e показує на інтерфейсі клієнта (скорочено; час і зайві
опції прибрано):
ARP Request who-has 10.0.1.1 tell 10.0.1.2 de:31:8d:78:ed:b2 > ff:ff:ff:ff:ff:ffARP Reply 10.0.1.1 is-at ee:c3:ba:a9:33:6c ee:c3:ba:a9:33:6c > de:31:8d:78:ed:b2IPv4 10.0.1.2.58386 > 10.0.2.2.80: Flags [S] de:31:8d:78:ed:b2 > ee:c3:ba:a9:33:6cIPv4 10.0.2.2.80 > 10.0.1.2.58386: Flags [S.] ee:c3:ba:a9:33:6c > de:31:8d:78:ed:b2IPv4 10.0.1.2.58386 > 10.0.2.2.80: Flags [.] ack 1IPv4 10.0.1.2.58386 > 10.0.2.2.80: Flags [P.] HTTP: GET / HTTP/1.1IPv4 10.0.2.2.80 > 10.0.1.2.58386: Flags [P.] HTTP: HTTP/1.0 200 OK...На що тут дивитися:
- ARP питає в усіх (
ff:ff:ff:ff:ff:ff) і отримує відповідь від шлюзу. Про сервер10.0.2.2ніхто не питає: він в іншій підмережі, тож клієнту цікавий тільки шлюз. - Перший пакет TCP іде з IP-адресою призначення сервера, але з MAC-адресою
призначення маршрутизатора
ee:c3…. Це і є наслідок кроку 3 і кроку 4: IP-адреса каже, куди пакет зрештою належить, MAC-адреса каже, кому передати його зараз. - Порт клієнта
58386вибрала система випадково; сервер слухає на 80. Пара адрес і пара портів однозначно позначають з’єднання. - Перша відповідь (
S.) приходить менш ніж за пів мілісекунди, бо все локально. У реальній мережі саме тут проходить перший RTT.
Дві моделі рівнів
Section titled “Дві моделі рівнів”Ви вже чули про «сім рівнів OSI». У 1980-х ISO і ITU розробляли еталонну модель відкритої взаємодії (OSI, Open Systems Interconnection) і власні протоколи під неї, а паралельно в дослідницьких мережах працював стек TCP/IP, який виріс із практики й запрацював раніше. Виграв TCP/IP. Протоколи OSI майже ніде не вижили, а модель залишилась як словник.
| OSI | Приклад | TCP/IP |
|---|---|---|
| 7 Прикладний | HTTP, DNS | Прикладний |
| 6 Подання | шифрування, кодування | ↑ |
| 5 Сеансовий | ↑ | ↑ |
| 4 Транспортний | TCP, UDP | Транспортний |
| 3 Мережевий | IP, ICMP | Міжмережевий (internet) |
| 2 Канальний | Ethernet, Wi-Fi | Канальний (link) |
| 1 Фізичний | кабель, радіо | ↑ |
Стрілки означають, що в TCP/IP цих рівнів немає окремо. Чотири рівні TCP/IP описані в RFC 1122; п’ятирівневий варіант (фізичний + канальний + мережевий + транспортний + прикладний) поширений у підручниках. Цей курс використовує саме його.
На практиці «L2» означає канальний рівень (комутатор, MAC), «L3» — мережевий (маршрутизатор, IP), «L4» — транспортний (порти), «L7» — прикладний. Балансувальник L4 роздає з’єднання за портом, а L7 читає HTTP і вирішує за шляхом чи заголовком. Рівні 5 і 6 з моделі OSI в реальних протоколах не розділяються: TLS не вкладається ні в один із них.
Суворої ієрархії рівні не утворюють, і протоколи часто «протікають» вгору чи вниз: TLS шифрує поверх TCP, але QUIC (основа HTTP/3) робить транспорт і шифрування разом поверх UDP; VPN-тунель кладе пакет IP всередину пакета IP.
Звідки беруться правила
Section titled “Звідки беруться правила”Пакет від Linux-комп’ютера розуміє маршрутизатор будь-якого виробника, бо всі дотримуються однакових специфікацій, і ними ніхто не «володіє».
IETF (Internet Engineering Task Force) — відкрита спільнота, яка створює стандарти інтернету. Її документи називаються RFC (Request for Comments) і мають номери, що не змінюються: IPv4 описаний у RFC 791, ARP у RFC 826, DNS в RFC 1034 та 1035, TLS 1.3 у RFC 8446. Якщо документ треба виправити, виходить новий RFC, який замінює старий: TCP спершу описував RFC 793, а тепер його замінив RFC 9293. Перед читанням перевірте, чи не застарів документ (rfc-editor.org показує зв’язки «obsoletes» та «updated by»). Девіз IETF — «грубий консенсус і працюючий код»: рішення ухвалюють не голосуванням, а коли серйозних заперечень не лишилося, і цінують специфікації, які вже хтось реалізував.
IEEE (Інститут інженерів електротехніки й електроніки) стандартизує те, що стосується одного сегмента мережі. Родина 802: 802.3 — Ethernet, 802.11 — Wi-Fi, 802.1Q — VLAN. Документи IEEE історично платні, хоча частина стандартів через певний час стає доступною безкоштовно.
IANA та регіональні реєстри розподіляють номери (адреси, номери автономних систем, порти) та імена верхнього рівня. Без єдиного реєстру двоє могли б випадково взяти однаковий порт чи адресу.
RFC описує протокол, але нікого не примушує його виконувати. Якщо ваша реалізація поводиться інакше, ніж інші, ламається саме вона. Тож під час налагодження, коли щось працює не за специфікацією, пошукайте, хто відхилився.
Як це насправді в Linux
Section titled “Як це насправді в Linux”Усе, що показано вище, можна побачити самому. Команди безпечні й нічого не змінюють.
ip route get 10.0.2.2Показує, яким маршрутом піде пакет до цієї адреси. Вивід у нашому стенді для сервера в іншій підмережі:
10.0.2.2 via 10.0.1.1 dev v1 src 10.0.1.2 uid 0via 10.0.1.1 — шлюз, dev v1 — інтерфейс, src — адреса відправника,
яку ядро обрало. Якщо via немає, адресат вважається сусідом по каналу.
ip neighТаблиця сусідів, тобто відповідність IP і MAC, яку заповнює ARP:
10.0.1.1 dev v1 lladdr ee:c3:ba:a9:33:6c REACHABLEЗапису про сервер 10.0.2.2 тут немає, і це не помилка: до нього ніхто
не звертався напряму.
getent hosts web.testРозв’язання імені тим самим шляхом, що й у програм: через
бібліотеку системи, з /etc/hosts, кешем і DNS за налаштуваннями
/etc/nsswitch.conf. Якщо dig знаходить ім’я, а getent ні, у вас
проблема в налаштуваннях системи, не в DNS-сервері.
traceroute -n 10.0.2.2traceroute to 10.0.2.2 (10.0.2.2), 30 hops max, 60 byte packets 1 10.0.1.1 0.290 ms 2 10.0.2.2 0.183 msКожен рядок — один маршрутизатор на шляху (traceroute вміє це завдяки
TTL, про що в модулі 6).
sudo tcpdump -n -e -i eth0 'tcp port 80 or arp'Знімок трафіку, як вище. Перед першим запуском tcpdump доведеться
встановити. Гарна звичка: додавати -n, щоб він не намагався розв’язувати
імена (що саме по собі викликає DNS-трафік і заплутує знімок).
Щоб повторити наш стенд, потрібні лише ip netns та veth; повний
приклад побудови топології з трьох просторів імен наведено в модулі 3.
Типові помилки розуміння
Section titled “Типові помилки розуміння”«Якщо ping працює, мережа справна». ping перевіряє лише IP між двома
вузлами. Порт може бути закритий файрволом, ім’я може розв’язуватися неправильно,
MTU може ламати великі пакети (малі ping пройдуть). Про це модулі 6 і 16.
«Інтернет — це один великий кабель, що йде до сервера». Між вами та сервером десятки окремих мереж різних власників, які домовляються про пересилання через BGP. У кожної свій маршрутизатор, свої черги й свої поломки.
«IP-адреса призначення змінюється по дорозі». Хибно: IP відправника й отримувача лишаються тими самими на всьому шляху (за винятком NAT, про який модуль 9). Змінюються MAC-адреси, бо вони описують лише один перехід. Саме це плутають найчастіше, і наш знімок це показує.
«Рівні OSI — це закон, у кожного протоколу є свій номер». Це словник для розмови. Реальні протоколи не завжди вкладаються в схему: TLS, ARP, MPLS чи VPN ні в один рівень чисто не потрапляють. Не витрачайте час на суперечку, де саме живе протокол; питання «що він робить і хто це читає» корисніше.
«RFC — це закон, і все, що там написано, виконується». Стандарт лише описує домовленість. У реальних реалізаціях бувають відхилення, а деякі RFC мають статус «інформаційний» і нічого не вимагають.
Перевір себе
Лабораторна
Section titled “Лабораторна”Цей модуль ще не має окремої лабораторної: він задає карту, а практика починається з наступних. Знадобиться він у фінальній роботі B7, де треба знайти кілька несправностей на різних рівнях, і в A1, де ви самі напишете клієнта та сервера TCP.
Джерела
Section titled “Джерела”- Kurose, Ross — Computer Networking: A Top-Down Approach, розділ 1
- Peterson, Davie — Computer Networks: A Systems Approach, розділ 1 (є відкрита онлайн-версія)
- Stevens — TCP/IP Illustrated, Vol. 1, розділ 1
- RFC 1122 (вимоги до хостів, чотири рівні), RFC 791 (IPv4), RFC 826 (ARP), RFC 9293 (TCP), RFC 8446 (TLS 1.3)
man 8 ip,man 8 tcpdump,man 8 traceroute,man 1 getent- rfc-editor.org — пошук RFC і зв’язків між ними