B2. Linux як маршрутизатор
Маршрутизатор у модулі 7 виглядає як окрема коробка
з таблицею маршрутів. У Linux це звичайний вузол, у якому ядру дозволили
пересилати чужі пакети. Тут ви зробите таку коробку з простору імен r1:
з’єднаєте нею дві приватні мережі, випустите їх у «зовнішній світ»
через NAT із модуля 9 і роздасте одній з мереж адреси
по DHCP. Потім подивитеся в tcpdump, що саме бачить провайдер.
Після цієї роботи ви зможете:
- з’єднати кілька підмереж через Linux: адреси, маршрути за замовчуванням,
net.ipv4.ip_forward; - пояснити по
ttlу відповіді й поtcpdump, що пакет пройшов через маршрутизатор; - налаштувати трансляцію адрес (masquerade) у
nftablesі показати, з якою адресою пакет виходить назовні; - підняти DHCP-сервер
dnsmasqдля однієї підмережі й отримати від нього адресу клієнтом у своєму просторі імен; - знайти, чого бракує, коли «хости між собою бачаться, а назовні ні»:
маршруту,
ip_forwardчи NAT.
Така розкладка (дві приватні мережі, шлюз, провайдер) є у кожному офісі та в кожній домашній мережі. Коли в ній щось ламається, поступово перевіряють саме ці три місця.
Завдання
Section titled “Завдання”Результат роботи — чотири простори імен і правила в r1:
LAN A 10.0.1.0/24 LAN B 10.0.2.0/24 ┌────┐ ┌────┐ │ h1 │ (DHCP) .2 │ h2 │ └─┬──┘ └─┬──┘ │ │ └───────────┐ ┌───────────┘ ┌──┴─────┴──┐ │ r1 │ .1 у кожній LAN └─────┬─────┘ │ .2 «зовнішня мережа» 203.0.113.0/24 │ .1 ┌─────┴─────┐ │ isp │ lo: 198.51.100.1 («інтернет») └───────────┘| Простір імен | Адреса | Примітка |
|---|---|---|
r1 |
10.0.1.1/24 (LAN A), 10.0.2.1/24 (LAN B), 203.0.113.2/24 (до провайдера) |
маршрутизатор |
h1 |
з DHCP із діапазону 10.0.1.100–10.0.1.199 |
хост у LAN A |
h2 |
10.0.2.2/24 |
хост у LAN B, адреса статична |
isp |
203.0.113.1/24 на інтерфейсі, 198.51.100.1/32 на lo |
провайдер і «інтернет» |
Назви просторів імен і адреси зафіксовані, їх перевіряє check.sh.
Назви інтерфейсів оберіть самі.
Що зробити:
- Побудувати топологію: чотири простори імен і три пари
veth(r1–h1,r1–h2,r1–isp). - Призначити адреси з таблиці й прописати статичні маршрути: хост
відправляє «усе чуже» через
r1,r1відправляє «усе чуже» провайдеру. Уispмаршрутів до приватних мереж немає, і це свідоме рішення: так працює справжній провайдер. - Ввімкнути в
r1пересилання пакетів. - Налаштувати NAT так, щоб усе, що виходить із
10.0.0.0/16не в приватну мережу, виглядало для провайдера як203.0.113.2. - Підняти в
r1DHCP-серверdnsmasqдля LAN A й отримати адресу та маршрут за замовчуванням уh1від нього. - Показати в
tcpdumpна стороні провайдера адресу відправника до NAT і після.
Чого робити не треба. DNS-сервер і DHCP для LAN B не потрібні. Динамічну маршрутизацію і файрвол залишимо для B3 і B4.
Обмеження. nftables для NAT, не iptables. Адресу h1 в
еталонному результаті видає dnsmasq, руками її не задавайте.
Готово, коли sudo ./check.sh не показує жодного «НІ», а в нотатках
є відповіді на питання з етапів.
Перед початком
Section titled “Перед початком”- Прочитайте в модулі 6 розділи про адреси й маски, у модулі 7 розділ про пересилання пакетів, а в модулі 9 розділи про NAT і DHCP.
- Встановіть інструменти:
sudo bash setup/provision.sh. Для цієї роботи потрібніiproute2,nftables,dnsmasq,isc-dhcp-client(командаdhclient),conntrack,tcpdump,python3. - Потрібні права root. Підходить віртуальна машина й більшість контейнерів,
де працюють простори імен та
nftables(див.setup/probe-net-env.sh). - Працюйте в каталозі
labs/b2-linux-router.
-
Простори імен і дроти.
Terminal window for ns in r1 h1 h2 isp; dosudo ip netns add $nssudo ip netns exec $ns ip link set lo updonesudo ip link add lanA-r netns r1 type veth peer name eth0 netns h1sudo ip link add lanB-r netns r1 type veth peer name eth0 netns h2sudo ip link add wan-r netns r1 type veth peer name eth0 netns ispНазви інтерфейсів тут ваші.
ip -n r1 linkпокаже три нові інтерфейси в станіDOWN. -
Адреси й маршрути.
Призначте адреси з таблиці, піднімайте обидва кінці кожного дроту. Маршрут за замовчуванням:
Terminal window sudo ip netns exec h2 ip route add default via 10.0.2.1sudo ip netns exec r1 ip route add default via 203.0.113.1Адресу
h1поки задайте вручну (10.0.1.50/24і маршрут через10.0.1.1): DHCP буде пізніше.Перевірте:
pingвід кожного хоста до його шлюзу проходить.h1→h2ще ні. -
Пересилання.
Terminal window sudo ip netns exec h1 ping -c1 10.0.2.2 # не проходитьsudo ip netns exec r1 sysctl -w net.ipv4.ip_forward=1sudo ip netns exec h1 ping -c1 10.0.2.2 # проходитьПерший
pingне проходить не тому, що маршруту немає. Пакет доходить доr1, але ядро відкидає чужі пакети, поки не ввімкненоip_forward. Подивіться у відповідь на другийping:ttl=63, а не 64. Одиниця різниці й підказує, скільки маршрутизаторів на шляху.Запишіть: у чому різниця між маршрутом у таблиці й дозволом пересилати? Що було б, якби
r1мав маршрут, але не мавip_forward? -
Вихід назовні й NAT.
Спершу переконайтеся, що без NAT назовні не вийти. Запустіть
tcpdumpуisp:Terminal window sudo ip netns exec isp tcpdump -ni any icmpі в іншому вікні
sudo ip netns exec h2 ping -c2 198.51.100.1. Запити приходять з адреси10.0.2.2, а відповіді немає: уispнемає маршруту до приватної мережі. Тепер додайте NAT:Terminal window sudo ip netns exec r1 nft add table ip natsudo ip netns exec r1 nft add chain ip nat postrouting \'{ type nat hook postrouting priority srcnat; }'sudo ip netns exec r1 nft add rule ip nat postrouting \ip saddr 10.0.0.0/16 ip daddr != 10.0.0.0/16 masqueradeПовторіть
ping. Уtcpdumpтепер відправник203.0.113.2, і відповіді доходять. Подивіться, якr1запам’ятав з’єднання:sudo ip netns exec r1 conntrack -L.Запишіть: чому правило NAT стоїть у хуку
postrouting, а неprerouting? Звідкиr1знає, кому віддати відповідь? -
DHCP.
Приберіть статичну адресу
h1(ip addr flush dev eth0) і запустіть уr1DHCP-сервер для LAN A:Terminal window sudo ip netns exec r1 dnsmasq --conf-file=/dev/null --no-resolv --port=0 \--interface=lanA-r --bind-interfaces \--dhcp-range=10.0.1.100,10.0.1.199,12hsudo ip netns exec h1 dhclient -1 -v eth0Замініть
lanA-rіeth0своїми назвами.--port=0вимикає DNS уdnsmasq, залишаючи лише DHCP. Подивіться вip -4 addrуh1адресу з позначкоюdynamicі вip routeмаршрут за замовчуванням через10.0.1.1: його теж роздавdnsmasq, адреса інтерфейсу стала шлюзом автоматично.Запустіть
tcpdump -ni any port 67 or port 68уr1і повторітьdhclient. Ви побачите чотири пакети:Discover,Offer,Request,Ack.Запишіть: чому
Discoverіде на255.255.255.255, а не на адресу сервера? З якої адреси його відправлено? -
Порівняння до і після.
Запишіть у нотатки три числа:
ttlу відповідіh1→h2, адресу відправника, яку бачитьispдо NAT і після, і діапазон адрес, який видавdnsmasq. Їх ви й поясните, якщо хтось спитає, що роблять ці три налаштування.
Перевірка
Section titled “Перевірка”sudo ./check.shСкрипт нічого не будує й від назв інтерфейсів не залежить: він знаходить інтерфейси за адресами. Перевіряється:
- адреси з таблиці на
r1,h2таisp; - що в
r1працюєdnsmasq, аh1має адресу з10.0.1.0/24, видану за оренду (не задану вручну), і маршрут через10.0.1.1; - що в
r1ввімкненоip_forward, аh1іh2пінгують одне одного; - що
h1іh2досягають198.51.100.1, а провайдер бачить їхнє TCP-з’єднання з адресою203.0.113.2, тобто NAT справді працює (скрипт на хвилину запускає вispслухач, який повідомляє клієнту його адресу); - що
ispне має доступу до приватних адрес.
Якщо топологію зламати, скрипт показує, де саме: без ip_forward
не проходять h1 → h2 і вихід назовні; без NAT проходить
усе, крім зовнішньої мережі; без dnsmasq адреса в h1 виявляється
заданою вручну.
Часті помилки
Section titled “Часті помилки”Не ввімкнено ip_forward у r1. sysctl працює на простір імен:
sudo sysctl -w net.ipv4.ip_forward=1 на господарі не допомагає, потрібно
в r1: ip netns exec r1 sysctl ....
NAT є, а назовні не проходить. Перевірте, чи маршрут за замовчуванням
у r1 дивиться на 203.0.113.1, і чи правило NAT підхоплює пакет:
nft list ruleset у r1 та лічильники правила (nft -a list ruleset
і counter).
dhclient висить. Перевірте, що dnsmasq слухає саме інтерфейс
у LAN A (--interface= ваша назва), а не інший. Дивіться, чи доходить
Discover до r1 у tcpdump.
Ручні й динамічні налаштування разом. Якщо після dhclient у h1
лишилася стара статична адреса чи маршрут, два набори налаштувань
конфліктують. Перед DHCP зробіть ip addr flush dev <інтерфейс> і
ip route flush default.
Залишки попередньої спроби. Якщо будували кілька разів, перевірте,
що старий dnsmasq не висить у r1 (ip netns pids r1) і що в
просторах імен не лишилося зайвих правил.
Далі, якщо цікаво
Section titled “Далі, якщо цікаво”Додаткове завдання: IPv6 (dual stack). Дайте LAN A і LAN B
адреси fd00:0:0:1::/64 і fd00:0:0:2::/64 (r1 має ::1 у кожній,
h1 — fd00:0:0:1::2, h2 — fd00:0:0:2::2), увімкніть
net.ipv6.conf.all.forwarding у r1 і переконайтеся, що h1 пінгує h2
командою ping -6. Перевірити це можна так:
sudo IPV6=1 ./check.sh. IPv6 працює не в усіх контейнерах
(у ядрі господаря його може не бути), тож ця частина потребує
віртуальної машини; setup/probe-net-env.sh покаже, чи є він у вас.
Подумайте, чому для IPv6 NAT зазвичай не потрібний.
Інші розширення: два правила nft для DNAT (пробросити порт зовнішньої
адреси на h2) або dnsmasq із DNS і статичним записом (--address=).