Домашнее задание №5
Задание выполняется на виртуальных машинах. После выполнения нужно записаться в очередь на проверку. Дедлайн – 01:00 AM (час ночи) 18 декабря.
Создание виртуального узла сети
Ядро Linux обладает весьма обширной поддержкой различных сетевых стандартов. Благодаря наличию механизма пространств имен, в том числе сетевых, на одном ядре Linux можно эмулировать целую виртуальную компьютерную сеть практически с любой топологией. Чтобы в процессе обучения сетевым возможностям Linux у вас было меньше шансов потерять доступ к виртуальной машине, вы будете настраивать виртуальные сетевые интерфейсы на виртуальных узлах сети, эмулированных с помощью изолированных сетевых пространст имен.
Предлагается использовать изоляцию только на уровне сетевого пространства имен, виртуальный узел будет разделять с основной системой пространство точек монтирования, пространство процессов, пользователей и т.д. Для сетевого взаимодействия с эмулируемым узлом будет использоваться пара связанных виртуальных сетевых интерфейсов, один из которых будет в пространстве узла, а второй – в базовом пространстве имен.
Создание связанных виртуальных интерфейсов
Создайте пару связанных виртуальных интерфейсов типа veth с помощью программы ip. За манипуляции с сетевыми интерфейсами в этой программе отвечает объект link, см. ip-link(8). Если при создании одного интерфейса veth указать дополнительный аргумент peer name, то второй связанный интерфейс с указанным именем будет создан автоматически. Все пакеты, отправленные в один из интефейсов, будут доступны во втором, и наоборот. Интерфейсы должны иметь имена ve0 и ve1. Убедитесь, что новые интерфейсы появились с помощью ip link show.
Теперь интерфейсы ve0 и ve1 нужно перевести в состояние up, используйте для этого ip link set. Убедитесь, что в описании интерфейсов появились ключевые слова UP и LOWER_UP.
Создание сетевого пространства имен
Далее необходимо создать новое сетевое пространство имен. Проще всего это сделать с помощью той же программы ip, тип объекта netns (ip-netns(8)). Имя нового пространства имен – ns0. Проверьте, что пространство имен появилось с помощью ip netns list.
В новом пространстве имен действует свой набор сетевых устройств и таблиц маршрутизации. Они могут быть использованы для эмуляции отдельных узлов сети.
Прочитайте описание ip netns exec, позволяющей выполнить произвольную команду в указанном пространстве имен, и получите с помощью нее список сетевых интерфейсов в ns0.
Использование veth для связи пространст имен
Если один виртуальный интерфейс из пары связанных присвоить пространству имен ns0, то можно будет настроить обмен пакетами. Присвоение просто осуществляется заданием аттрибута netns для соответствующего интерфейса, см. описание команды set для объекта link программы ip. Присвойте ve1 пространству имен ns0 и убедитесь, что он теперь отсутствует в списке интерфейсов базового пространства имен, но появился в новом.
Сетевой интерфейс ve1 теперь можно настраивать так, будто это единственный интерфейс узла сети, который вы эмулируете с помощью ns0. Сетевой доступ к этому узлу из базового пространства имен можно будет получить через интерфейс ve0.
Добавьте интерфейсу ve1 IP-адрес 172.18.1.1 из подсети 172.18.1.0 с помощью ip-address(8). Подсеть указывается с помощью сетевой маски в составе самого IP-адреса. Это сразу добавит соответствующее правило маршрутизации в таблицу маршрутизации пространства имен ns0.
Проверка связи с помощью ping
Ваша задача – запустить программу ping в пространстве ns0 и выяснить, какие пакеты приходят на интерфейс ve0 с помощью tcpdump.
Сначала запустите tcpdump в базовом пространстве имен, в опциях указав только правильный сетевой интерфейс.
В пространстве ns0 пошлите один запрос (опция -c) с помощью ping на адрес 172.18.1.2. Для такого адреса уже есть подходящая запись в таблице маршрутизации, если вы правильно указали маску подсети при добавлении адреса интерфейсу ve1. Поэтому необходимые ping пакеты будут отправлены через интерфейс ve1. Но в виртуальной сети отсутствует узел с указанным адресом, поэтому вы сможете увидеть только безуспешную попытку определения физического адреса получателя с помощью ARP. После истечения таймаута утилита ping сообщит, что пакет был отправлен, но ответа на него получено не было. Хотя, на самом деле, пакет ICMP даже не был "до конца" отправлен. Отправка завершилась неудачей на этапе выяснения адреса получателя на канальном уровне стека сетевых протоколов.
Добавление второго узла сети
Чтобы получить ответ на ping, нужно добавить второй узел сети. Проделав аналогичные операции, создайте пространство имен ns1 и пару виртуальных интерфейсов ve2/ve3. Переместите ve3 в ns1 и добавьте этому интерфейсу адрес 172.18.1.2 из той же подсети. Не забудьте "поднять" сетевые интерфейсы.
Полностью повторите тест с ping и tcpdump, изменилось ли что-нибудь?
Проблема в том, что каждый из узлов сейчас соединен с базовым пространством имен, но они не соединены между собой. Никто магическим образом не "перекладывает" пакеты из ve0 в ve2 и обратно. В реальной компьютерной сети простейшим устройством, которое осуществляет такое "перекладывание", является мост (bridge). Это устройство тоже можно эмулировать в Linux с помощью сетевого интерфейса типа bridge.
Добавьте виртуальный мост с именем br0 в базовое пространство имен и переведите его в состояние up.
Теперь необходимо подключить к мосту устройства, которые он будет объединять, т.е. ve0 и ve2. Это делается путем установки атрибута master у подключаемых интерфейсов. С помощью команды bridge link show br0 убедитесь, что оба интерфейса подключены к мосту.
Программа bridge – это еще одна утилита из того же пакета, что и ip. Как можно это проверить? Как узнать имя этого пакета?
Теперь повторите тест с ping, в выдаче tcpdump на этот раз должны быть признаки не только удачного запроса ARP, но и обмен сообщениями ICMP типов echo request/reply. Обратите внимание, что при отправке ответа на ping-запрос тоже потребовалось знать MAC-адрес получателя. Он был кэширован во время ответа на ARP-запрос от 172.18.1.1, но с пометкой, что требуется перепроверка. Перепроверка отложенная, по умолчанию осуществляется через 5 секунд.
Добавления простого правила маршрутизации
Добавьте интерфейсу ve3 адрес 172.18.10.1/24 и попробуйте выполнить в ns0 ping на этот адрес. Полученное сообщение означает, что ядро Linux не знает даже в какой интерфейс отправлять пакеты, ведь в таблице маршрутизации отсуствует запись, соответствующая адресу 172.18.10.1.
Операции с записями в таблице маршрутизации тоже выполняются с помощью ip, название объекта – route. Просмотрите ip-route(8) и узнайте, как просмотреть существующие записи в таблице маршрутизации в ns0. Добавьте запись для 172.18.10.1 аналогичную той, что уже присутствует в таблице для подсети 172.18.1.0/24. В данном случае вам потребуется добавить запись не для целой подсети, а только для 172.18.10.1. При добавлении записи будет достаточно указать адрес получателя и название интерфейса, в который нужно помещать пакеты с таким адресом получателя. Убедитесь, что запись появилась в таблице.
Теперь повторите эксперимент с ping в ns0 на адрес 172.18.10.1, он должен пройти успешно.
Для зачета этого домашнего задания вам потребуется создать файл /root/task5.log, в котором сначала будет приведена выдача ip netns list в базовом пространстве имен. Далее в этом же файле должна следовать выдача tcpdump на интерфейсе ve0 на время отправки запроса ping в пространстве ns0 на адрес 172.18.10.1. В выдаче tcpdump могут отсуствовать запросы ARP, так как их результат на некоторое время кэшируется, чтобы не перегружать сеть. Кроме того, могут присутствовать запросы ICMPv6 от интерфейсов, пытающихся обнаружить роутер для IPv6, удалять их не надо.
