Прохождение пакета¶
Посмотрим какой путь проходит пакет когда docker контейнер с IP-адресом 172.17.0.2 отправляет пинг на хост с IP-адресом 10.100.1.2
У контейнера есть маршрут по умолчанию (default) через адрес 172.17.0.1 на интерфейс eth0. Это означает, что любой трафик, не адресованный конкретно для локальной сети контейнера, будет направлен через этот адрес.
Ethernet-кадр отправляемый из контейнера для пинга на 10.100.1.2 и проходящий через маршрут по умолчанию, будет иметь Source MAC контейнера, Destination MAC - соответствующий MAC-адресу хоста docker с адресом 172.17.0.1(так как если у контейнера нет прямого маршрута к 10.100.1.2 и он идет через маршрут по умолчанию (172.17.0.1), то Destination MAC будет соответствовать MAC-адресу интерфейса, соответствующего адресу 172.17.0.1.)
В итоге будет сформирован Ethernet кадр с важными полями:
MAC source интерфейса(где ip #172.17.0.2)
MAC dest интерфейса(где ip #172.17.0.1)
IP-s(172.17.0.2)
IP-d(10.100.1.2)
В цепочках mangle prerouting, nat prerouting - пусто.
Далее на этапе маршрутизации, Ethernet-кадр(полученный хостом Docker) имеющий адрес назначения 10.100.1.2, он посмотрит таблицу маршрутизации и увидит там маршрут для сети 10.100.1.0\24, который мы задаем через ip route add 10.100.1.0/24 dev wg0
Учитывая правило маршрутизации 10.100.1.0/24 dev wg0 scope link
, пакет, адресованный на 10.100.1.2, будет направлен через интерфейс wg0, так как он доступен напрямую через этот интерфейс.
Пакет попадает в цепочку FORWARD(не INPUT) таблицы filter, так как IP-адрес назначения не принадлежит хосту R1, а подлежит пересылке.
Далее изменится ethernet кадр:
MAC-s интерфейса wg(где ip 10.0.1.1)
MAC-d интерфейса след роутер(где ip 10.0.1.3)
IP-s интерфейса с которого будет отправлен пакет(10.0.1.1)
IP-d(10.100.1.2)
На принимающем хосте проиcходит деинкапсуляция внешнего пакета , получение wireguard пакета с адресом назначения 10.100.1.2 и далее уже по известной схеме...
2. Перенаправление трафика на docker хосте¶
Рассмотрим вкратце как работают правила iptables в случае когда на 10.0.1.1 запущен контейнер на порту 8080 и идет обращение к docker контейнеру извне хоста.(все правила ниже docker создает сам при запуске контейнере и пробрасывании порта на хост)
Iptables правила: - prerouting nat -A PREROUTING -m addrtype --dst-type LOCAL -j DOCKER если адрес шлюза локальный, то пакет переходит в цепочку nat.DOCKER
-
далее правило dnat меняет адрес назначения nat -A DOCKER -d 10.0.1.101/32 ! -i br-d2a592a6f53a -p tcp -m tcp --dport 8080 -j DNAT --to-destination 172.18.0.2:8080
-
маршрутизация : ищется маршрут в сеть в которой может быть расположен хост 172.18.0.2 находится примерно такая сеть и через какой интерфейс туда можно обратиться и ip адрес интерфейса: 172.18.0.0/16 dev br-d2a592a6f53a proto kernel scope link src 172.18.0.1
Комментарии к iptables:
-p tcp --dport 22 - если порт указывается то обязательно должен быть и протокол -i интерфейс куда пакет пришел изначально правила выполняются последовательно, Если в пользовательской цепочке нет совпадений, то возврат автоматом в родительскую, Если в стандартной цепочке нет совпадений, то применяется то, что по умолчанию для цепочки