Модуль 04 — Маршрутизация, NAT, IPv6

Как пакет выбирается из своей сети и как ему отвечают

Прогресс курса Модуль 4 из 9

Что вы освоите в этом модуле

01

Своя сеть и чужая

Отправляя пакет, узел сначала решает: получатель в моей сети или нет. Если в своей — кадр отправляется прямо ему (через ARP). Если нет — пакет отдаётся маршрутизатору, а тот решает, что делать дальше. Решение принимается по таблице маршрутов:

$ ip route
default via 192.168.116.1 dev ens18 proto dhcp src 192.168.116.34 metric 1002
192.168.116.0/24 dev ens18 proto dhcp scope link src 192.168.116.34 metric 1002
СтрокаСмысл
192.168.116.0/24 dev ens18 … scope linkСвоя сеть: отправлять напрямую через интерфейс ens18
default via 192.168.116.1Всё остальное (0.0.0.0/0) — шлюзу 192.168.116.1
metricПриоритет, если маршрутов в одну сеть несколько: меньше — лучше

Спросить у ядра, какой маршрут оно выберет для адреса, — ip route get:

$ ip route get 77.88.8.8
77.88.8.8 via 192.168.116.1 dev ens18 src 192.168.116.34 uid 1000
$ ip route get 192.168.116.10
192.168.116.10 dev ens18 src 192.168.116.34 uid 1000

Если подходят несколько маршрутов, выбирается самый точный — с наибольшим префиксом. Маршрут в 10.1.2.0/24 победит маршрут в 10.0.0.0/8 для адреса 10.1.2.5, а default (префикс 0) подходит всем и проигрывает всем.

02

Лаборатория: две сети и маршрутизатор

Соберём в пространствах имён схему: два офисных компьютера в разных сетях, маршрутизатор r1 между ними и «провайдер» isp. Команды сборки — в задании на портале; ниже — что происходит на каждом шаге.

  h1 192.168.10.10/24          h2 192.168.20.10/24
        │                            │
   lan1 192.168.10.1           lan2 192.168.20.1
        └──────────[ r1 ]────────────┘
                     │ wan 203.0.113.2/30
                     │
              isp 203.0.113.1/30 ── «интернет» 198.51.100.1

Шаг 1. Нет шлюза. У h1 есть только маршрут в свою сеть — про 192.168.20.0 он ничего не знает:

$ sudo ip netns exec h1 ping -c 1 192.168.20.10
ping: connect: Сеть недоступна
$ sudo ip -n h1 route
192.168.10.0/24 dev eth0 proto kernel scope link src 192.168.10.10

Шаг 2. Шлюз есть, а ответа нет. Добавляем маршруты по умолчанию на h1 и h2 — пакеты уходят на r1, но дальше не идут:

$ sudo ip -n h1 route add default via 192.168.10.1
$ sudo ip -n h2 route add default via 192.168.20.1
$ sudo ip netns exec h1 ping -c 1 -W 1 192.168.20.10
1 packets transmitted, 0 received, 100% packet loss, time 0ms
$ sudo ip netns exec r1 sysctl net.ipv4.ip_forward
net.ipv4.ip_forward = 0

По умолчанию Linux — не маршрутизатор: пакеты, адресованные не ему, он выбрасывает. Это защита: обычный сервер с двумя сетевыми картами не должен соединять сети без ведома администратора.

Шаг 3. Включаем пересылку.

$ sudo ip netns exec r1 sysctl -w net.ipv4.ip_forward=1
net.ipv4.ip_forward = 1
$ sudo ip netns exec h1 ping -c 2 192.168.20.10
64 bytes from 192.168.20.10: icmp_seq=1 ttl=63 time=0.118 ms
64 bytes from 192.168.20.10: icmp_seq=2 ttl=63 time=0.070 ms
$ sudo ip netns exec h1 traceroute -n -q1 192.168.20.10
traceroute to 192.168.20.10 (192.168.20.10), 30 hops max, 60 byte packets
 1  192.168.10.1  0.052 ms
 2  192.168.20.10  0.025 ms

Обратите внимание на ttl=63 вместо 64: каждый маршрутизатор уменьшает поле TTL (Time To Live) на единицу, а при нуле выбрасывает пакет. Так пакеты не кружат вечно, если маршруты зациклились. На этом же построен traceroute (модуль 08). Постоянно пересылка включается файлом в /etc/sysctl.d/: net.ipv4.ip_forward = 1.

03

Статические маршруты

У r1 три сети подключены напрямую, а путь в остальной мир он должен знать — добавляем маршрут по умолчанию через провайдера:

$ sudo ip -n r1 route
192.168.10.0/24 dev lan1 proto kernel scope link src 192.168.10.1
192.168.20.0/24 dev lan2 proto kernel scope link src 192.168.20.1
203.0.113.0/30 dev wan proto kernel scope link src 203.0.113.2
$ sudo ip -n r1 route add default via 203.0.113.1
$ sudo ip -n r1 route get 198.51.100.1
198.51.100.1 via 203.0.113.1 dev wan src 203.0.113.2 uid 0

Маршрут в конкретную сеть через конкретный шлюз — ip route add 10.50.0.0/16 via 192.168.20.254: так подключают сеть филиала через VPN-шлюз. Шлюз в маршруте должен быть доступен напрямую — находиться в одной из сетей интерфейсов.

В больших сетях маршруты не прописывают руками: маршрутизаторы обмениваются ими по протоколам динамической маршрутизации — OSPF внутри организации, BGP между провайдерами. Именно BGP связывает автономные системы интернета.

04

NAT

Попробуем выйти «в интернет» с h1:

$ sudo ip netns exec h1 ping -c 1 -W 1 198.51.100.1
1 packets transmitted, 0 received, 100% packet loss, time 0ms
$ sudo ip netns exec isp tcpdump -i eth0 -nn icmp       # что видит провайдер
IP 192.168.10.10 > 198.51.100.1: ICMP echo request, id 39677, seq 1, length 64

Запрос до провайдера дошёл, но с частным адресом отправителя 192.168.10.10. Провайдер не знает, куда отвечать на такой адрес: таких сетей в мире миллионы. Решение — NAT (трансляция адресов): r1 заменяет адрес отправителя своим внешним, запоминает соответствие и, получив ответ, возвращает его нужному компьютеру. Вариант, при котором подставляется адрес исходящего интерфейса, называется маскарадингом. В Linux его настраивают в nftables:

$ sudo ip netns exec r1 nft list ruleset
table ip nat {
	chain post {
		type nat hook postrouting priority srcnat; policy accept;
		oifname "wan" masquerade
	}
}
$ sudo ip netns exec h1 ping -c 1 -W 1 198.51.100.1
64 bytes from 198.51.100.1: icmp_seq=1 ttl=63 time=0.426 ms
$ sudo ip netns exec isp tcpdump -i eth0 -nn icmp
IP 203.0.113.2 > 198.51.100.1: ICMP echo request, id 39699, seq 1, length 64
IP 198.51.100.1 > 203.0.113.2: ICMP echo reply, id 39699, seq 1, length 64

Провайдер теперь видит только адрес r1. Так работает каждый домашний роутер: десяток устройств выходит в интернет через один публичный адрес.

Следствия NAT

  • Снаружи внутрь не зайти. Соединение может начать только внутренний узел. Чтобы опубликовать сервер из локальной сети, на маршрутизаторе настраивают проброс порта (DNAT): «всё, что пришло на внешний порт 443, — на 192.168.10.50:443».
  • NAT — не защита. Он мешает входящим соединениям побочно; защищает межсетевой экран с явными правилами.
  • Двойной NAT у провайдера. Если у роутера внешний адрес из 100.64.0.0/10, провайдер делает свой NAT (CGNAT), и проброс порта на роутере не поможет — нужен «белый» адрес.
05

IPv6

IPv6 решает проблему нехватки адресов: в нём 128 бит. Адрес пишут восемью группами по 4 шестнадцатеричные цифры через двоеточие; ведущие нули в группе опускают, а одну серию нулевых групп заменяют на ::.

2001:0db8:0000:0000:0000:ff00:0042:8329
2001:db8::ff00:42:8329                    # то же самое, сокращённо
$ ip -6 addr show ens18
2: ens18: <BROADCAST,MULTICAST,UP,LOWER_UP> mtu 1500 state UP qlen 1000
    inet6 fe80::b641:8f47:5a50:a157/64 scope link
       valid_lft forever preferred_lft forever
АдресНазначение
fe80::/10 — link-localЕсть у каждого интерфейса всегда, работает только в пределах своей сети. В выводе выше — именно он
2000::/3 — глобальныеПубличные адреса интернета, выдаются провайдером
fd00::/8 — уникальные локальныеАналог частных сетей IPv4
::1Петлевой, аналог 127.0.0.1

Главные отличия от IPv4

  • Подсеть для узлов — всегда /64; провайдер выдаёт клиенту блок /56 или /48 — сотни подсетей.
  • Адрес узел может получить сам: маршрутизатор объявляет префикс сети, узел достраивает адрес (SLAAC). DHCPv6 — по желанию.
  • ARP нет — его роль выполняет протокол обнаружения соседей NDP поверх ICMPv6. Широковещания нет — только групповые адреса.
  • NAT не нужен: у каждого узла глобальный адрес. Поэтому межсетевой экран для IPv6 обязателен — иначе внутренние узлы доступны из интернета.

В России IPv6 у домашних абонентов встречается редко, а в ЦОД и облаках — всё чаще. Сервис, слушающий порт на [::], доступен и по IPv6: проверяйте, что правила межсетевого экрана заданы для обоих протоколов.

Ключевые выводы модуля

Запомните главное

  • Узел в своей сети — напрямую, в чужой — через шлюз; решение по таблице маршрутов (ip route, ip route get)
  • Побеждает маршрут с самым длинным префиксом; default — последний вариант
  • Linux пересылает чужие пакеты только с net.ipv4.ip_forward = 1; каждый маршрутизатор уменьшает TTL
  • NAT подменяет частный адрес внешним; входящие соединения — только через проброс порта
  • IPv6: 128 бит, подсети /64, link-local fe80::, без ARP и NAT — нужен межсетевой экран
Практические задания — на учебном портале. Задания, критерии оценивания, сдача работ и оценки преподавателя — в курсе на portal.nevabit.ru. Учётную запись выдаёт преподаватель.
Модуль 03: IPv4 Все модули Модуль 05: TCP и UDP