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

Как предотвратить подмену IP-адреса с помощью MAC и ebtables?

Я пытаюсь создать IP-MAC правила спаривания в ebtables. Доступно несколько руководств и связанных вопросов [1], но у меня есть особые настройки.

ОКРУЖАЮЩАЯ СРЕДА: у меня есть много физических хостов. У каждого хоста есть несколько карт Ethernet, связанных между собой и используемых в качестве подчиненного устройства для моста. На каждом хосте много виртуальных машин (kvm, qemu, libvirt). Каждая виртуальная машина подключена к мосту своего физического хоста через новый порт vnet [0-9] +. Нет NAT. Сеть работает нормально, можно пинговать все физические хосты, все виртуальные машины тоже. Каждая виртуальная машина имеет свой IP-адрес и MAC-адрес.

ПРОБЛЕМА: Внутри виртуальной машины IP-адрес может быть изменен на другой.

НАЙДЕНО РЕШЕНИЕ: На сайте ebtables [2] есть известное решение, но оно применимо, когда используется только один хост. Он разрешает весь трафик, и если есть пакет от IP с другим MAC, чем разрешенный, пакет отбрасывается. Если существует более одного хоста, требуется, чтобы все существующие пары IP-MAC были зарегистрированы на всех хостах. Необходимо решение обратной политики.

ПРОИЗВОДНОЕ РЕШЕНИЕ: Я пробовал использовать ebtables в перевернутом виде. Вот пример того, что я пробовал.

ПРИМЕР 1

Bridge table: filter
Bridge chain: INPUT, entries: 2, policy: DROP
-i bond0 -j ACCEPT 
-p IPv4 -s 54:52:0:98:d7:b6 --ip-src 192.168.11.122 -j ACCEPT 
Bridge chain: FORWARD, entries: 0, policy: ACCEPT
Bridge chain: OUTPUT, entries: 0, policy: ACCEPT

ПРИМЕР 2

Bridge table: filter
Bridge chain: INPUT, entries: 0, policy: ACCEPT
Bridge chain: FORWARD, entries: 1, policy: DROP
-p IPv4 -s 54:52:0:98:d7:b6 --ip-src 192.168.11.122 -j ACCEPT 
Bridge chain: OUTPUT, entries: 0, policy: ACCEPT

Я хочу иметь DROP политики по умолчанию и разрешать трафик только с виртуальных машин с правильной парой IP-MAC, развернутой на данном хосте. Однако эти решения не работают.

ВОПРОС: Как разрешить трафик на мосту только для указанных пар IP-MAC работающих виртуальных машин и отбросить все неизвестные пары IP-MAC, поступающие с портов vnet [0-9] +?

Большое спасибо за любые ответы.

Наконец-то мне удалось создать рабочее решение.

  1. Решение использует пары ebtables и IP-MAC.
  2. Единственная необходимая таблица - это таблица фильтров по умолчанию.
  3. Нет необходимости добавлять какие-либо правила или политику в цепочку INPUT, поскольку цепочка INPUT НЕ связана с запущенными виртуальными машинами. Объяснение значений цепочек INPUT, OUTPUT и FORWARD в таблице фильтров находится на странице руководства ebtables.
  4. Поскольку ebtables работает на уровне Ethernet, а связывание IP-MAC применимо только для IP-пакетов, необходимо подчеркнуть это в правилах, чтобы не блокировать кадры ARP и другой жизненно важный трафик.

Итак, вначале нет никаких правил, и все политики настроены на ACCEPT. Нет пользовательских цепочек. Таблица фильтров выглядит так:

Bridge table: filter
Bridge chain: INPUT, entries: 0, policy: ACCEPT
Bridge chain: FORWARD, entries: 0, policy: ACCEPT
Bridge chain: OUTPUT, entries: 0, policy: ACCEPT

Добавлена ​​новая цепочка. Эта цепочка содержит все разрешенные пары IP-MAC. Это называется VMS.

# ebtables -N VMS

Теперь важная часть. Для каждого кадра, содержащего IP-пакет (или его части), который проходит через мост из порта vnet [0-9] +, примените политику цепочки и правила цепочки VMS. Другими словами, для каждого IP-пакета, поступающего с любой виртуальной машины, примените цепочку VMS.

# ebtables -A FORWARD -p ip -i vnet+ -j VMS

Политика цепочки VMS по умолчанию должна быть DROP. Таким образом, каждый IP-пакет, поступающий с любой виртуальной машины, по умолчанию отбрасывается. Позже добавляются исключения для разрешенных пар IP-MAC. По умолчанию политика DROP приводит к тому, что весь трафик с любой виртуальной машины с неизвестной парой IP-MAC удаляется сразу, что делает невозможным IP-спуфинг.

# ebtables -P VMS DROP

Фильтр таблицы теперь выглядит так. Также так это выглядит, когда нет запущенных виртуальных машин (разрешено).

Bridge table: filter
Bridge chain: INPUT, entries: 0, policy: ACCEPT
Bridge chain: FORWARD, entries: 1, policy: ACCEPT
-p IPv4 -i vnet+ -j VMS
Bridge chain: OUTPUT, entries: 0, policy: ACCEPT
Bridge chain: VMS, entries: 0, policy: DROP

Допустим, есть две работающие машины. Если мы попытаемся выполнить эхо-запрос к ним или от них, трафик будет сброшен, и пункт назначения станет недоступен. Это желаемый результат, так как этот трафик еще не разрешен. Достаточно одной команды, чтобы разрешить трафик каждой виртуальной машины.

# ebtables -A VMS -p ip --ip-src 192.168.11.125 -s 54:52:00:cc:35:fa -j ACCEPT
# ebtables -A VMS -p ip --ip-src 192.168.11.122 -s 54:52:00:98:d7:b6 -j ACCEPT

Теперь трафик от разрешенных виртуальных машин проходит нормально, и спуфинг IP предотвращен.

Это решение может быть несовершенным, и если у вас есть какие-либо комментарии или улучшения, я с удовольствием их выслушаю.