Лабораторная работа 4. Маршрутизация, NAT и firewall

Цель

Вы проследите путь IPv4-пакета и разберётесь, как работают трансляция адресов и фильтрация трафика.

Задачи

  1. Настройте прямые и обратные статические маршруты.
  2. Найдите причину отказа при отсутствии обратного маршрута.
  3. Проверьте SNAT и DNAT внутри учебной сети.
  4. Разрешите HTTP и запретите соединения с выбранным портом.
  5. Сопоставьте результат с захватом пакетов и счётчиками правил.

Рабочее окружение

Вам понадобятся знания из ЛБ0–3 и подготовленная ВМ. Укажите в отчёте, сколько времени заняла работа. На ВМ:

cd ~/labs-mag/containerlab/lab4
sudo containerlab deploy -t lab4.clab.yml
sudo containerlab inspect -t lab4.clab.yml

Вход в узел: sudo docker exec -it clab-labs4-r1 bash, где r1 замените именем нужного узла. Все дальнейшие команды выполняйте в контейнерах, кроме сохранения файлов и удаления стенда. В контейнере sudo не нужен. eth0 — управление; его адреса не используйте для проверок.

client:eth1 ─ eth1:r1:eth2 ─ eth1:r2:eth2 ─ eth1:server
  LAN A                    транзит               LAN B
Узелeth1eth2
client10.4.1.10/24—
r110.4.1.1/2410.4.12.1/30
r210.4.12.2/3010.4.2.1/24
server10.4.2.10/24—

Начальные сценарии убирают маршрут по умолчанию через management. Связность проверяется только через учебные интерфейсы, управление через docker exec сохраняется.

Задание 1. Адреса и маршруты

1. На каждом узле назначьте адреса из таблицы и поднимите используемые интерфейсы. Пример для r1:

ip address add 10.4.1.1/24 dev eth1
ip address add 10.4.12.1/30 dev eth2
ip link set eth1 up
ip link set eth2 up
sysctl -w net.ipv4.ip_forward=1

На r2 также включите forwarding. На клиентах forwarding не нужен.

2. Добавьте маршруты. На client:

ip route add 10.4.2.0/24 via 10.4.1.1
ip route add 10.4.12.0/30 via 10.4.1.1

На r1: ip route add 10.4.2.0/24 via 10.4.12.2. На r2: ip route add 10.4.1.0/24 via 10.4.12.1. На server: ip route add 10.4.1.0/24 via 10.4.2.1.

3. На server запустите сервисы, привязанные к учебному адресу:

mkdir -p /tmp/www
printf 'lab4 server\n' > /tmp/www/index.html
python3 -m http.server 80 --bind 10.4.2.10 --directory /tmp/www >/tmp/http.log 2>&1 &
python3 -m http.server 8000 --bind 10.4.2.10 --directory /tmp/www >/tmp/admin.log 2>&1 &

На client:

ip route get 10.4.2.10
ping -c 4 10.4.2.10
tracepath -n 10.4.2.10
curl -f --max-time 5 http://10.4.2.10/
curl -f --max-time 5 http://10.4.2.10:8000/

Порт 8000 моделирует административный сервис; до фильтрации он доступен.

Задание 2. Отсутствие обратного пути

1. На r2 удалите только маршрут в LAN A:

ip route del 10.4.1.0/24 via 10.4.12.1
ip route get 10.4.1.10

На r2 откройте tcpdump -ni eth1 icmp, с клиента повторите ping сервера. Сравните входящие запросы и ответы. Почему наличия прямого пути недостаточно?

2. Верните маршрут на r2, повторите ping. Это исходное состояние для NAT.

Задание 3. SNAT

1. На r1 создайте отдельную таблицу. Вводите блок целиком:

nft -f - <<'NFT'
table ip lab4_nat {
  chain postrouting {
    type nat hook postrouting priority srcnat; policy accept;
    ip saddr 10.4.1.0/24 ip daddr 10.4.2.0/24 oifname "eth2" counter snat to 10.4.12.1
  }
}
NFT

2. На server добавьте обратный маршрут для нового адреса источника:

ip route add 10.4.12.0/30 via 10.4.2.1

На r1 в двух терминалах запустите:

tcpdump -i eth1 -w /tmp/lab4-before.pcap 'tcp port 80'
tcpdump -i eth2 -w /tmp/lab4-after.pcap 'tcp port 80'

С клиента выполните новый HTTP-запрос. Остановите оба захвата Ctrl+C, прочитайте tcpdump -nn -r /tmp/lab4-after.pcap. На r1:

nft list table ip lab4_nat
conntrack -L -p tcp

Сопоставьте исходный адрес клиента на eth1 и адрес 10.4.12.1 на eth2. NAT-цепочка обрабатывает первый пакет соединения; счётчик NAT не обязан равняться количеству всех пакетов.

Задание 4. DNAT

На r1 добавьте правило перенаправления адреса 10.4.12.1:8080 на сервер:

nft -f - <<'NFT'
add chain ip lab4_nat prerouting { type nat hook prerouting priority dstnat; policy accept; }
add rule ip lab4_nat prerouting iifname "eth1" ip daddr 10.4.12.1 tcp dport 8080 counter dnat to 10.4.2.10:80
NFT

С client выполните запрос curl -f http://10.4.12.1:8080/. Сравните адрес назначения до и после r1. Оба адреса находятся внутри ВМ; публичный IP и порт на основной ОС для DNAT не требуются.

Задание 5. Политика доступа

1. На r1 разрешите ответы, HTTP к серверу и ICMP, остальное из LAN A в LAN B запретите. Правила относятся только к транзиту учебных интерфейсов:

nft -f - <<'NFT'
table inet lab4_filter {
  chain forward {
    type filter hook forward priority filter; policy accept;
    ct state established,related counter accept
    iifname "eth1" oifname "eth2" ip daddr 10.4.2.10 tcp dport 80 counter accept
    iifname "eth1" oifname "eth2" ip daddr 10.4.2.0/24 ip protocol icmp counter accept
    iifname "eth1" oifname "eth2" ip daddr 10.4.2.0/24 counter drop
  }
}
NFT

2. С client отправьте новые запросы к портам 80, 8080 на r1 и 8000 на server. Первые два должны проходить, последний — завершаться по тайм-ауту. Для отказа: curl --max-time 5 http://10.4.2.10:8000/ (введите в одну строку). На r1 посмотрите nft -a list table inet lab4_filter и изменение счётчика drop. Проверьте на server через ss -lnt, что сервис по-прежнему слушает порт 8000.

3. Теперь создайте неисправность: через nft -a найдите handle разрешающего HTTP правила и удалите его командой nft delete rule inet lab4_filter forward handle НОМЕР. Проверьте отказ нового HTTP-соединения и рост счётчика запрета. Восстановите правило перед drop через nft insert rule с теми же условиями и повторите проверку. Не используйте flush ruleset на ВМ.

Самостоятельное задание и отчёт

Разрешите порт 8000 только клиенту 10.4.1.10, затем запретите его повторно. До изменения запишите место правила и ожидаемые счётчики. Приложите таблицу адресов, маршруты, оба PCAP, conntrack и проверки разрешённого/запрещённого запросов. Ответьте:

  1. Почему обратный маршрут нужен до SNAT и после него?
  2. Чем DNAT отличается от публикации порта контейнера?
  3. Почему фильтр видит порт 80 после DNAT с 8080?
  4. Как conntrack связывает запрос и ответ?

Сохранение и завершение

На ВМ сохраните свои команды в configs/*/startup.sh. На r1 сохраните nft list ruleset > /tmp/lab4.nft, скопируйте файл в configs/r1/rules.nft; в конце его startup добавьте nft -f /opt/lab/rules.nft. Добавьте запуск HTTP-сервисов в сценарий server. Частные адреса управления в сценарии не сохраняйте. Скопируйте PCAP и журналы через docker cp в отчёт.

Пересоздайте стенд и выполните на ВМ sudo bash verify.sh:

sudo containerlab destroy -t lab4.clab.yml --cleanup
sudo containerlab deploy -t lab4.clab.yml
sudo bash verify.sh
sudo containerlab destroy -t lab4.clab.yml --cleanup

Файлы configs/ останутся. Для полного повтора восстановите их начальное содержимое из отдельной чистой копии репозитория.