Назад | Перейти на главную страницу

Перенаправлять трафик на тот же интерфейс

Я управляю сервером, на котором размещен набор служб, каждая из которых работает в отдельном контейнере 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:

  • Если они находятся в одной подсети, они смогут обращаться друг к другу напрямую через коммутатор (который будет заблокирован VEPA, как вы предложили). Хост pfSense увидит трафик, только если:
    • IP-адрес назначения трафика находится за пределами подсети контейнера, и в этом случае контейнер будет отправлять трафик на шлюз по умолчанию для маршрутизации; или
    • трафик напрямую адресован на имя хоста / IP-адрес pfSense.
  • Если вы поместите каждый контейнер в другую подсеть (или даже в отдельные виртуальные сети), то трафик между ними будет маршрутизироваться через шлюз (pfSense). Это позволит pfSense контролировать политику межсетевого экрана.
  • Если вы можете определить политику того, каким группам контейнеров разрешен прямой доступ друг к другу, было бы разумнее сгруппировать их в виртуальные / докерные сети; тогда проблема уходит. В этом случае вы согласование топологии сети с политикой безопасности. Это, как правило, легче исправить, поддерживать и другим людям легче урезонить.

Вы можете посмотреть Docker Macvlan's Режим моста магистрали 802.1q что может упростить подключение нескольких контейнерных сетей к одному интерфейсу libvirt / pfSense.

В качестве альтернативы может случиться так, что существует только очень узкий и последовательный набор способов доступа контейнеров друг к другу. В этом случае вы можете рассмотреть возможность переадресации портов. Ты бы:

  • определить конкретную контейнерную службу, которую вы хотите сделать доступной для других контейнеров
  • на pfSense перенаправить входящий трафик с определенного порта интерфейса MACVLAN на IP / порт желаемого контейнера
  • когда другим контейнерам необходим доступ к службе, они используют IP-адрес (и назначенный порт) хоста pfSense (не целевой контейнер)

В этом случае другие контейнеры ничего не знают о том, где находится целевая служба - она ​​также может размещаться непосредственно на хосте pfSense. Однако обратите внимание, что это плохо масштабируется и будет работать только для простого трафика TCP / UDP (настройка FTP может быть болезненной).

Также могут быть некоторые другие сетевые функции Docker или libvirt, которые позволят вам определить более подробную политику брандмауэра между контейнерами в виртуальной сети, хотя я сам не вдавался в подробности.