Как мы предвидели в предыдущих уроках этой серии LFCE (Linux Foundation Certified Engineer), в этой статье мы обсудим маршрутизацию IP-трафика статически и динамически с конкретными применениями.

Представляем программу сертификации Фонда Linux
Сначала давайте разберемся с некоторыми определениями:
- Простыми словами, пакет – это основная единица, используемая для передачи информации в сети. Сети, использующие TCP/IP в качестве сетевого протокола, следуют тем же правилам для передачи данных: фактическая информация разбивается на пакеты, состоящие как из данных, так и из адреса, куда они должны быть отправлены.
- Маршрутизация – это процесс “руководства” данными от источника к месту назначения внутри сети.
- Статическая маршрутизация требует ручной настройки набора правил, определенных в таблице маршрутизации. Эти правила являются фиксированными и используются для определения пути, по которому должен проходить пакет, когда он перемещается с одной машины на другую.
- Динамическая маршрутизация, или умная маршрутизация (если хотите), означает, что система может автоматически изменять маршрут, по которому следует пакет, по мере необходимости.
Расширенная настройка IP и сетевых устройств
Пакет iproute предоставляет набор инструментов для управления сетями и контроля трафика, которые мы будем использовать на протяжении этой статьи, так как они являются заменой устаревших инструментов, таких как ifconfig и route.
Основной утилитой в наборе iproute является просто называемая ip. Ее базовый синтаксис следующий:
# ip object command
Где объект может быть только одним из следующих (показаны только наиболее часто используемые объекты – для полного списка можно обратиться к man ip):
- link: сетевое устройство.
- addr: протокольный (IP или IPv6) адрес на устройстве.
- route: запись в таблице маршрутизации.
- rule: правило в базе данных политики маршрутизации.
Где команда представляет собой конкретное действие, которое можно выполнить над объектом. Вы можете запустить следующую команду, чтобы отобразить полный список команд, которые можно применить к конкретному объекту:
# ip object help
Например,
# ip link help

На приведенном выше изображении показано, что вы можете изменить статус сетевого интерфейса с помощью следующей команды:
# ip link set interface {up | down}
Для большего количества примеров команды ‘ip‘ читайте 10 полезных команд ‘ip’ для настройки IP-адреса
Пример 1: Отключение и включение сетевого интерфейса
В этом примере мы отключим и включим eth1:
# ip link show # ip link set eth1 down # ip link show

Если вы хотите снова включить eth1,
# ip link set eth1 up
Вместо отображения всех сетевых интерфейсов, мы можем указать один из них:
# ip link show eth1
Что вернет всю информацию для eth1.
Пример 2: Отображение основной таблицы маршрутизации
Вы можете просмотреть вашу текущую основную таблицу маршрутизации с помощью любой из следующих 3 команд:
# ip route show # route -n # netstat -rn

Первый столбец в выводе трех команд указывает на целевую сеть. Вывод команды ip route show (после ключевого слова dev) также представляет собой сетевые устройства, которые служат физическим шлюзом для этих сетей.
Хотя в настоящее время предпочтительнее использовать команду ip вместо route, вы все еще можете обратиться к man ip-route и man route для подробного объяснения остальных столбцов.
Пример 3: Использование Linux-сервера для маршрутизации пакетов между двумя частными сетями
Мы хотим маршрутизировать icmp (ping) пакеты от dev2 к dev4 и наоборот (обратите внимание, что обе клиентские машины находятся в разных сетях). Имя каждого сетевого интерфейса вместе с соответствующим IPv4-адресом указано в квадратных скобках.
Наша тестовая среда выглядит следующим образом:
Client 1: CentOS 7 [enp0s3: 192.168.0.17/24] - dev1 Router: Debian Wheezy 7.7 [eth0: 192.168.0.15/24, eth1: 10.0.0.15/24] - dev2 Client 2: openSUSE 13.2 [enp0s3: 10.0.0.18/24] - dev4
Давайте посмотрим таблицу маршрутизации в dev1 (CentOS box):
# ip route show
а затем измените ее, чтобы использовать свой сетевой интерфейс enp0s3 и соединение с 192.168.0.15 для доступа к хостам в сети 10.0.0.0/24:
# ip route add 10.0.0.0/24 via 192.168.0.15 dev enp0s3
Что в сущности означает: “Добавить маршрут к сети 10.0.0.0/24 через сетевой интерфейс enp0s3, используя 192.168.0.15 в качестве шлюза”.

Точно так же в dev4 (openSUSE box) для пинга хостов в сети 192.168.0.0/24:
# ip route add 192.168.0.0/24 via 10.0.0.15 dev enp0s3

Наконец, нам нужно включить пересылку в нашем маршрутизаторе Debian:
# echo 1 > /proc/sys/net/ipv4/ip_forward
Теперь давайте сделаем пинг:

и,

Чтобы сделать эти настройки постоянными после перезагрузки, отредактируйте /etc/sysctl.conf на маршрутизаторе и убедитесь, что переменная net.ipv4.ip_forward установлена в true следующим образом:
net.ipv4.ip_forward = 1
Настройте сетевые интерфейсы на обоих клиентах (найдите файл конфигурации в /etc/sysconfig/network на openSUSE и /etc/sysconfig/network-scripts на CentOS – в обоих случаях он называется ifcfg-enp0s3).
Вот файл конфигурации с openSUSE:
BOOTPROTO=static BROADCAST=10.0.0.255 IPADDR=10.0.0.18 NETMASK=255.255.255.0 GATEWAY=10.0.0.15 NAME=enp0s3 NETWORK=10.0.0.0 ONBOOT=yes
Пример 4: Использование Linux-сервера для маршрутизации пакетов между частными сетями и Интернетом
Еще один сценарий, когда Linux-машина может быть использована в качестве маршрутизатора, это когда вам нужно поделиться своим интернет-соединением с частной локальной сетью.
Router: Debian Wheezy 7.7 [eth0: Public IP, eth1: 10.0.0.15/24] - dev2 Client: openSUSE 13.2 [enp0s3: 10.0.0.18/24] - dev4
Помимо настройки пересылки пакетов и статической таблицы маршрутизации на клиенте, как в предыдущем примере, нам нужно добавить несколько правил iptables в маршрутизатор:
# iptables -t nat -A POSTROUTING -o eth0 -j MASQUERADE # iptables -A FORWARD -i eth0 -o eth1 -m state --state RELATED,ESTABLISHED -j ACCEPT # iptables -A FORWARD -i eth1 -o eth0 -j ACCEPT
Первая команда добавляет правило в цепочку POSTROUTING в таблице nat (Network Address Translation), указывая, что сетевой интерфейс eth0 должен использоваться для исходящих пакетов.
MASQUERADE указывает, что этот сетевой интерфейс имеет динамический IP и что перед отправкой пакета в “дикий мир Интернета”, частый исходный адрес пакета должен быть изменен на общедоступный IP-адрес маршрутизатора.
В локальной сети с множеством хостов маршрутизатор отслеживает установленные соединения в /proc/net/ip_conntrack, чтобы знать, куда возвращать ответ из Интернета.
Только часть вывода:
# cat /proc/net/ip_conntrack
показана на следующем скриншоте.

Где источник (частный IP-адрес с openSUSE) и назначение (Google DNS) пакетов выделены. Это был результат выполнения:
# curl www.tecmint.com
на openSUSE.
Как я уверен, вы уже догадались, что маршрутизатор использует 8.8.8.8 от Google в качестве сервера имен, что объясняет, почему адрес назначения исходящих пакетов указывает на этот адрес.
Примечание: Входящие пакеты из Интернета принимаются только в том случае, если они являются частью уже установленного соединения (команда #2), в то время как исходящие пакеты разрешены для “свободного выхода” (команда #3).
Не забудьте сделать ваши правила iptables постоянными, следуя шагам, описанным в Часть 8 – Настройка брандмауэра Iptables этой серии.
Динамическая маршрутизация с Quagga
В настоящее время наиболее используемым инструментом для динамической маршрутизации в Linux является quagga. Он позволяет системным администраторам реализовать, сравнительно недорогим Linux-сервером, ту же функциональность, которую предоставляют мощные (и дорогостоящие) маршрутизаторы Cisco.
Сам инструмент не обрабатывает маршрутизацию, а скорее изменяет таблицу маршрутизации ядра по мере изучения новых лучших маршрутов для обработки пакетов.
Поскольку это форк zebra, программы, разработка которой прекратилась некоторое время назад, он сохраняет по историческим причинам те же команды и структуру, что и zebra. Поэтому вы увидите много ссылок на zebra с этой точки зрения.
Обратите внимание, что невозможно охватить динамическую маршрутизацию и все связанные протоколы в одной статье, но я уверен, что представленный здесь контент послужит отправной точкой для вас.
Установка Quagga в Linux
Для установки quagga на выбранном вами дистрибутиве:
# aptitude update && aptitude install quagga [On Ubuntu] # yum update && yum install quagga [CentOS/RHEL] # zypper refresh && zypper install quagga [openSUSE]
Мы будем использовать ту же среду, что и в Примере №3, с единственным отличием, что eth0 подключен к основному шлюзовому маршрутизатору с IP-адресом 192.168.0.1.
Затем отредактируйте /etc/quagga/daemons следующим образом,
zebra=1 ripd=1
Теперь создайте следующие файлы конфигурации.
# /etc/quagga/zebra.conf # /etc/quagga/ripd.conf
и добавьте эти строки (замените на имя хоста и пароль по вашему выбору):
service quagga restart hostname dev2 password quagga
# service quagga restart

Примечание: Файл ripd.conf является файлом конфигурации для Протокола маршрутизации информации, который предоставляет маршрутизатору информацию о том, какие сети могут быть достигнуты и на каком расстоянии (в терминах количества переходов) они находятся.
Обратите внимание, что это только один из протоколов, которые могут использоваться вместе с quagga, и я выбрал его для этого учебного пособия из-за его простоты использования и потому, что большинство сетевых устройств его поддерживают, хотя у него есть недостаток передачи учетных данных в виде обычного текста. По этой причине вам нужно назначить правильные разрешения для файла конфигурации:
# chown quagga:quaggavty /etc/quagga/*.conf # chmod 640 /etc/quagga/*.conf
Пример 5: Настройка quagga для динамической маршрутизации IP-трафика
В этом примере мы будем использовать следующую настройку с двумя маршрутизаторами (убедитесь, что вы создали файлы конфигурации для маршрутизатора №2, как было объяснено ранее):

Важно: Не забудьте повторить следующую настройку для обоих маршрутизаторов.
Подключитесь к zebra (слушающему на порту 2601), который является логическим посредником между маршрутизатором и ядром:
# telnet localhost 2601
Введите пароль, установленный в файле /etc/quagga/zebra.conf, а затем включите конфигурацию:
enable configure terminal
Введите IP-адрес и сетевую маску каждого сетевого интерфейса:
inter eth0 ip addr 192.168.0.15 inter eth1 ip addr 10.0.0.15 exit exit write

Теперь нам нужно подключиться к терминалу демона RIP (порт 2602):
# telnet localhost 2602
Введите имя пользователя и пароль, настроенные в файле /etc/quagga/ripd.conf, а затем введите следующие команды жирным шрифтом (комментарии добавлены для ясности):
enable turns on privileged mode command. configure terminal changes to configuration mode. This command is the first step to configuration router rip enables RIP. network 10.0.0.0/24 sets the RIP enable interface for the 10.0.0.0/24 network. exit exit write writes current configuration to configuration file.

Примечание: В обоих случаях конфигурация добавляется к строкам, которые мы ранее добавили (/etc/quagga/zebra.conf и /etc/quagga/ripd.conf).
Наконец, подключитесь снова к службе zebra на обоих маршрутизаторах и обратите внимание, как каждый из них “выучил” маршрут к сети, которая находится за другим, и какой следующий переход для доступа к этой сети, выполнив команду show ip route:
# show ip route

Если вы хотите попробовать различные протоколы или настройки, вам может потребоваться обратиться к сайту проекта Quagga для получения дополнительной документации.
Заключение
В этой статье мы объяснили, как настроить статическую и динамическую маршрутизацию, используя маршрутизатор(ы) на базе Linux. Не стесняйтесь добавлять столько маршрутизаторов, сколько захотите, и экспериментировать насколько захотите. Не стесняйтесь обращаться к нам, используя контактную форму ниже, если у вас есть какие-либо комментарии или вопросы.