Я бегаюдва контейнера Docker на одном хостеживу в Docker той же сети мостов, и у меня настроены nftables для ограничения более или менее всего трафика (правила ниже).
Моя единственная проблема (о которой я знаю) заключается в том, чтодвижение из одного контейнера в другой заблокировано, если контейнер используетпубличный URL-адрес сервиса, предоставляемого другим контейнером.
Например, служба A — это SMTP-сервер, имеющий публичную запись DNS mail.acme.com
, а служба B — это приложение, которое хочет отправлять почту на веб-сервер.используя этот URLSMTP-сервер настроен так, чтобы он был доступен извне (т. е. переадресация портов, как 0.0.0.0:25:25
в Docker Compose).
В этом конкретном случае входной интерфейс в nftables — это не мой внешний интерфейс, а интерфейс сети Docker, в которой находится контейнер. Трафик не маршрутизируется FORWARD
, правила, добавленные Docker, не применяются, и трафик попадает туда, INPUT
где он и отбрасывается.
Я не хочу настраивать отдельные правила, разрешающие трафик с интерфейсов Docker на разрешенные порты.
Я ищу решение, которое позволяет службам использовать соответствующие URL-адреса и которое не зависит от портов и интерфейсов, используемых в настройке Docker. Возможно ли это вообще с помощью одного nftables?
Единственное, что я придумал на данный момент, это перейти от INPUT
к FORWARD
, если интерфейс ввода не является внешним интерфейсом, но мне кажется, что этого делать не стоит.
Вот мои INPUT
правила:
chain INPUT {
type filter hook input priority filter; policy drop;
ct state vmap { invalid : drop, established : accept, related : accept }
iifname "lo" accept
iifname "externalif0" icmp type echo-request accept
iifname "externalif0" icmpv6 type echo-request accept
}
Вот что происходит, когда контейнер пытается достичь другого контейнера.на том же хосте: (Я обрезал часть выходных данных трассировки, которая показалась мне не слишком важной)
trace id 196c1ae6 ip filter trace_chain packet: iif "dockerbr0" ip saddr <containerip> ip daddr <public host ip> tcp sport 33546 tcp dport 443
trace id 196c1ae6 ip nat PREROUTING packet: iif "dockerbr0" ip saddr <containerip> ip daddr <public host ip> tcp sport 33546 tcp dport 443
trace id e7c2ca4b ip filter INPUT packet: iif "dockerbr0" ip saddr <containerip> ip daddr <public host ip> tcp sport 33546 tcp dport 443
И вотвнешний трафикна ту же услугу:
trace id 29f9da6c ip filter trace_chain packet: iif "externalif0" ip saddr <someip> ip daddr <public host ip> sport 36382 tcp dport 443
trace id 29f9da6c ip nat PREROUTING packet: iif "externalif0" ip saddr <someip> ip daddr <public host ip> sport 36382 tcp dport 443
trace id 29f9da6c ip nat DOCKER rule iifname != "dockerbr0" dport 443 dnat to <dockerip>:443 (verdict accept)
trace id 29f9da6c ip filter FORWARD packet: iif "externalif0" oif "dockerbr0" ip saddr <someip> daddr <containerip> sport 36382 tcp dport 443
trace id 29f9da6c ip filter DOCKER rule iifname != "dockerbr0" oifname "dockerbr0" daddr <containerip> tcp dport 443 accept (verdict accept)
trace id 29f9da6c ip nat POSTROUTING packet: iif "externalif0" oif "dockerbr0" ip saddr <someip> ip daddr <containerip> sport 36382 tcp dport 443
Также на хосте:
iptables-legacy -S
-P INPUT ACCEPT
-P FORWARD ACCEPT
-P OUTPUT ACCEPT