Выпуск пакетного фильтра nftables 1.0.7

Опубликован выпуск пакетного фильтра nftables 1.0.7, унифицирующего интерфейсы фильтрации пакетов для IPv4, IPv6, ARP и сетевых мостов (нацелен на замену iptables, ip6table, arptables и ebtables). В пакет nftables входят компоненты пакетного фильтра, работающие в пространстве пользователя, в то время как на уровне ядра работу обеспечивает подсистема nf_tables, входящая в состав ядра Linux начиная с выпуска 3.13. На уровне ядра предоставляется лишь общий интерфейс, не зависящий от конкретного протокола и предоставляющий базовые функции извлечения данных из пакетов, выполнения операций с данными и управления потоком.

Непосредственно правила фильтрации и специфичные для протоколов обработчики компилируются в байткод в пространстве пользователя, после чего данный байткод загружается в ядро при помощи интерфейса Netlink и выполняется в ядре в специальной виртуальной машине, напоминающей BPF (Berkeley Packet Filters). Подобный подход позволяет значительно сократить размер кода фильтрации, работающего на уровне ядра и вынести все функции разбора правил и логики работы с протоколами в пространство пользователя.

Основные изменения:

  • Для систем с ядром Linux 6.2+ добавлена поддержка сопоставления протоколов vxlan, geneve, gre и gretap, что позволяет использовать простые выражения для проверки заголовков в инкапсулированных пакетах. Например, для проверки IP-адреса в заголовке вложенного пакета из VxLAN, теперь можно использовать правила (без необходимости предварительной деинкапсуляции заголовка VxLAN и привязки фильтра к интерфейсу vxlan0):
    
          ... udp dport 4789 vxlan ip protocol udp
          ... udp dport 4789 vxlan ip saddr 1.2.3.0/24
          ... udp dport 4789 vxlan ip saddr . vxlan ip daddr { 1.2.3.4 . 4.3.2.1 }
    
  • Реализована поддержка автоматического слияния остатков после частичного удаления элемента set-списка, что позволяет удалить элемент или часть диапазона из существующего диапазона (раньше диапазон можно было удалить только целиком). Например, после удаления элемента 25 из set-списка с диапазонами 24-30 и 40-50 в списке останутся 24, 26-30 и 40-50. Исправления, необходимые для работы автослияния, будут предложены в корректирующих выпусках стабильных веток ядра 5.10+.
    
          # nft list ruleset
          table ip x {
              set y {
                  typeof tcp dport
                  flags interval
                  auto-merge
                  elements = { 24-30, 40-50 }
              }
          }
    
          # nft delete element ip x y { 25 }
    
          # nft list ruleset
          table ip x {
              set y {
                  typeof tcp dport
                  flags interval
                  auto-merge
                  elements = { 24, 26-30, 40-50 }
              }
          }
    
  • Разрешено использование контактации и диапазонов при маппинге трансляции адресов (NAT).
    
      table ip nat {
          chain prerouting {
              type nat hook prerouting priority dstnat; policy accept;
              dnat to ip daddr . tcp dport map { 10.1.1.136 . 80 : 1.1.2.69 . 1024, 
    10.1.1.10-10.1.1.20 . 8888-8889 : 1.1.2.69 . 2048-2049 } persistent
         }
      }
    
  • Добавлена поддержка выражения «last», позволяющего узнать время последнего использования элемента правила или set-списка. Возможность поддерживается начиная с ядра Linux 5.14.
    
      table ip x {
          set y {
              typeof ip daddr . tcp dport
              size 65535
              flags dynamic,timeout
              last
              timeout 1h
          }
    
          chain z {
              type filter hook output priority filter; policy accept;
              update @y { ip daddr . tcp dport }
          }
      }
    
      # nft list set ip x y
      table ip x {
          set y {
              typeof ip daddr . tcp dport
              size 65535
              flags dynamic,timeout
              last
              timeout 1h
              elements = { 172.217.17.14 . 443 last used 1s591ms timeout 1h expires 59m58s409ms,
                           172.67.69.19 . 443 last used 4s636ms timeout 1h expires 59m55s364ms,
                           142.250.201.72 . 443 last used 4s748ms timeout 1h expires 59m55s252ms,
                           172.67.70.134 . 443 last used 4s688ms timeout 1h expires 59m55s312ms,
                           35.241.9.150 . 443 last used 5s204ms timeout 1h expires 59m54s796ms,
                           138.201.122.174 . 443 last used 4s537ms timeout 1h expires 59m55s463ms,
                           34.160.144.191 . 443 last used 5s205ms timeout 1h expires 59m54s795ms,
                           130.211.23.194 . 443 last used 4s436ms timeout 1h expires 59m55s564ms }
             }
      }
    
  • Добавлена возможность определения квот в set-списках. Например, для определения квоты на трафик для каждого целевого IP-адреса, можно указать:
    
      table netdev x {
          set y {
              typeof ip daddr
              size 65535
              quota over 10000 mbytes
          }
    
          chain y {
              type filter hook egress device "eth0" priority filter; policy accept;
              ip daddr @y drop
          }
      }
    
      # nft add element inet x y { 8.8.8.8 }
      # ping -c 2 8.8.8.8
     
      # nft list ruleset
      table netdev x {
          set y {
              type ipv4_addr
              size 65535
              quota over 10000 mbytes
              elements = { 8.8.8.8 quota over 10000 mbytes used 196 bytes }
          }
    
          chain y {
              type filter hook egress device "eth0" priority filter; policy accept;
              ip daddr @y drop
          }
      }
    
  • Разрешено использование констант в set-списках. Например, при использования в качестве ключа списка адреса назначения и идентификатора VLAN можно напрямую указать номер VLAN (daddr . 123):
    
          table netdev t {
              set s {
                  typeof ether saddr . vlan id
                  size 2048
                  flags dynamic,timeout
                  timeout 1m
              }
    
              chain c {
                  type filter hook ingress device eth0 priority 0; policy accept;
                  ether type != 8021q update @s { ether daddr . 123 } counter
              }
          }
    
  • Добавлена новая команда «destroy» для безоговорочного удаления объектов (в отличие от команды delete не генерирует ENOENT при попытке удаления отсутствующего объекта). Для работы требуется как минимум ядро Linux 6.3-rc.
    
         destroy table ip filter
    

Источник: http://www.opennet.ru/opennews/art.shtml?num=58791