Я управляю сервером, на котором размещен набор служб, каждая из которых работает в отдельном контейнере Docker. Кроме того, есть KVM, на котором запущен pfSense, который действует как межсетевой экран. Брандмауэр имеет физический интерфейс, который подключен к внешней сети, и виртуальную сетевую карту, которая подключена к внутренней сети контейнера, используя MACVLAN на стороне Docker, поэтому каждый контейнер имеет свой собственный IP-адрес, но все они находятся в одном подсеть.
По соображениям безопасности контейнеры должны быть изолированы и не должны иметь принципиальную возможность связываться друг с другом (только с внешней сетью). Для этого MACVLAN настроен в режиме VEPA, который разрешает трафик от и к родительскому устройству, но не к другим адресам на том же родительском устройстве.
Теперь я хотел бы разрешить определенный трафик между конкретными контейнерами, поэтому pfSense должен направлять трафик на тот же интерфейс, на котором он получал трафик, с учетом настроенных правил брандмауэра (читайте, если входящий трафик на внутреннем интерфейсе соответствует правилу PASS, он должен быть перенаправлено на хост в том же интерфейсе / в той же подсети).
Я не могу заставить этот сценарий работать (нет трафика между хостами на внутреннем интерфейсе, трафик из и во внешнюю сеть работает должным образом). Есть идеи, как действовать дальше?
Есть ли какой-либо элемент конфигурации во FreeBSD в целом или в pfSense, в частности, чтобы предотвратить такие сценарии, такие как «фильтрация трафика на собственном интерфейсе» или «на практике этого не должно происходить, потому что трафик перенаправляется на коммутатор перед маршрутизатором, потому что он такой же подсеть так что нечего с ней делать "?
Интересно, что pfSense даже не отвечает на запрос ARP (который может иметь ту же причину):
[root@server ~]# ip r
default via 10.0.20.1 dev server proto static metric 410
10.0.20.0/24 dev server proto kernel scope link src 10.0.20.2 metric 410
21:52:49.651286 ARP, Request who-has 10.0.20.4 tell 10.0.20.2, length 28
21:52:50.673895 ARP, Request who-has 10.0.20.4 tell 10.0.20.2, length 28
21:52:51.697860 ARP, Request who-has 10.0.20.4 tell 10.0.20.2, length 28
21:52:52.721992 ARP, Request who-has 10.0.20.4 tell 10.0.20.2, length 28
Я предполагаю ответ с MAC интерфейса 10.0.20.0/24. Трассировка была сделана на брандмауэре на этом интерфейсе (PING от брандмауэра до 10.0.20.4 работает должным образом).
При добавлении записи вручную я вижу эхо-запрос ICMP, но нет ответа:
[root@server ~]# arp -s 10.0.20.4 02:42:0a:00:14:04
10.0.20.4 ether 02:42:0a:00:14:04 CM server
22:00:21.403515 IP 10.0.20.2 > 10.0.20.4: ICMP echo request, id 5622, seq 1, length 64
22:00:22.450162 IP 10.0.20.2 > 10.0.20.4: ICMP echo request, id 5622, seq 2, length 64
22:00:23.473790 IP 10.0.20.2 > 10.0.20.4: ICMP echo request, id 5622, seq 3, length 64
22:00:24.497803 IP 10.0.20.2 > 10.0.20.4: ICMP echo request, id 5622, seq 4, length 64
Частично это зависит от того, как вы намереваетесь, чтобы один контейнер ссылался на другой. Стоит подумать, подходит ли эта топология сети для вашего варианта использования и политики безопасности.
Если вы хотите, чтобы контейнер A обращался к контейнеру B напрямую по имени хоста или IP-адресу, это должно соответствовать коммутации уровня 2 и маршрутизации уровня 3:
Вы можете посмотреть Docker Macvlan's Режим моста магистрали 802.1q что может упростить подключение нескольких контейнерных сетей к одному интерфейсу libvirt / pfSense.
В качестве альтернативы может случиться так, что существует только очень узкий и последовательный набор способов доступа контейнеров друг к другу. В этом случае вы можете рассмотреть возможность переадресации портов. Ты бы:
В этом случае другие контейнеры ничего не знают о том, где находится целевая служба - она также может размещаться непосредственно на хосте pfSense. Однако обратите внимание, что это плохо масштабируется и будет работать только для простого трафика TCP / UDP (настройка FTP может быть болезненной).
Также могут быть некоторые другие сетевые функции Docker или libvirt, которые позволят вам определить более подробную политику брандмауэра между контейнерами в виртуальной сети, хотя я сам не вдавался в подробности.