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

Как пересылать пакеты, не предназначенные для хоста linux, в контейнер

Я пытаюсь выполнить некоторую проверку трафика на контейнере lxc на моем хост-компьютере. Моя хост-машина подключена к зеркальному порту, и ей отправляются дублированные копии трафика 4-5 других машин в локальной сети.

Я могу видеть весь трафик с этих других машин через wirehark, поэтому я знаю, что они достигают моего интерфейса, но у меня возникают проблемы с пересылкой их последнего перехода в мой контейнер lxc.

Я пробовал выполнять NAT через iptables, но после прочтения нескольких других сообщений подозреваю, что они фильтруются до достижения iptables. Я видел одно или два предложения по ebtables и безуспешно пытался выполнить статическую маршрутизацию.

Мы будем очень благодарны за любую помощь или указатели на существующую литературу.

Я настоятельно рекомендую вам как-нибудь инкапсулировать свой трафик. Самым простым, вероятно, является VLAN (потому что я знаю, как легко с этим справиться с tc), но, конечно, ERSPAN является стандартом де-факто. Без инкапсуляции непросто угадать, идет ли полученный трафик для вашей системы или от зеркала (как насчет широковещательных рассылок? Многоадресной рассылки? ARP?)

Поэтому я предлагаю упрощенный способ дублирования очередной раз весь ваш полученный трафик в ваши контейнеры, за исключением пакетов IPv4, имеющих ваш собственный IP (меня не будут интересовать пакеты ARP или другой менее частый трафик для вашего хоста). Если бы полученный трафик был инкапсулирован, было бы доступно больше вариантов (начиная с перенаправления, а не с зеркалирования всего), и этот ответ пришлось бы переработать.

Вы не можете ожидать, что при получении зеркального трафика будет применяться нормальная маршрутизация или даже мостовое соединение. Для этого вы можете использовать инструмент низкого уровня: Управление трафиком (tc). Это довольно сложный инструмент, способный обрабатывать различные сетевые функции, в первую очередь предназначенные для формирования трафика и т.п. Достаточно сказать, что есть действие для дублирования описанных там пакетов: tc зеркальный, что действие используется фильтр и что фильтр применяется к дисциплине классной очереди (qdisc). По мере поступления особый входить qdisc используется.

Я не буду описывать, как это автоматически интегрировать с LXC (возможно, это возможно, если указать фиксированное имя в lxc.net.[i].veth.pair для стороны, подключенной к мосту, предназначенной для LXC, вместо того, чтобы позволить LXC выбрать случайное имя и затем использовать какой-либо крючок для сценариев, если интерфейс уже создан при вызове ловушки). Поскольку имена интерфейсов должны существовать при создании tc фильтры, при этом вручную контейнеры должен начинать раньше,

Итак, давайте предположим это (отредактируйте в соответствии с вашей конфигурацией):

  • ваш уникальный реальный интерфейс называется eth0,
  • ваш "внешний" (закрепленный за eth0) IP-адрес системы - 192.0.2.2,
  • вы запустили два контейнера, и их veth стороны пары на хосте называются veth123456 и veth89ABCD. Тот факт, что они порабощены как мост-порт (например: lxcbr0) не имеет значения.

Сделаем первоначальную сантехнику:

tc qdisc add dev eth0 ingress

Давайте добавим первую копию с приоритетом фильтра (чтобы переопределить его позже) и условиями для добавления дополнительных:

tc filter add dev eth0 ingress prio 10 matchall \
   action mirred egress mirror dev veth123456 continue

Поскольку Продолжать использовался контроль, этот фильтр не окончательный. Можно добавить больше (и Продолжать можно снова добавить для еще большего количества фильтров):

tc filter add dev eth0 ingress prio 10 matchall \
   action mirred egress mirror dev veth89ABCD

Поскольку критерии одинаковы (соответствие всем), два предыдущих фильтра также можно было переписать, используя труба управление действиями с этим уникальным фильтром:

tc filter add dev eth0 ingress prio 10 matchall \
   action mirred egress mirror dev veth123456 pipe \
   action mirred egress mirror dev veth89ABCD

Теперь довольно легко вставить фильтр с более ранним приоритетом, чтобы предотвратить копирование пакетов с IP-адресом назначения (но не ARP, широковещательных, многоадресных или IPv6 ...), предназначенных для хоста (проходить делает действие окончательным):

tc filter add dev eth0 ingress prio 5 protocol ip \
   u32 match ip dst 192.0.2.2 action pass

Обратите внимание, что при этом мост (и почти весь сетевой стек) был полностью обойден: пакет был перемещен с одного интерфейса на другой, замыкая все, что между ними. Вы также можете создать дополнительный veth-интерфейс со стороной хоста, не подключенной к мосту (если LXC может это разрешить? В противном случае просто используйте фиктивный мост) и скопируйте туда пакеты, получив таким образом выделенный интерфейс в контейнере.

Чтобы отобразить фильтры со статистикой использования:

tc -statistics filter show dev eth0 ingress

Чтобы отменить все, удалив qdisc также удалит фильтры:

tc qdisc delete dev eth0 ingress

ОБНОВИТЬ: интерфейс получает трафик, не предназначенный для него, это означает, что адреса назначения кадра Ethernet, скорее всего, не являются MAC-адресом интерфейса. По умолчанию оборудование интерфейса отфильтровывает эти кадры, и система никогда не увидит их, в том числе tc, оставляя видимыми только зеркальные широковещательные сообщения (например, запросы ARP). Так что лучше переключить интерфейс в неразборчивый режим:

ip link set dev eth0 promisc on