Ограничение количества MAC-адресов на порт на платформе на базе Linux

Я хочу ограничить количество MAC-адресов, разрешенных для изучения на конкретном порту. Аналогичная функциональность существует на коммутаторе L2. Например, это конфигурация на базе Cisco. Если будет достигнут максимум, пакеты с новым MAC-адресом должны быть:

  1. Не изучены в мосте Linux
  2. Отброшены.

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

Спасибо, Илья

3
задан 27 September 2020 в 14:57
1 ответ

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

Один из возможных способов сделать это — использовать nftables в семействе netdev и set с размером, равным максимальному количеству разрешенных MAC-адресов. чтобы сохранить их, и при необходимости установить тайм-аут по умолчанию для его элементов к времени старения моста.


Предварительные требования

Таблица семейства netdev требует, чтобы интерфейс (который здесь является мостовым портом) существовал заранее для создания базовой цепочки, использующей его. Таким образом, таблица должна быть загружена только после того, как такой интерфейс существует. Если это виртуальный интерфейс, таблица, вероятно, должна быть загружена сразу после ее создания, до того, как интерфейс будет запущен, или, по крайней мере, до того, как он будет установлен в качестве порта моста, чтобы предотвратить обучение.

Должны использоваться достаточно свежие версии nftables и ядра:

  • nftables 0.9.1 представило ключевое слово dynamic, представленное ниже (которое все еще может быть опущено для предыдущие версии), поэтому nftables >= 0.9.1 следует предпочесть,
  • nftables 0.8.4 представил новый синтаксис для добавления элемента из пути пакета, поэтому следует избегать nftables < 0.8.4 или переработано правило,
  • ядро 4.2 ввело поддержку семейства netdev: ядро ​​>= 4.2 является обязательным

Реализация

Если бы фильтрация выполнялась на уровне моста (он же семейство мостов), это действительно фильтрует трафик, но это не помешает мосту узнать какой-либо MAC-адрес перед лишние MAC-адреса отбрасываются фильтром, потому что перехватчики моста netfilter вызываются с моста после того, как такие кадры были обнаружены мостом (можно подтвердить, запустив bridge monitor fdb ). Можно отключить изучение всех MAC-адресов на порту моста, но не выбирать, какие из них являются, а какие нет.

Поэтому это нужно сделать до моста, чтобы он никогда не видел MAC-адрес и не имел возможности узнать его: на уровне интерфейса, используя netdev семья. netfilter в настоящее время может обрабатывать только вход в семействе netdev, но это нормально, поскольку нас интересует только фильтрация входящего трафика для этого случая: "и въезд на мост.

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

В семействе netdev базовая цепочка привязана к интерфейсу.

ОБНОВЛЕНИЕ: изменен ответ, чтобы он обрабатывал устаревание, чтобы недавний слот MAC-адреса освобождался для повторного использования через некоторое время (что лучше должно быть временем старения моста или это время плюс одна секунда). В то же время было исключено правило «быстрого пути», поскольку теперь каждый пакет все равно должен обновлять таймер для исходного MAC-адреса. Правило update ведет себя как правило add, за исключением того, что оно также сбрасывает таймер на значение времени ожидания (которое, если оно не указано в правиле, является значением по умолчанию, определенным в установить). Когда MAC-адрес не виден в течение этого времени, он автоматически удаляется из набора ядром. Для этого осталось только одно правило:

  • для любого полученного кадра обновить набор с MAC-адресом источника:
    • сбой, если набор заполнен и предпринимается попытка добавить новый MAC-адрес, поэтому оставшийся оператор accept не выполняется,
    • в противном случае добавьте новый MAC-адрес в набор или обновите его, если уже присутствует, с тайм-аутом 30 с, и выполнить оператор accept
  • удалить все оставшееся (политика по умолчанию).

Набор правил

В этом примере набора правил, который можно загрузить с помощью nft -f portsecmax.nft,

  • интерфейс порта моста называется swp1 (это могло быть eth0 или ens224 и т. д.), и базовая цепочка была выбрана с тем же именем,

  • размер набора, используемого для запоминания MAC-адресов, устанавливается равным максимально допустимому количеству MAC-адресов: 3 в этом примере,

  • тайм-аут по умолчанию для элементов набора выбрано значение 30 с, которое является значением по умолчанию aging_time на мосту Linux, если оно не изменено. Если вариант использования состоит в том, чтобы навсегда сохранить первый размер (здесь 3) видимых MAC-адреса, просто удалите время ожидания 30 с ниже.

portsecmax.nft:

table netdev portsecmax        # for idempotency
delete table netdev portsecmax # for idempotency

table netdev portsecmax {
    set macswp1 {
        type ether_addr
        size 3
        flags dynamic,timeout
        timeout 30s
    }

    chain swp1 {
        type filter hook ingress device "swp1" priority filter; policy drop;
        update @macswp1 { ether saddr } accept comment "false if set is full and adding a new element"
    }
}

Сброс списка разрешенных MAC-адресов:

nft flush set netdev portsecmax macswp1

Отключение функции (выберите один из трех вариантов): удалите таблицу или удалите цепочку или измените политику цепочки по умолчанию на accept:

nft delete table netdev portsecmax
nft delete chain netdev portsecmax swp1
nft add chain netdev portsecmax swp1 '{ policy accept; }'
1
ответ дан 27 September 2020 в 21:38

Теги

Похожие вопросы