Сетевой уровень: адресация и маршрутизация
Из-за технических трудностей сегодняшняя лекция вышла сумбурной и урезанной. Здесь будет три раздела и что перенесено на следующую лекцию
Слегка запоздалое объявление: Сети для самых маленьких — хороший ресурс (недостаток: специфика не-linux сетевого оборудования, где его в домашних условиях взять?).
Задачи:
- Глобальная идентификация (адресация)
- Структура адреса
Механизм раздачи
- Алгоритм доставки (маршрутизация)
- Известный маршрут и маршрут по умолчанию внутри крупной сети
- Связность крупных сетей (карта достижимости / стоимость)
IPv4
- Структура адреса.
- адрес сети + адрес абонента
- сетевая маска
- широковещательный адрес
Legacy: классы (NB: 1110 — multicast)
Адреса интерфейсов в Linux: ip a (add, del и т. п.)
- Принятие решения о маршрутизации
Таблица маршрутизации Linux: ip route
- Заполнение маршрутных таблиц:
Специальные адреса и сети (rfc5735)
0.0.0.0/8
"This" Network
rfc1122, Section 3.2.1.3
10.0.0.0/8
Private-Use Networks
127.0.0.0/8
Loopback
rfc1122, Section 3.2.1.3
169.254.0.0/16
Link Local
172.16.0.0/12
Private-Use Networks
192.0.0.0/24
IETF Protocol Assignments
192.0.2.0/24
TEST-NET-1
192.88.99.0/24
6to4 Relay Anycast
192.168.0.0/16
Private-Use Networks
198.18.0.0/15
Network Interconnect Device Benchmark Testing
198.51.100.0/24
TEST-NET-2
203.0.113.0/24
TEST-NET-3
224.0.0.0/4
Multicast
240.0.0.0/4
Reserved for Future Use
rfc1112, Section 4
255.255.255.255/32
Limited Broadcast
Протоколы сетевого и сетевого/интерфейсного уровня
- ARP
ip neigh
- proxy arp
ICMP (rfc1122)
работа traceroute
Path MTU Discovery (RFC4821 / Maximum_transmission_unit)
- IPSec, RARP, BOOTP, ...
Настройка IP в Linux и табличная маршрутизация
Сетевая маска: количество старших разрядов в двоичном представлении адреса, соответствующих «адресу сети». Оставшиеся младшие биты — адрес абонента в этой сети:
Часто записывается как последовательность 1 в двоичном виде
# ipcalc 10.20.30.40/24 Address: 10.20.30.40 00001010.00010100.00011110. 00101000 Netmask: 255.255.255.0 = 24 11111111.11111111.11111111. 00000000 Wildcard: 0.0.0.255 00000000.00000000.00000000. 11111111 => Network: 10.20.30.0/24 00001010.00010100.00011110. 00000000 HostMin: 10.20.30.1 00001010.00010100.00011110. 00000001 HostMax: 10.20.30.254 00001010.00010100.00011110. 11111110 Broadcast: 10.20.30.255 00001010.00010100.00011110. 11111111 Hosts/Net: 254 Class A, Private Internet
- Запись в десятичном виде придумали ещё во времена legacy network classes, когда адрес проходил по границе байта. Сейчас это необязательно, а десятичная запись неудобна:
# ipcalc -n 192.168.11.1 Address: 192.168.11.1 11000000.10101000.00001011. 00000001 Netmask: 255.255.255.0 = 24 11111111.11111111.11111111. 00000000 Wildcard: 0.0.0.255 00000000.00000000.00000000. 11111111 => Network: 192.168.11.0/24 11000000.10101000.00001011. 00000000 HostMin: 192.168.11.1 11000000.10101000.00001011. 00000001 HostMax: 192.168.11.254 11000000.10101000.00001011. 11111110 Broadcast: 192.168.11.255 11000000.10101000.00001011. 11111111 Hosts/Net: 254 Class C, Private Internet
При настройке IP на сетевом интерфейсе Linux указывается размер подсети, тем самым заполняется таблица маршрутизации записью вида: «такая-то IP-подсеть находится непосредственно за этим сетевым интерфейсом»
1 srv:~# ip link set dev eth1 up
2 [root@srv] # ip addr add dev eth1 10.20.30.1/24
3 srv:~# ip r
4 10.20.30.0/24 dev eth1 proto kernel scope link src 10.20.30.1 linkdown
5 srv:~# ping 10.20.30.2
6 PING 10.20.30.2 (10.20.30.2) 56(84) bytes of data.
7 ^C
8 1 packets transmitted, 0 received, 100% packet loss, time 0ms
9 srv:~# ip n
10 10.20.30.2 dev eth1 INCOMPLETE
11 srv:~# ping 10.20.31.2
12 ping: connect: Network is unreachable
13
Адрес сети интерфейса eth1 — 10.20.30.0/24 совпадает с абонентским (10.20.30.2), если применить ту же сетевую маску /24.
Это значит, что с абонентом мы связаны единой средой передачи данных, и сетевая подсистема вправе ожидать появления MAC-адреса этого 10.20.30.2 в ARP-таблице (ip neighbour)
При применении той же сетевой маски к 10.20.31.2 мы получаем адрес 10.20.31.0/24, он ни с чем не совпадает, а других записей в таблице маршрутизации у нас нет — как следствие, сообщение о недостижимости.
Подключим к этой машине маршрутизатор, а ко второму интерфейсу маршрутизатора — ещё одну машину
- маршрутизатор:
1 router:~# ip link set dev eth1 up 2 router:~# ip addr add dev eth1 10.20.30.2/24 3 router:~# ping -c 1 10.20.30.1 4 PING 10.20.30.1 (10.20.30.1) 56(84) bytes of data. 5 64 bytes from 10.20.30.1: icmp_seq=1 ttl=64 time=1.84 ms 6 router:~# ip n 7 10.20.30.1 dev eth1 lladdr 08:00:27:f5:75:0c REACHABLE 8 router:~# ip link set dev eth2 up 9 router:~# ip addr add dev eth2 10.40.60.2/24
- удалённая машина:
1 clone:~# ip link set dev eth1 up 2 clone:~# ip addr add dev eth1 10.40.60.1/24 3 clone:~# ping -c1 10.40.60.2 4 PING 10.40.60.2 (10.40.60.2) 56(84) bytes of data. 5 64 bytes from 10.40.60.2: icmp_seq=1 ttl=64 time=0.864 ms 6 clone:~# ping 10.20.30.1 7 ping: connect: Network is unreachable 8 clone:~# ip route add default via 10.40.60.2 9 clone:~# ip r 10 default via 10.40.60.2 dev eth1 11 10.40.60.0/24 dev eth1 proto kernel scope link src 10.40.60.1 12
default — это такая сеть с нулевой сетевой маской 0.0.0.0/0 — т. е. весь Интернет. Такой записи соответствует вообще любой пакет.
Если адрес получателя в пакете отвечает сразу нескольким записям в таблице маршрутизации, выбирается запись с наибольшей сетевой маской (т. е. «самая определённая»)
Надо сделать ещё два действия:
Превратить router в собственно маршрутизатор: включить в ядре поддержку пересылки IP-пакетов
1 router:~# sysctl net.ipv4.ip_forward=1
- или, что то же самое:
1 router:~# echo 1 > /proc/sys/net/ipv4/ip_forward
Настроить маршрут на машине srv. Не будем добавлять default, а используем более точное указание сети:
srv:~# ip route add 10.40.60.0/24 via 10.20.30.2 srv:~# ip r 10.20.30.0/24 dev eth1 proto kernel scope link src 10.20.30.1 10.40.60.0/24 via 10.20.30.2 dev eth1 srv:~# ping -c1 10.20.30.1 PING 10.20.30.1 (10.20.30.1) 56(84) bytes of data. 64 bytes from 10.20.30.1: icmp_seq=1 ttl=64 time=0.041 ms
Вторая запись в таблице означает: нам известно, что для посылки пакетов в сеть 10.40.60.0/24, их надо направлять на 10.20.30.2 (это маршрутизатор, он разберётся)
Простая табличная маршрутизация:
- Получаем пакет
- Просматриваем все записи в таблице, из них выбираем те, для которых адрес сети совпадает с адресом сети получателя пакета (если к нему применить соответствующую маску)
- Если настроен маршрут по умолчанию (с сетевой маской длины 0), он всегда подходит
- Среди подходящих записей выбирается та, что имеет самую длинную сетевую маску (т. е. в которой меньше абонентов)
- Если это запись вида «сеть dev интерфейс», обращаемся за адресом к ARP-таблице, если «сеть via адрес» — используем этот адрес
- Пересылаем пакет на найденный адрес
Сети /32 и proxy ARP
Присоединим к маршрутизатору ещё один компьютер посредством ещё одной сети через интерфейс eth3, причём IP-адрес возьмём из диапазона 10.40.60.0/24. Как сделать его достижимым?
Есть два пути. Можно поисследовать IP-адреса всех имеющихся в «старой» сети 10.40.60.0/24 (которая видна на router за интерфейсом eth2), и разбить её на две сети /25. При этом «старые» абоненты (у нас такой вообще один) останутся в сети 10.40.60.0/25, а «новые» будем снабжать ip-адресами из сети 10.40.60.128/25, и интерфейсу eth3 на router тоже выдать адрес из этого диапазона (можно воспользоваться ipcalc, чтобы посмотреть, почему 128). Поменять /24 на /25 надо будет на всех абонентах, принадлежащих этим диапазонам.
(TODO нужен ли пример?)
Но что если за интерфейсом eth2 уже много самых разных абонентов, и нет возможности / желания менять все настройки?
Тогда воспользуемся вариантом маршрутизации вида «сеть/32 → интерфейс» и «абонент/32 → интерфейс»:
1 router:~# ip addr add dev eth3 10.40.60.102/32
2 router:~# ip l set eth3 up
3 router:~# ip route add 10.40.60.100/32 dev eth3
4 router:~# ip addr
5 1: lo: <LOOPBACK,UP,LOWER_UP> mtu 65536 qdisc noqueue state UNKNOWN group default qlen 1000
6 link/loopback 00:00:00:00:00:00 brd 00:00:00:00:00:00
7 inet 127.0.0.1/8 scope host lo
8 valid_lft forever preferred_lft forever
9 2: eth0: <BROADCAST,MULTICAST> mtu 1500 qdisc noop state DOWN group default qlen 1000
10 link/ether 08:00:27:cd:9b:53 brd ff:ff:ff:ff:ff:ff
11 altname enp0s3
12 3: eth1: <BROADCAST,MULTICAST,UP,LOWER_UP> mtu 1500 qdisc fq_codel state UP group default qlen 1000
13 link/ether 08:00:27:f3:ec:2d brd ff:ff:ff:ff:ff:ff
14 altname enp0s8
15 inet 10.20.30.2/24 scope global eth1
16 valid_lft forever preferred_lft forever
17 4: eth2: <BROADCAST,MULTICAST,UP,LOWER_UP> mtu 1500 qdisc fq_codel state UP group default qlen 1000
18 link/ether 08:00:27:97:d9:52 brd ff:ff:ff:ff:ff:ff
19 altname enp0s9
20 inet 10.40.60.2/24 scope global eth2
21 valid_lft forever preferred_lft forever
22 5: eth3: <BROADCAST,MULTICAST,UP,LOWER_UP> mtu 1500 qdisc fq_codel state UP group default qlen 1000
23 link/ether 08:00:27:77:03:e7 brd ff:ff:ff:ff:ff:ff
24 altname enp0s10
25 inet 10.40.60.102/32 scope global eth3
26 valid_lft forever preferred_lft forever
27 router:~# ip route
28 10.20.30.0/24 dev eth1 proto kernel scope link src 10.20.30.2
29 10.40.60.0/24 dev eth2 proto kernel scope link src 10.40.60.2
30 10.40.60.100 dev eth3 scope link
31
Настройка адреса в сети 10.40.60.102/32 — это способ «привесить» интерфейсу адрес, ничего при этом не меняя в таблице маршрутизации (потому что сетевая маска занимает все 32 бита: в такой сети нет абонентов).
В таблицу заносится правило вида «абонент → интерфейс», которое утверждает, что за интерфейсом eth3 доступен абонент 10.40.60.100. Поскольку сетевая маска такого правила максимальна (/32), оно считается наиболее приоритетным.
На новом абоненте (назовём его single):
1 single:~# ip link set dev eth1 up
2 single:~# ip addr add dev eth1 10.40.60.100/32
3 single:~# ip route add 10.40.60.102/32 dev eth1
4 single:~# ip route add default via 10.40.60.102
5 single:~# ip r
6 default via 10.40.60.102 dev eth1
7 10.40.60.102 dev eth1 scope link
8 single:~# ping -c1 10.20.30.1
9 PING 10.20.30.1 (10.20.30.1) 56(84) bytes of data.
10 64 bytes from 10.20.30.1: icmp_seq=1 ttl=63 time=1.29 ms
11
Proxy ARP
Однако не всё ещё работает. Например, single недоступен с абонента clone, находящегося в «старой» сети:
1 clone:~# ping -c1 10.40.60.100 2 PING 10.40.60.100 (10.40.60.100) 56(84) bytes of data. 3 From 10.40.60.1 icmp_seq=1 Destination Host Unreachable 4 1 packets transmitted, 0 received, +1 errors, 100% packet loss, time 0ms 5 clone:~# ip r 6 default via 10.40.60.2 dev eth1 7 10.40.60.0/24 dev eth1 proto kernel scope link src 10.40.60.1 8 clone:~# ip n 9 10.40.60.100 dev eth1 FAILED 10
Почему так? Маршрут вида 10.40.60.0/24 dev eth1 говорит о том, что за интерфейсом eth1 находится вся сеть 10.40.60.0/24 и, стало быть, мы вправе ожидать появления 10.40.60.100 в ARP-таблице. Но взяться ему там неоткуда: в действительности же этот абонент находится совсем в другой сети, и на arp-запрос ответа не приходит.
Решение: попросить router отвечать на приходящий из старой сети ARP-запрос адреса 10.40.60.100 что-то вроде «всё в порядке, это мой IP». Тогда у абонентов создастся впечатление, что router просто имеет два IP-адреса на соответствующем интерфейсе, и они начнут использовать при инкапсуляции на интерфейсный уровень тот же самый MAC-адрес. Получив такой фрейм, router обнаружит там IP-пакет для 10.40.60.100, и перешлёт его.
Теперь работает:
Обратите внимание на совпадение MAC-адресов, которые clone считает закреплёнными за 10.40.60.100 и 10.40.60.2
Proxy ARP можно включить на нескольких интерфейсах целиком, за это отвечает специальный sysctl, (net.ipv4.conf.интерфейс.proxy_arp, он же /proc/sys/net/ipv4/conf/интерфейс/proxy_arp). С точки зрения абонентов устройство с такой настройкой будет работать как bridge, то есть роутер уровня 2 — интерфейсного. Много интерфейсов — единое адресное пространство, в ARP-таблицах видны все абоненты. Однако в действительности маршрутизация будет идти на уровне 3, то есть IP, сетевом: полученный фреймы будут декапсулироваться до IP-пакетов, и на основании IP-адреса будет происходит пересылка (с последующей инкапсуляцией в фрейм).
Здесь начинается часть, которой не было на лекции.
TODO: хорошо бы действующий пример OSPF для пробрасывания таблиц.
На следующий раз
- Автономные системы. Маршрутизация на уровне AS (BGP)
https://img-fotki.yandex.ru/get/5637/83739833.27/0_b9007_9151d107_XL.png
- Достижимость
- Стоимость
- Full view (на сегодня порядка 1M маршрутов) + «Last resort»
- Динамика!
Policy routing
Бонус: настройка выхода в интернет
на Базовой машине:
- Маршрут по умолчанию (это понятно)
- Работа роутером (это понятно)
- Настройка NAT (а что вы хотели от Private use?)
iptables -t nat -A POSTROUTING -o интерфейс -j MASQUERADE
- стоит признаться, что внешний адрес у нас тоже private use. И следующий. Больше натов богу натов.
Везде:
- Настройка DNS
IPv6
Адрес (IPv6_address)
- 128 бит, включает идентификатор интерфейса (например, MAC или его хэш)
- Unicast: [48+] — routing prefix; [16-] — subnet id; [64] — interface identifier
- Unicast / Anycast / Multicast (нет широковещания, оно — частный случай multicast)
- Link-local адреса: уникальны только в рамках одного сегмента связи
Запись: 2001:0db8:85a3:0000:0000:8a2e:0370:7334 == 2001:db8:85a3::8a2e:370:7334
- 128 бит, включает идентификатор интерфейса (например, MAC или его хэш)
- Нет фрагментации на маршрутизаторе (либо PMTUD, либо на стороне отправителя)
- Нет CRC заголовка (есть же в data link)
- Маршрутизация
- (адрес)/(битовый размер префикса) — как в IPv4
- + Multicast (IGMP) / Anycast и т. п.
Д/З
Изменения в образе: добавлен traceroute и ipcalc
ВНИМАНИЕ: адрес пересылки отчётов изменился на uneexlectures@cs.msu.ru
Задание 4
- Суть: объединить четыре компьютера тремя сетями по простой линейной схеме:
clone ←сеть3→ router2 ←сеть2→ router1 ←сеть1→ base
На машинах clone и base — по одному интерфейсу
На машинах router2 и router1 — два, там настроить маршрутизацию
Обеспечить доступность между clone и base
- Отчёт (выполнятся с нуля на ненастроенных машинах):
report 4 clone
- Настройка/поднятие интерфейса
- Дополнительные настройки маршрутизации (если нужны)
tcpdump -c4 (должен показать пинги)
report 4 router2
- Настройка/поднятие двух интерфейсов
- Дополнительные настройки маршрутизации (если нужны)
report 4 router1
- Настройка/поднятие двух интерфейсов
- Дополнительные настройки маршрутизации (если нужны)
report 4 base (выполняется последним)
- Настройка/поднятие интерфейса
- Дополнительные настройки маршрутизации (если нужны)
ping -c4 адрес_clone (должен проходить)
Четыре отчёта (названия сохранить(должно быть: report.04.base, report.04.clone, report.04.router1, report.04.router2)) переслать одним письмом в качестве приложений на uneexlectures@cs.msu.ru