動機

記錄用

基本概念

table: chain與各式data structrue的收納庫,定義旗下的chain收什麼類型的封包(family)

  • family
    • ip: ipv4
    • ip6: ipv6
    • arp: arp
    • bridge: 在linux bridge的pkt
    • inet = ip + ip6
    • netdev: interface的pkt chain: 就有一堆rule,由type與hook決定這個chain在哪發揮作用
  • type: 說明這個chain處理哪個方面的工作
    • filter: 就是filter
      • arp, bridge, ip, ip6, inet, netdev
    • route: Mark packets
      • ip, ip6, inet
    • nat: Perform Network Address Translation
      • ip, ip6, inet
  • hook: 裡面的rule會掛在netfilter的那個hook上
    • ip, ip6, inet: prerouting, input, forward, output, postrouting
    • arp: input, output
    • netdev: ingress (這個是例外,這不在原本的netfilter)
    • bridge: prerouting, input, forward, output, postrouting (這個是例外,這不在原本的netfilter)

nftable一個做得好的是把chain與hook分開了 所有XXtables都是照netfilter去掛hook做packet過濾,但是之前都是會事先綁好,導致真的不好懂,也不知道為什麼要這麼做

netfilter hooks

基本操作

  • 全清掉: nft flush ruleset
  • 刪table: nft delete table ip mytable
  • 列所有table: nft list tables
  • 列table裡面有的東西: nft list table ip mytable -n -a
    • -n -a: 是為了show handle,就是iptables的rule位置(index)
  • 插rule: nft insert rule mytable mychain position 8 ip daddr 127.0.0.8 drop
    • insert before handle 8
  • 塞rule到第一個: nft insert rule mytable mychain ip daddr 127.0.0.8 drop
  • 刪rule: nft delete rule mytable mychain handle 8

特別注意!!

  • 現在nft的錯誤訊息做的十分不好,不論什麼錯都是找不到對應的檔案的err msg,所以要
    • 一條一條的下
    • family都要打出來

加規則

  • nft verb
    • family table
      • chain …
    • family table chain
      • conditions
        • ip saddr ip …

下面是同一個rule的兩種下法

nft add table ip mytable
nft add chain ip mytable mychain { type filter hook output priority 0 \; policy accept \; }
nft add rule ip mytable mychain ip saddr 192.168.12.23 tcp dport 1234 drop
define myaddr = "192.168.12.23"
table ip mytable {
    chain mychain {
        type filter hook output priority 0;
        policy accept;

        ip saddr $myaddr tcp dport 1234 drop
    }
}

只有type要加分號,其他都不用

剩下還有很多condition可以下,可以去參考Quick reference-nftables in 10 minutes

接著介紹其他有點程式語言的功能

data structrue

symbol var

就是macro展開

define myaddr = 192.168.12.23

table ip mytable {
    chain chain2 {
        type filter hook output priority 0;
        policy accept;

        ip saddr $myaddr tcp dport 1234 drop
    }
}

set

nft add set ip mytable myset { type ipv4_addr \; }
nft add element ip mytable myset { 192.168.1.4, 192.168.1.5 }
nft add rule ip mytable mychain ip saddr @myset

attributes

type & typeof

ipv4_addr: IPv4 address ipv6_addr: IPv6 address. ether_addr: Ethernet address. inet_proto: Inet protocol type. inet_service: Internet service (read tcp port for example) mark: Mark type. ifname: Network interface name (eth0, eth1..)

table inet mytable {
	set s1 {
		typeof osf name
		elements = { "Linux" }
	}
	set s2 {
		typeof vlan id
		elements = { 2, 3, 103 }
	}
	set s3 {
		typeof ip daddr
		elements = { 1.1.1.1 }
	}
}
flags

constant - set content may not change while bound interval - set contains intervals timeout - elements can be added with a timeout

nft add set ip mytable myset { type ipv4_addr \; flags constant, interval \; }
meter

dynamic - make a meter!!

nft add set my_filter_table my_ssh_meter { type ipv4_addr\; flags dynamic \;}
nft add rule my_filter_table my_input_chain tcp dport 22 ct state new add @my_ssh_meter { ip saddr limit rate 10/second } accept
etc

size: mits the maximum number of elements of the set policy: set selection policy * performance (default) * memory elements: initialize the set with some elements in it

nft add set ip filter daddrs {type ipv4_addr \; flags timeout \; elements={192.168.1.1 timeout 10s, 192.168.1.2 timeout 30s} \;}

map

nft add map ip mytable porttoip  { type inet_service: ipv4_addr\; }
nft add element ip mytable porttoip { 80 : 192.168.1.100, 8888 : 192.168.1.101 }
nft add rule ip mytable postrouting snat to tcp dport map @porttoip

Verdict Maps

value是action

table ip filter {
    chain input {
                type filter hook input priority 0;
                ip protocol vmap { udp : jump udp-chain, tcp : jump tcp-chain, icmp : jump icmp-chain}
    }

    chain tcp-chain {
                counter packets 4 bytes 520
    }

    chain udp-chain {
                counter packets 4 bytes 678
    }

    chain icmp-chain {
                counter packets 4 bytes 336
    }
}
nft add map filter mydict { type ipv4_addr : verdict\; }
nft add element filter mydict { 192.168.0.10 : drop, 192.168.0.11 : accept }
nft add rule filter input ip saddr vmap @mydict

Concatenations (tuple)

把value或是條件用.連起來

nft add rule ip mytable mychain ip saddr . ip daddr . ip protocol { 1.1.1.1 . 2.2.2.2 . tcp, 1.1.1.1 . 3.3.3.3 . udp} counter accept

其他有用的資料結構

flow table: 可以跳過linux stack的table,做offload Conntrack helpers: 依據Conntrack去控制rule

Ref

nftables Main page Setting up nftables Firewall Quick reference-nftables in 10 minutes