Сетевой уровень: адресация и маршрутизация

Задачи

  1. Глобальная идентификация (адресация)
    1. Структура адреса
    2. Механизм раздачи идентификаторов

  2. Алгоритм доставки (маршрутизация)
    1. Известный маршрут и маршрут по умолчанию внутри крупной сети
    2. Связность крупных сетей (карта достижимости / стоимость)

Динамическая (в общем случае) природа обеих задач.

IPv4

rfc791

Протоколы сетевого и сетевого/интерфейсного уровня

Настройка IP в Linux и табличная маршрутизация

Сетевая маска: количество старших разрядов в двоичном представлении адреса, соответствующих «адресу сети». Оставшиеся младшие биты — адрес абонента в этой сети:

Настройка «выхода в Интернет» в виртуалке (без DNS)

   1 srv:~# ip link set eth0 up
   2 srv:~# ip address add dev eth0 10.0.2.15/24
   3 srv:~# ip route add default via 10.0.2.2
   4 srv:~# traceroute 5.255.255.242

Что представляет собой таблица маршрутизации:

   1 srv:~# ip r
   2 default via 10.0.2.2 dev eth0 
   3 10.0.2.0/24 dev eth0 proto kernel scope link src 10.0.2.15 
   4 

Заодно посмотрим

   1 base:~# ip neighbour 
   2 10.0.2.2 dev eth0 lladdr 52:54:00:12:35:02 REACHABLE
   3 

Настройка внутренней подсети

При настройке IP на сетевом интерфейсе Linux указывается размер подсети, тем самым заполняется таблица маршрутизации записью вида: «такая-то IP-подсеть находится непосредственно за этим сетевым интерфейсом»

   1 srv:~# ip link set dev eth1 up
   2 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 
   5 

Как работает ARP

Вывод tcpdump:

Поддерживается ядром Linux.

Маршрутизация между двумя сетями

Машина router подключена сразу к двум локальным сетям: в одной из них (intnet) находится srv, в другой — deep — ещё одна машина, client

Пока что маршрутизировать никто никого не хочет:

  1. Чтобы linux-машина заработала маршрутизатором, надо включить на ней специальную настройку ядра ip_forward:

       1 router:~# sysctl net.ipv4.ip_forward
       2 net.ipv4.ip_forward = 0
       3 router:~# sysctl net.ipv4.ip_forward=1
       4 router:~# sysctl net.ipv4.ip_forward
       5 net.ipv4.ip_forward = 1
       6 
    
    • (или, что то же самое: router:~# echo 1 > /proc/sys/net/ipv4/ip_forward)

  2. Сейчас машина srv не знает о существовании сети 10.40.60.0/24, а client — о 10.20.30.0/24. Надо добавить это знание в таблицу маршрутов. Сделаем это двумя разными способами:

    • На client зарегистрируем router как маршрутизатор по умолчанию:

         1 client:~# ip route add default via 10.40.60.2
         2 client:~# ip r
         3 default via 10.40.60.2 dev eth1 
         4 10.40.60.0/24 dev eth1 proto kernel scope link src 10.40.60.1 
         5 
      
    • На srv зарегистрируем router как маршрутизатор для конкретной сети 10.40.60.0/24`

         1 srv:~# ip r
         2 10.20.30.0/24 dev eth1 proto kernel scope link src 10.20.30.1 
         3 10.40.60.0/24 via 10.20.30.2 dev eth1 
         4 srv:~# ping -c1 10.40.60.1
         5 PING 10.40.60.1 (10.40.60.1) 56(84) bytes of data.
         6 64 bytes from 10.40.60.1: icmp_seq=1 ttl=63 time=0.523 ms
         7 
         8 --- 10.40.60.1 ping statistics ---
         9 1 packets transmitted, 1 received, 0% packet loss, time 0ms
        10 rtt min/avg/max/mdev = 0.523/0.523/0.523/0.000 ms
        11 
      

Простая табличная маршрутизация

  1. Получаем пакет
  2. Просматриваем все записи в таблице, из них выбираем те, для которых адрес сети совпадает с адресом сети получателя пакета (если к нему применить соответствующую маску)
    • Если настроен маршрут по умолчанию (с сетевой маской длины 0), он всегда подходит
  3. Среди подходящих записей выбирается та, что имеет самую длинную сетевую маску (т. е. в которой меньше абонентов)
  4. Если это запись вида «сеть dev интерфейс», обращаемся за адресом к ARP-таблице, если «сеть via адрес» — используем этот адрес
  5. Пересылаем пакет на найденный адрес

Сети /32 и proxy ARP

Присоединим к маршрутизатору ещё один компьютер single посредством ещё одной среде передачи данных — deep3 — через интерфейс eth3, причём IP-адрес возьмём из диапазона 10.40.60.0/24. Как сделать его достижимым?

Вариант 1

Разбить 10.40.60.0/24 на две подсети (скажем, 10.40.60.0/25 и 10.40.60.128/25; (можно воспользоваться ipcalc, чтобы посмотреть, почему 128) и перераспределить адреса абонентов так, чтобы после применения сетевой маски абоненты deep оказались в одном диапазоне, а deep2 — в другом.

  • Потребуется перенастройка всех интерфейсов этих сетей на новую сетевую маску /25

Вариант 2

Если в deep2 у нас только один абонент single, можно попробовать по протоколу ARP всем рассказывать, что MAC-адрес этого single принадлежит самому router, а когда ему пришлют фрейм для single — декапсулировать и маршрутизировать его!

  • ProxyARP.png

  • Воспользуемся вариантом маршрутизации вида «интерфейс: сеть/32» + «маршрут: абонент/32 → интерфейс»:
       1 router:~# ip l set eth3 up
       2 router:~# ip addr add 10.40.60.102/32 dev eth3
       3 router:~# ip route add 10.40.60.100/32 dev eth3
       4 router:~# ip addr show dev eth3
       5 5: eth3: <BROADCAST,MULTICAST,UP,LOWER_UP> mtu 1500 qdisc fq_codel state UP group default qlen 1000
       6     link/ether 08:00:27:65:97:e6 brd ff:ff:ff:ff:ff:ff
       7     altname enp0s10
       8 router:~# ip route 
       9 10.20.30.0/24 dev eth1 proto kernel scope link src 10.20.30.2 
      10 10.40.60.0/24 dev eth2 proto kernel scope link src 10.40.60.2 
      11 10.40.60.100 dev eth3 scope link 
      12 
    
  • Настройка адреса в сети 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, находящегося в «старой» сети:

Почему так? Маршрут вида 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, и перешлёт его.

Теперь работает:

   1 client:~# ping -c1 10.40.60.100
   2 PING 10.40.60.100 (10.40.60.100) 56(84) bytes of data.
   3 64 bytes from 10.40.60.100: icmp_seq=1 ttl=63 time=603 ms
   4 client:~# ip n
   5 10.40.60.2 dev eth1 lladdr 08:00:27:7a:10:f4 STALE
   6 10.40.60.100 dev eth1 lladdr 08:00:27:7a:10:f4 REACHABL
   7 

Proxy ARP можно включить на нескольких интерфейсах целиком:

Д/З

Образ не изменился.

Задание 4

  1. Суть: объединить четыре компьютера тремя сетями по простой линейной схеме:
    • clone ←сеть3→ router2 ←сеть2→ router1 ←сеть1→ base

    • На машинах clone и base — по одному интерфейсу

    • На машинах router2 и router1 — два, там настроить маршрутизацию

    • Обеспечить доступность между clone и base

  2. Отчёт (выполнятся с нуля на ненастроенных машинах):
    1. report 4 clone

      • Настройка/поднятие интерфейса
      • Дополнительные настройки маршрутизации (если нужны)
      • tcpdump -c4 (должен показать пинги)

    2. report 4 router2

      • Настройка/поднятие двух интерфейсов
      • Дополнительные настройки маршрутизации (если нужны)
    3. report 4 router1

      • Настройка/поднятие двух интерфейсов
      • Дополнительные настройки маршрутизации (если нужны)
    4. report 4 base (выполняется последним)

      • Настройка/поднятие интерфейса
      • Дополнительные настройки маршрутизации (если нужны)
      • ping -c4 адрес_clone (должен проходить)

  3. Четыре отчёта (report.04.base, report.04.router1, report.04.router2 и report.04.clone) именно с такими названиями переслать одним письмом в качестве приложений на uneexlectures@cs.msu.ru

    • В теме письма должно встречаться слово LinuxNetwork2024

LecturesCMC/LinuxNetwork2024/04_AddressAndRoute (последним исправлял пользователь FrBrGeorge 2024-03-16 17:30:37)