Вышла CentOS 8, nftables все еще нельзя использовать?

Linux

Оригинальная ссылка:Вышла CentOS 8, nftables все еще нельзя использовать?

Если вы не живете в прошлом веке и занимаетесь облачными вычислениями или смежной областью, то вы должны были слышать, что недавно была выпущена официальная версия CentOS 8,CentOSполное соответствиеRed Hat, и стремится быть полностью функционально совместимым с вышестоящими продуктами. Основные изменения CentOS 8 такие же, как и в RedHat Enterprise Linux 8, основанные на Fedora 28 и версии ядра.4.18, основные изменения в сети заключаются в использованииnftablesальтернатива кадраiptablesFramework в качестве инструмента фильтрации сетевых пакетов по умолчанию. **Если вы еще не слышали о nftables, сейчас самое время узнать об этом.

nftables — этоnetfilterПроект, направленный на замену существующей структуры таблиц {ip,ip6,arp,eb}, предоставляя новую структуру фильтрации пакетов, новую утилиту пользовательского пространства (nft) и уровень совместимости для таблиц {ip,ip6}. Он использует существующие хуки, системы отслеживания ссылок, компоненты очередей пользовательского пространства иnetfilterподсистема регистрации.

nftables в основном состоит из трех компонентов: реализация ядра, связь libnl netlink и пользовательское пространство nftables. где ядро ​​предоставляетnetlinkинтерфейс конфигурации и оценка набора правил во время выполнения,libnlСодержит основные функции для связи с ядром, может проходить пространство пользователяnftвзаимодействовать с пользователями.

В этой статье в основном представлены инструменты командной строки пользовательского пространства.nftиспользование.

1. nftables VS iptables

Как и iptables, nftables состоит из таблиц, цепочек и правил.Таблицы содержат цепочки, цепочки содержат правила, а правила — это реальные действия. По сравнению с iptables, nftables в основном имеет следующие изменения:

  • iptablesОбычная компоновка основана на непрерывных больших блоках памяти, то есть компоновке массива; иnftablesВ правилах используется цепочка макетов. На самом деле это разница между массивом и связанным списком, как будто пользователи Kubernetes должны быть в восторге от этого?
  • iptablesБольшая часть работы выполняется в режиме ядра, если вы хотите добавить новые функции, вы можете только перекомпилировать ядро;nftablesБольшая часть работы выполняется в пользовательском режиме, и легко добавлять новые функции без изменения ядра.
  • iptablesЕсть встроенные цепочки, и даже если вам нужна только одна цепочка, остальные последуют за ней; иnftablesВстроенной цепочки нет, можно зарегистрироваться по запросу. так какiptablesИмеется встроенный счетчик пакетов, поэтому даже если эти встроенные цепочки пусты, производительность снижается.
  • имитироватьIPv4/IPv6Двойное управление стеком
  • Встроенная поддержка коллекций, словарей и карт

Вернемся к nftables, давайте посмотрим, каков набор правил по умолчанию:

$ nft list ruleset

Ничего, толком никакой встроенной цепочки (если замкнутьfirewalldСлужить).

2. Создайте таблицу

Каждая таблица nftables имеет только один кластер адресов и применяется только к пакетам этого кластера. В таблице может быть указан один из пяти кластеров:

кластер nftables инструмент командной строки iptables
ip iptables
ip6 ip6tables
inet iptables и ip6tables
arp arptables
bridge ebtables

inetПрименяется как к пакетам IPv4, так и к пакетам IPv6, т.е.ipиip6Кластеры упрощают определение правил, и в приведенных ниже примерах будут использоваться кластеры inet.

Сначала создайте новую таблицу:

$ nft add table inet my_table

Перечислите все правила:

$ nft list ruleset
table inet my_table {
}

В таблице еще нет правил, и необходимо создать цепочку для хранения правил.

3. Создайте цепочку

Цепочки используются для хранения правил, и, как и таблицы, их также необходимо явно создавать, поскольку в nftables нет встроенной цепочки. Цепи бывают двух видов:

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

Создайте обычную цепочку:

$ nft add chain inet my_table my_utility_chain

Создайте основную цепочку:

$ nft add chain inet my_table my_filter_chain { type filter hook input priority 0 \; }
  • обратная косая черта (\) для экранирования, чтобы оболочка не интерпретировала точку с запятой как конец команды.
  • priorityПринимает целочисленное значение, которое может быть отрицательным, и цепочка с меньшим значением имеет приоритет.

Перечислите все правила в цепочке:

$ nft list chain inet my_table my_utility_chain
table inet my_table {
        chain my_utility_chain {
        }
}

$ nft list chain inet my_table my_filter_chain
table inet my_table {
        chain my_filter_chain {
                type filter hook input priority 0; policy accept;
        }
}

4. Создайте правила

Когда у вас есть таблица и цепочка, вы можете создавать правила, состоящие из операторов или выражений, содержащихся в цепочках. Добавьте правило ниже, чтобы разрешить вход по SSH:

$ nft add rule inet my_table my_filter_chain tcp dport ssh accept

addозначает добавить правило в конец цепочки, если вы хотите добавить правило в начало цепочки, вы можете использоватьinsert.

$ nft insert rule inet my_table my_filter_chain tcp dport http accept

Перечислите все правила:

$ nft list ruleset
table inet my_table {
        chain my_filter_chain {
                type filter hook input priority 0; policy accept;
                tcp dport http accept
                tcp dport ssh accept
        }
}

Обратите внимание, что правило HTTP поступает перед правилом SSH, потому что он использовалinsert.

Правила также можно вставлять в указанные позиции в цепочке двумя способами:

1. Используйтеindexуказать индекс правила.addУказывает, что новое правило добавляется после правила в позицию индекса,inserУказывает, что новое правило добавляется перед правилом в позиции индекса. Значение индекса увеличивается с 0.

$ nft insert rule inet my_table my_filter_chain index 1 tcp dport nfs accept
$ nft list ruleset
table inet my_table {
     chain my_filter_chain {
             type filter hook input priority 0; policy accept;
             tcp dport http accept
             tcp dport nfs accept
             tcp dport ssh accept
     }
}

$ nft add rule inet my_table my_filter_chain index 0 tcp dport 1234 accept
$ nft list ruleset
table inet my_table {
     chain my_filter_chain {
             type filter hook input priority 0; policy accept;
             tcp dport http accept
             tcp dport 1234 accept
             tcp dport nfs accept
             tcp dport ssh accept
     }
}

indexпохоже на iptables-Iвариант, но следует отметить два момента: во-первых, значение индекса начинается с 0, во-вторых, индекс должен указывать на существующее правило, напримерnft insert rule … index 0является незаконным.

2. Используйтеhandleчтобы указать дескриптор правила.addУказывает, что новое правило добавляется после правила в позицию индекса,inserУказывает, что новое правило добавляется перед правилом в позиции индекса.handleЗначение может быть передано через параметр--handleПолучать.

$ nft --handle list ruleset
table inet my_table { # handle 10
     chain my_filter_chain { # handle 2
             type filter hook input priority 0; policy accept;
             tcp dport http accept # handle 4
             tcp dport 1234 accept # handle 6
             tcp dport nfs accept # handle 5
             tcp dport ssh accept # handle 3
     }
}

$ nft add rule inet my_table my_filter_chain handle 4 tcp dport 1234 accept
$ nft insert rule inet my_table my_filter_chain handle 5 tcp dport nfs accept
$ nft --handle list ruleset
table inet my_table { # handle 10
     chain my_filter_chain { # handle 2
             type filter hook input priority 0; policy accept;
             tcp dport http accept # handle 4
             tcp dport 2345 accept # handle 8
             tcp dport 1234 accept # handle 6
             tcp dport 3456 accept # handle 9
             tcp dport nfs accept # handle 5
             tcp dport ssh accept # handle 3
     }
}

В nftables значение дескриптора является фиксированным, если правило не удалено, что обеспечивает стабильный индекс для правила. иindexЗначение является изменяемым и может изменяться всякий раз, когда вставляется новое правило. Обычно рекомендуетсяhandleчтобы вставить новое правило.

Вы также можете получить значение дескриптора правила при создании правила, вам нужно только добавить параметры при создании правила.--echoи--handle.

$ nft --echo --handle add rule inet my_table my_filter_chain udp dport 3333 accept
add rule inet my_table my_filter_chain udp dport 3333 accept # handle 10

5. Удалить правила

Одно правило можно удалить только по его дескриптору, сначала вам нужно найти дескриптор правила, которое вы хотите удалить:

$ nft --handle list ruleset
table inet my_table { # handle 10
        chain my_filter_chain { # handle 2
                type filter hook input priority 0; policy accept;
                tcp dport http accept # handle 4
                tcp dport 2345 accept # handle 8
                tcp dport 1234 accept # handle 6
                tcp dport 3456 accept # handle 9
                tcp dport nfs accept # handle 5
                tcp dport ssh accept # handle 3
                udp dport 3333 accept # handle 10
        }
}

Затем используйте значение дескриптора, чтобы удалить правило:

$ nft delete rule inet my_table my_filter_chain handle 8
$ nft --handle list ruleset
table inet my_table { # handle 10
        chain my_filter_chain { # handle 2
                type filter hook input priority 0; policy accept;
                tcp dport http accept # handle 4
                tcp dport 1234 accept # handle 6
                tcp dport 3456 accept # handle 9
                tcp dport nfs accept # handle 5
                tcp dport ssh accept # handle 3
                udp dport 3333 accept # handle 10
        }
}

6. Перечислите правила

В предыдущем примере перечислены все правила, мы также можем перечислить часть правил в соответствии с нашими потребностями. Например:

Запишите все правила в таблицу:

$ nft list table inet my_table
table inet my_table {
        chain my_filter_chain {
                type filter hook input priority 0; policy accept;
                tcp dport http accept
                tcp dport 1234 accept
                tcp dport 3456 accept
                tcp dport nfs accept
                tcp dport ssh accept
                udp dport 3333 accept
        }
}

Список всех правил в цепочке:

$ nft list chain inet my_table my_other_chain
table inet my_table {
    chain my_other_chain {
        udp dport 12345 log prefix "UDP-12345"
    }
}

7. Коллекция

nftablesСинтаксис изначально поддерживает коллекции, которые можно использовать для сопоставления нескольких IP-адресов, номеров портов, сетевых карт или любых других критериев.

анонимная коллекция

Коллекция делится наанонимная коллекцияиименованная коллекция, анонимные коллекции больше подходят для правил, которые не нужно менять в дальнейшем.

Например, следующее правило разрешает трафик с исходного IP-адреса в10.10.10.123 ~ 10.10.10.231Трафик хостов в этом интервале.

$ nft add rule inet my_table my_filter_chain ip saddr { 10.10.10.123, 10.10.10.231 } accept
$ nft list ruleset
table inet my_table {
        chain my_filter_chain {
                type filter hook input priority 0; policy accept;
                tcp dport http accept
                tcp dport nfs accept
                tcp dport ssh accept
                ip saddr { 10.10.10.123, 10.10.10.231 } accept
        }
}

Недостатком анонимных коллекций является то, что если коллекцию нужно изменить, правила должны быть заменены. Если впоследствии коллекцию необходимо будет часто изменять, рекомендуется использовать именованную коллекцию.

Правила, добавленные в предыдущем примере, также можно упростить с помощью коллекций:

$ nft add rule inet my_table my_filter_chain tcp dport { http, nfs, ssh } accept

iptables может использоватьipsetдля использования коллекций, а nftables изначально поддерживает коллекции, так что нет необходимости прибегать кipset.

именованная коллекция

nftables также поддерживает именованные коллекции, которые можно изменять. Для создания коллекции необходимо указать тип ее элементов.В настоящее время поддерживаются следующие типы данных:

  • ipv4_addr: IPv4-адрес
  • ipv6_addr: IPv6-адрес
  • ether_addr: Ethernet-адрес
  • inet_proto: Сетевой протокол
  • inet_service: Интернет служба
  • mark: тип тега

Сначала создайте пустую именованную коллекцию:

$ nft add set inet my_table my_set { type ipv4_addr \; }
$ nft list sets
table inet my_table {
        set my_set {
                type ipv4_addr
        }
}

Чтобы сослаться на коллекцию при добавлении правила, используйте@Символ следует за названием коллекции. Следующие правила указывают, что коллекция будетmy_setДобавьте IP-адреса в черный список.

$ nft insert rule inet my_table my_filter_chain ip saddr @my_set drop
$ nft list chain inet my_table my_filter_chain
table inet my_table {
        chain my_filter_chain {
                type filter hook input priority 0; policy accept;
                ip saddr @my_set drop
                tcp dport http accept
                tcp dport nfs accept
                tcp dport ssh accept
                ip saddr { 10.10.10.123, 10.10.10.231 } accept
        }
}

Добавьте элементы в коллекцию:

$ nft add element inet my_table my_set { 10.10.10.22, 10.10.10.33 }
$ nft list set inet my_table my_set
table inet my_table {
        set my_set {
                type ipv4_addr
                elements = { 10.10.10.22, 10.10.10.33 }
        }
}

Если вы добавите диапазон в коллекцию, вы получите сообщение об ошибке:

$ nft add element inet my_table my_set { 10.20.20.0-10.20.20.255 }

Error: Set member cannot be range, missing interval flag on declaration
add element inet my_table my_set { 10.20.20.0-10.20.20.255 }
                                   ^^^^^^^^^^^^^^^^^^^^^^^

Для использования интервала в коллекции нужно добавить флагinterval, потому что ядро ​​должно заранее подтвердить, какой тип данных хранится в коллекции, чтобы принять соответствующую структуру данных.

интервал поддержки

Создайте именованную коллекцию, которая поддерживает диапазоны:

$ nft add set inet my_table my_range_set { type ipv4_addr \; flags interval
$ nft add element inet my_table my_range_set { 10.20.20.0/24 }
$ nft list set inet my_table my_range_set
table inet my_table {
        set my_range_set {
                type ipv4_addr
                flags interval
                elements = { 10.20.20.0/24 }
        }
}

Обозначение маски подсети неявно преобразуется в диапазон IP-адресов, вы также можете использовать этот диапазон напрямую.10.20.20.0-10.20.20.255для получения того же эффекта.

Каскадирование разных типов

Именованный набор также поддерживает различные типы каскадных элементов, каскад оператором.разделять. Например, следующее правило одновременно сопоставляет IP-адреса, протоколы и номера портов.

$ nft add set inet my_table my_concat_set  { type ipv4_addr . inet_proto . inet_service \; }

$ nft list set inet my_table my_concat_set
table inet my_table {
        set my_concat_set {
                type ipv4_addr . inet_proto . inet_service
        }
}

Добавьте элементы в коллекцию:

$ nft add element inet my_table my_concat_set { 10.30.30.30 . tcp . telnet }

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

$ nft add rule inet my_table my_filter_chain ip saddr . meta l4proto . tcp dport @my_concat_set accept

Это означает, что если исходный IP-адрес, тип протокола и порт назначения пакета совпадают10.30.30.30、tcp、telnet, nftables пропустит пакет.

Анонимные коллекции также могут использовать каскадные элементы, например:

$ nft add rule inet my_table my_filter_chain ip saddr . meta l4proto . udp dport { 10.30.30.30 . udp . bootps } accept

Теперь вы сможете оценить всю мощь коллекции nftables в баре.

Коллекции типов каскадов NFTable аналогичны совокупным типам IPSet, например,hash:ip,port.

8. Словарь

Словарь — это расширенная функция nftables, она может использовать различные типы данных и сопоставлять условия сопоставления с правилом, а поскольку это хеш-карта, она может полностью избежать накладных расходов на переходы по цепочке правил.

Например, чтобы логически разделить правила обработки для пакетов TCP и UDP, можно использовать словарь для достижения вышеуказанных требований.

$ nft add chain inet my_table my_tcp_chain
$ nft add chain inet my_table my_udp_chain
$ nft add rule inet my_table my_filter_chain meta l4proto vmap { tcp : jump my_tcp_chain, udp : jump my_udp_chain }
$ nft list chain inet my_table my_filter_chain
table inet my_table {
    chain my_filter_chain {
    ...
    meta nfproto ipv4 ip saddr . meta l4proto . udp dport { 10.30.30.30 . udp . bootps } accept
    meta l4proto vmap { tcp : jump my_tcp_chain, udp : jump my_udp_chain }
    }
}

Как и в случае с наборами, в дополнение к анонимным словарям также могут быть созданы именованные словари:

$ nft add map inet my_table my_vmap { type inet_proto : verdict \; }

Добавьте элементы в словарь:

$ nft add element inet my_table my_vmap { 192.168.0.10 : drop, 192.168.0.11 : accept }

Затем на элементы словаря можно ссылаться в правилах:

$ nft add rule inet my_table my_filter_chain ip saddr vmap @my_vmap

9. Таблицы и пространства имен

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

$ nft add table inet table_one
$ nft add chain inet table_one my_chain
$ nft add table inet table_two
$ nft add chain inet table_two my_chain
$ nft list ruleset
...
table inet table_one {
    chain my_chain {
    }
}
table inet table_two {
    chain my_chain {
    }
}

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

Конечно, эта функция также несовершенна: поскольку каждая таблица рассматривается как независимый брандмауэр, определенный пакет данных должен быть выпущен по правилам во всех таблицах, чтобы быть действительно освобожденным, даже еслиtable_oneпозволить пакету пройти, пакет все еще может бытьtable_twoМусор. Чтобы решить эту проблему, Nftables представляет приоритет,priorityЦепочки с более высокими значениями имеют более низкий приоритет, поэтомуpriorityнизкий коэффициент цепиpriorityЦепочки с более высокими значениями выполняются первыми. Если две цепочки имеют одинаковый приоритет, возникает состояние гонки.

10. Резервное копирование и восстановление

Правила во всех приведенных выше примерах являются временными. Чтобы они вступили в силу навсегда, мы можем сделать резервную копию правил и автоматически загрузить и восстановить их после перезапуска.systemdТак работают службы.

Правила резервного копирования:

$ nft list ruleset > /root/nftables.conf

Восстановление нагрузки:

$ nft -f /root/nftables.conf

В CentOS 8,nftables.serviceПравила хранятся в/etc/nftables.conf, которые включают в себя некоторые другие примеры правил, обычно расположенные в/etc/sysconfig/nftables.confфайл, но по умолчанию закомментирован.

11. Резюме

Я надеюсь, что благодаря объяснению этой статьи вы можете понять функции и использование Nftables. Конечно, эта статья охватывает только некоторые простые использования. Для более продвинутых использований вы можете проверить официальные NFTABLE.wiki, или ждите моей следующей статьи. Я считаю, что с запасом знаний из этой статьи вы сможете с удовольствием использовать nftables для реализации интеллектуального распространения Linux, пожалуйста, обратитесь к этой статье за ​​подробностями:Глобальное интеллектуальное решение для распространения Linux.

Публичный аккаунт WeChat

Отсканируйте приведенный ниже QR-код, чтобы подписаться на официальный аккаунт WeChat, ответьте в официальном аккаунте ◉Добавить группу◉, чтобы присоединиться к нашей облачной коммуникационной группе, и обсудите облачные технологии с Сунь Хунляном, директором Чжаном, Ян Мином и другими крупными шишками.