Различия между версиями 20 и 21
Версия 20 от 2022-03-16 20:28:50
Размер: 23667
Редактор: FrBrGeorge
Комментарий:
Версия 21 от 2023-03-08 01:38:35
Размер: 23669
Редактор: ArsenyMaslennikov
Комментарий: таблие
Удаления помечены так. Добавления помечены так.
Строка 157: Строка 157:
 1. Если это запись вида «сеть dev интерфейс», обращаемся за адресом к ARP-таблие, если «сеть via адрес» — используем этот адрес  1. Если это запись вида «сеть dev интерфейс», обращаемся за адресом к ARP-таблице, если «сеть via адрес» — используем этот адрес

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

/!\ Из-за технических трудностей сегодняшняя лекция вышла сумбурной и урезанной. Здесь будет три раздела

  1. что рассказано,
  2. что надо самому посмотреть,
  3. и что перенесено на следующую лекцию

Слегка запоздалое объявление: Сети для самых маленьких — хороший ресурс (недостаток: специфика не-linux сетевого оборудования, где его в домашних условиях взять?).

Задачи:

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

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

IPv4

rfc791

  • Структура адреса.
    • адрес сети + адрес абонента
    • сетевая маска
    • широковещательный адрес
    • Legacy: классы (NB: 1110 — multicast)

  • Адреса интерфейсов в Linux: ip a (add, del и т. п.)

  • Принятие решения о маршрутизации
    • Таблица маршрутизации Linux: ip route

  • Заполнение маршрутных таблиц:
    • автоматическое при добавлении сети
    • ручное
    • Локальные протоколы (RIP*, OSPF)

      • Linux/*NIX — сервер BIRD

  • Специальные адреса и сети (rfc5735)

    • 0.0.0.0/8

      "This" Network

      rfc1122, Section 3.2.1.3

      10.0.0.0/8

      Private-Use Networks

      rfc1918

      127.0.0.0/8

      Loopback

      rfc1122, Section 3.2.1.3

      169.254.0.0/16

      Link Local

      rfc3927

      172.16.0.0/12

      Private-Use Networks

      rfc1918

      192.0.0.0/24

      IETF Protocol Assignments

      rfc5736

      192.0.2.0/24

      TEST-NET-1

      rfc5737

      192.88.99.0/24

      6to4 Relay Anycast

      rfc3068

      192.168.0.0/16

      Private-Use Networks

      rfc1918

      198.18.0.0/15

      Network Interconnect Device Benchmark Testing

      rfc2544

      198.51.100.0/24

      TEST-NET-2

      rfc5737

      203.0.113.0/24

      TEST-NET-3

      rfc5737

      224.0.0.0/4

      Multicast

      rfc3171

      240.0.0.0/4

      Reserved for Future Use

      rfc1112, Section 4

      255.255.255.255/32

      Limited Broadcast

      rfc919, Section 7, rfc922, Section 7

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

Настройка 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 
  • Адрес сети интерфейса eth110.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 (это маршрутизатор, он разберётся)

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

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

Сети /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, и перешлёт его.

  •    1 router:~# ip neighbour add proxy 10.40.60.100 dev eth2
       2 router:~# ip n
       3 10.40.60.1 dev eth2 lladdr 08:00:27:61:be:45 STALE
       4 10.40.60.100 dev eth3 lladdr 08:00:27:53:d4:16 STALE
       5 router:~# ip n show proxy
       6 10.40.60.100 dev eth2  proxy
       7 
    

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

   1 clone:~# 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 clone:~# ip n
   5 10.40.60.100 dev eth1 lladdr 08:00:27:97:d9:52 REACHABLE
   6 10.40.60.2 dev eth1 lladdr 08:00:27:97:d9:52 STALE
   7 
  • Обратите внимание на совпадение 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 для пробрасывания таблиц.

На следующий раз

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

  • Нет фрагментации на маршрутизаторе (либо PMTUD, либо на стороне отправителя)
  • Нет CRC заголовка (есть же в data link)
  • Маршрутизация
    • (адрес)/(битовый размер префикса) — как в IPv4
    • + Multicast (IGMP) / Anycast и т. п.

Д/З

  • Изменения в образе: добавлен traceroute и ipcalc

  • <!> ВНИМАНИЕ: адрес пересылки отчётов изменился на uneexlectures@cs.msu.ru

Задание 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.clone, report.04.router1, report.04.router2)) переслать одним письмом в качестве приложений на uneexlectures@cs.msu.ru

LecturesCMC/LinuxNetwork2022/04_AddressAndRoute (последним исправлял пользователь ArsenyMaslennikov 2023-03-08 01:38:35)