IP-адреса
число, що вказує мережі, куди доставити пакет

Фото: Liza / Pixabay 
Фото: Violinka / Pixabay
Застосуйте поняття до рішення
Застосуйте «Що таке IP-адреса?» до конкретного рішення. Ми можемо пов'язати поняття із системою, яку ви створюєте або купуєте. Wi-Fi, фаєрволи і віддалений доступ налаштовані так, щоб працювати можна було звідусіль, а заходити — лише своїм.
Перевірте припущення за терміном
Використайте пояснення та пов'язані роботи, щоб сформулювати запитання для проєкту. Ми можемо перевірити припущення разом до вибору інструмента. Керувала 30 інстансами Ubuntu Linux VPS — 30 серверів Linux під управлінням, із планом відновлення
Що це таке
IP-адреса (англійською IP address) — це число, яке протокол IP записує в кожен пакет, щоб указати, куди той прямує, поруч із другою адресою, що вказує, звідки він прийшов. RFC 791, специфікація IP версії 4 від 1981 року, називає її інтернет-адресою і розводить поняття так: назва каже, що ми шукаємо, а «адреса вказує, де воно є». Назву, наприклад домен, спершу треба перетворити на адресу, і цим займається DNS. Маршрут, тобто шлях між двома адресами, лишається на маршрутизаторах посередині.
В IPv4 адреса має 32 біти, тобто чотири октети, і записується як чотири десяткові числа від 0 до 255, розділені крапками: 192.0.2.10. RFC 791 ділив ці біти на номер мережі й локальну частину, а три фіксовані класи визначали, де проходить межа. Більшості організацій класи пасували погано: мережа класу C вміщала щонайбільше 254 хости, мережа класу B — до 65 534, тож номери класу B закінчувалися, а таблиці маршрутизації росли. У вересні 1993 року RFC 1519 замінив класи на CIDR, який дозволяє провести межу після будь-якого біта й записує її позицію після скісної риски. 192.0.2.0/24 — це блок, у якого перші 24 біти зафіксовані: 256 адрес.
IPv6 розширює адресу до 128 бітів. Її записують як вісім груп до чотирьох
шістнадцяткових цифр, розділених двокрапками, а RFC 4291 дозволяє стиснути одну
послідовність нульових груп до ::, тож 2001:db8:0:0:0:0:2:1 можна записати й
як 2001:db8::2:1. Оскільки ту саму адресу відтак можна було записати багатьма
способами, згодом RFC 5952 закріпив одну рекомендовану форму: малі літери,
жодних нулів на початку групи і :: для найдовшої послідовності нульових груп.
Адреса належить мережевому інтерфейсу, а не машині. Уже RFC 791 казав, що один
хост мусить уміти діяти як кілька, з кількома інтернет-адресами, і що деякі
хости мають кілька фізичних інтерфейсів. RFC 4291 вимагає, щоб кожен інтерфейс
IPv6 мав принаймні одну локальну адресу каналу (link-local), чинну лише в його
власному сегменті мережі, незалежно від інших адрес, які він має. Тож хост у
мережі, де працюють обидві версії, має кілька адрес одночасно, а ще адреси петлі
(loopback), якими звертається сам до себе: блок 127.0.0.0/8 в IPv4 і ::1 в
IPv6.
Не кожна адреса досяжна звідусіль. RFC 1918 виділяє для приватних мереж три блоки IPv4, 10.0.0.0/8, 172.16.0.0/12 і 192.168.0.0/16, і каже, що інформацію маршрутизації про них не можна передавати між організаціями. Тож пристрій з такою адресою виходить в інтернет лише через щось, що виступає замість нього, наприклад через NAT, який RFC 3022 описує як перетворення приватної адреси на публічну на виході. Ще три блоки, 192.0.2.0/24, 198.51.100.0/24 і 203.0.113.0/24, RFC 5737 зарезервував для документації, а RFC 3849 робить те саме для 2001:db8::/32 в IPv6. Усі адреси-приклади в цій статті взято з цих документаційних діапазонів.
Чому це важливо
Адреса — це єдине, що сервер завжди знає про клієнта, бо без неї відповіді не було б куди йти. Тому вона стає типовим ключем для багатьох рішень: правила брандмауера дозволяють або блокують за адресою, обмеження частоти запитів рахує запити на кожну адресу, журнал доступу пише її в кожному рядку, а скарга на зловживання її називає. Кожне з цих рішень працює лише настільки добре, наскільки адреса справді ідентифікує те, що, як ви думаєте, вона ідентифікує.
Ідентифікує вона менше, ніж здається. За NAT усі пристрої в офісі чи домогосподарстві можуть виходити в інтернет з однієї публічної адреси IPv4, тож блокування чи ліміт, спрямовані на один із них, зачіпають усіх. За проксі або CDN сервер бачить у кожному запиті адресу проксі, а власна адреса клієнта надходить, якщо надходить узагалі, у заголовку, який написав хтось інший. Правило, написане проти адреси, — це правило про позицію в мережі, а не про людину.
Водночас вона розкриває більше, ніж зазвичай думають. RFC 7239, який
стандартизував заголовок Forwarded, яким проксі передають адресу клієнта далі,
зазначає в розділі про приватність, що IP-адреса може однозначно ідентифікувати
клієнта, показати, яким оператором він користується, і дати приблизне уявлення
про те, де він перебуває. Тож журнал, повний адрес, — це не лише інструмент, а й
відповідальність, і добра причина вирішити, що ви зберігатимете, ще до того, як
почнете зберігати.
А тепер їх два види. Усе, що розбирає, зберігає чи порівнює адреси, мусить однаково приймати IPv4 і IPv6, бо клієнт у мережі, яка пропонує обидві версії, може прийти через будь-яку з них. Код, написаний тоді, коли кожна адреса вміщалася в п’ятнадцять символів із цифр і крапок, ламається на першому відвідувачеві з IPv6, і зазвичай далеко від місця, де адресу прочитали.
Як це виглядає на практиці
У стандартній бібліотеці Python є модуль ipaddress, який розбирає обидві
версії і бере на себе арифметику, тож рядки ніколи не доводиться ділити вручну.
В інтерактивному сеансі:
>>> import ipaddress
>>> ipaddress.ip_address("203.0.113.57")
IPv4Address('203.0.113.57')
>>> ipaddress.ip_address("2001:0DB8:0000:0000:0000:0000:0002:0001")
IPv6Address('2001:db8::2:1')
>>> ipaddress.ip_network("203.0.113.57/24", strict=False)
IPv4Network('203.0.113.0/24')
>>> ipaddress.ip_network("2001:db8:42:7::5/48", strict=False)
IPv6Network('2001:db8:42::/48')Другий виклик показує нормалізацію, яку рекомендує RFC 5952: довгий запис
великими літерами і короткий малими — це та сама адреса, і модуль виводить
канонічну форму. Рядок на кшталт 192.0.2.300 модуль відхиляє з ValueError, бо
300 не вміщається в октет. Останні два виклики перетворюють адресу на мережу
навколо неї. Без strict=False модуль відхилив би й їх, бо в 203.0.113.57/24
встановлено біти хоста; з ним частина хоста обнуляється, і лишається сама
мережа.
Саме таке обнулення цей сайт застосовує до адрес своїх відвідувачів. Сторінка про приватність каже, що IP-адреса ніколи не зберігається повністю: її скорочують у момент запису рядка журналу, і остання частина замінюється нулями ще до того, як щось потрапить на диск, тож збережене вказує на приблизну мережу, у якій цілий офіс і ціла вулиця можуть виглядати однаково. Сторінка додає, що сервер записує адресу у двох полях і розмиває обидва, а заголовки, які можуть містити власну адресу, — ті, що додає корпоративний проксі або мережа доставки вмісту, — видаляє ще до запису рядка. Скільки бітів лишається, вона не каже; /24 і /48 вище — це ілюстрація цієї статті, а не налаштування сайту. Але суть від цього не змінюється. Адресу, яку ніколи не записують повністю, неможливо повністю й розголосити, а скорочення на вході не залежить від завдання з очищення, яке одного дня може перестати запускатися.
Де виникають проблеми
Довіряти заголовку щодо адреси клієнта. X-Forwarded-For і стандартний
заголовок Forwarded — звичайні заголовки запиту, і RFC 7239 попереджає, що
кожен вузол на шляху до сервера, зокрема й сам клієнт, може змінити Forwarded.
Код, який бере першу адресу зі списку, дозволяє будь-якому клієнтові вибрати
собі адресу, а з нею і власний ліміт, і власне місце в списку дозволених.
Використовуйте адресу TCP-з’єднання, якщо тільки запит не пройшов через проксі,
який ви експлуатуєте самі, і тоді читайте лише те, що додали ваші власні проксі,
рахуючи справа.
Вважати адресу людиною. Оскільки одну адресу можуть ділити багато користувачів, бан адреси може заблокувати цілий офіс, а ліміт, розрахований на одну людину, душить цілу школу. Використовуйте адреси для грубих рішень, задавайте ліміти з огляду на спільні адреси, а все персональне прив’язуйте до облікового запису, у який людина ввійшла.
Порівнювати адреси як рядки. 2001:db8::2:1 і 2001:DB8:0:0:0:0:2:1 — це одна адреса і два різні рядки, тож список дозволених, який порівнює текст, прийме одну й відхилить другу. Розбирайте обидві сторони перед порівнянням або зберігайте лише форму з RFC 5952.
Розбирати лише IPv4. Регулярний вираз для чотирьох чисел із крапками, стовпець на п’ятнадцять символів або код, що відділяє хост від порту за останньою двокрапкою, — усе це ламається на IPv6. Використовуйте справжній парсер і тип чи довжину стовпця, придатні для обох версій. Коли поруч з адресою IPv6 пишуть порт, RFC 5952 рекомендує квадратні дужки, як у [2001:db8::1]:443, бо інакше останню групу можна прочитати як частину адреси.
Тримати повні адреси довше, ніж потрібно. Журнали, аналітичні таблиці й резервні копії роками накопичують адреси, якщо їх ніщо не зупиняє. Вирішіть, яка точність вам потрібна, скорочуйте адресу під час запису, а не згодом, і задайте решті термін придатності.
Використовувати справжні адреси в прикладах. Приклад конфігурації, тестові дані чи знімок екрана зі справжньою адресою когось іншого скеровують скопійований трафік до незнайомця. RFC 5737 резервує свої три блоки саме для того, щоб зменшити такі конфлікти й плутанину; користуйтеся ними, а для IPv6 — 2001:db8::/32.
Що почитати далі
- RFC 791: Internet Protocol — специфікація IPv4 1981 року з 32-бітною адресою і розрізненням назв, адрес і маршрутів.
- RFC 4291: IP Version 6 Addressing Architecture — типи адрес IPv6, їхні текстові форми і вимога мати локальну адресу каналу.
- RFC 5952: A Recommendation for IPv6 Address Text Representation — один канонічний спосіб записувати адресу IPv6 і проблеми, яких завдають довільні варіанти запису.
- RFC 7239: Forwarded HTTP Extension — як проксі передають адресу клієнта далі, чому результатові не можна просто довіряти і чого це коштує приватності.
- RFC 5737: IPv4 Address Blocks Reserved for Documentation — три діапазони, призначені для прикладів.
- ipaddress: IPv4/IPv6 manipulation library — стандартний модуль Python для розбору, порівняння й групування адрес.

