NFtables設定メモ

nftables はLinuxのFirewall設定機能iptablesの刷新

使用環境
  kernel 3.13 以降
  kernel 3.15で完成の域に達する予定でバージョンによりサポートしていない機能がある。
  3.15 以降も従来の iptables は使用出来る。

テスト環境
 Fedora-20上のVirtualBox,Fedora-20でテストする。
   kernel-3.14.9
   libmnl-20140524,libnftnl-1.0.2, nftables-0.3

  libmnl    kernelとユーザー空間アプリの橋渡しライブラリ
  libnftnl  nftables ユーザー空間のエンジン部分
  nftables  nftables ユーザー空間のフロント部分
 
  nft コマンドは nftablesのユーザー空間での設定コマンド

使用したスクリプト(Sample code) nft_sample-0.3.tar.gz ダウンロード (Download) 
 edit  nft.d/nft_ip4.nft
 Usage)
   sudo ./nft.sh [start | stop]
   sudo ./nft.sh list

  1. nftables のコンパイル
  2. nftables の構造
  3. 使用方法
  4. nftables chain,setの削除
  5. 設定手順
  6. シンボリック変数
  7. 比較
  8. アドレス指定
  9. メタ表現
  10. Conntrack (CT)
  11. log
  12. sets
  13. map (Dictionary)
  14. Debug
  15. Mark
  16. MAC address
  17. Rate limiting
  18. NAT
  19. comments
  20. connlabel support
  21. tcp flags

  1. nftables のコンパイル
  2. requirement)
        yum install gmp gmp-devel
        yum install readline
        yum install docbook*  (doc 作成)
        yum install jansson jansson-devel ( >= 2.3) 
          tables の入出力(json)の為に使用する
    
        A:libmnl
          .configure
           make; sudo make install
        B:libnftnl
          ./configure --with-json-parsing  (--with-xml-parsing )
          make; make install
        C:nftables
          kernel 3.14.x が起動している環境でコンパイルする
          ./configure  ( --prefix=/ )
          make; sudo make install
    
    
  3. nftables の構造
  4.    Table        Chain        Hook           直下のsub-chain   それ他のsub-chain
          ip          filter      prerouting     prerouting ==> sub-chains ==> sub-chains 
          ip6         route       postrouting               ==> sub-chains ==> sub-chains 
          inet        nat         input
          arp                     output
          bridge                  forward
    
           直下のsub-chain は  iptabelsのINPUT、OUTPUT等登録済みのchainと同じ機能
          nftabelsは直下のsub-chain を定義する必要がある
           直下のsub-chainの定義がない場合には何もしないので accept と同じになる
           直下のsub-chainのtemplateが
                /etc/nftables (/usr/local/etc/nftables)  にある
                   ipv4-filter 
                   ipv4-mangle ...
    
          nft -f /etc/nftables/ipv4-filter  等で取り込む使用する事が出来る。
    
          直下のsub-chain設定には Chain,Hookのtype を指定する
            chain prerouting { type filter hook prerouting  priority 0;}
    
          それ他のchainにはChain,Hook等の指定はしない。
            nft add chain ip filter incoming_tcp{}
    
    
  5. 使用方法
  6.   1)shell ファイルに記述、又はシェルからコマンドを使用する
         nft add table ip filter
    
      2)ファイル記述
        ファイルにコードを記述し引数で指定する、又はファイルを直接起動する
         sudo nft -f filename
         sudo ./ipv4.nft
    
        ファイルにルールを保存し、保存したファイルから設定する
        nft list table filter > filter-table
        nft -f filter-table
     
        XML/JSON ruleset export
          sudo nft export json > rules.json
           json,XML 形式での保存、(将来は読み込みも可能)
    
      3)インタラクティブモード
        sudo nft -i
        nft> add table ip filter
        nft> list tables
        nft> delete table ip filter
    
    
  7. nftables chain,setの削除
  8. nftables を設定する場合には既存の nftables chain,setを削除してから行う。
      下記は削除スクリプト
    
      -----------------------------------
      #!/bin/bash
      Tables="ip ip6 inet arp bridge"
    
      function nft_flush_delete() {
         for T in $(nft list tables $1 | cut -d ' ' -f 2) ; do
            #echo "flush $1 $T"
            nft flush table $1 $T
            nft list table $1 $T -nn | awk '/^[ \t]+chain/{ print $2 }' | xargs -r -L 1 nft delete chain $1 $T
            #echo "flush set $1 $T"
            nft list table $1 $T -nn | awk '/^[ \t]+set/{ print $2 }' | xargs -r -L 1 nft delete set $1 $T
            nft delete table $1 $T > /dev/null
         done
      }
    
      for P in $Tables; do
         nft_flush_delete $P
      done
    
      -----------------------------------
    
    iptables が起動している場合には stop しテーブルをクリアする
        Fedora系)
            sudo systemctl --system stop firewalld.service
            sudo systemctl --system disable firewalld.service
    
        Ubuntu系)
            sudo initctl stop iptables
    
    
  9. 設定手順
  10. 直下のsub-chainを設定する
     nft -f /etc/nftables/ipv4-filter を読み込む
     
     又は設定ファイルを作成する
     add table ip filter {
    	chain prerouting { type filter hook prerouting  priority 0;}
    	chain postrouting{ type filter hook postrouting priority 0;}
    	chain output     { type filter hook output  priority 0;}
    	chain input      { type filter hook input   priority 0;}
    	chain forward    { type filter hook forward priority 0;}
      }
    
    ip は省略出来る(default設定)
        add table ip filter
        ==> add table filter
    
    設定の一覧表示
        sudo nft list tables [ip| ip6 | inet | arp | bridge]
        sudo nft list ip table [filter| nat] -nn
        sudo nft list set ip filter [blacklists | tcp_ports | ... ] -n
    
         -n   ipaddress を名前に変換しない
         -nn  port番号をサービス名に変換しない
    
        サンプルコード (lnft.sh)
    
  11. シンボリック変数
  12.     define ext_if = eth0
        define ext_ifs = { $ext_if }
        filter input iifname $ext_ifs
    
      アドレスで使用する場合には注意)
        define private_addr2 = {192.168.2.126-192.168.255.255}
        define private_addr1 = {192.168.0.0/16} 
        define private_addr0 = {10.0.0.0/8,172.16.0.0/12,192.0.2.0/24,192.0.0.0/24,192.88.99.0/24,169.254.0.0/16}
    
        define  private_addr_all = {$private_addr2, $private_addr0 }
        add rule filter postrouting oif $ext_if1 ip daddr $private_addr_all log prefix "Drop_post_private_addr_all:" drop
            ==> Error: Core dump
    
        下記はOK
        add rule filter postrouting oif $ext_if1 ip daddr $private_addr0 log prefix "Drop_post_private_addr_0:" drop
        add rule filter postrouting oif $ext_if1 ip daddr $private_addr2 log prefix "Drop_post_private_addr_2:" drop
    
    
      includeしたファイル内では使用出来る
        ## ephmeral-ports
        define ephmeral_min = 49152
        define ephmeral_max = 61000
        include "local_printer.nft"
    
        local_printer.nft
          add rule filter jetdirect_out ct state new,established tcp sport >= $ephmeral_min tcp sport = $ephmeral_max tcp dport $jetdirect_tcp accept
    
  13. 比較
  14.     ne which stands for non equal. Alternatively you can use !=
        lt means less than. Alternatively you can use <
        gt means less than. Alternatively you can use >
        le means less than. Alternatively you can use <=
        ge means less than. Alternatively you can use >=
    
        nft add rule input test test tcp dport != 22
        nft add rule input test test tcp dport >= 1024
    
    
  15. アドレス指定
  16.     add rule filter OUTPUT ip daddr 192.168.0.0/24
        add rule filter OUTPUT ip daddr 192.168.0.0/255.255.255.0
        add rule filter OUTPUT ip saddr . ip daddr 192.168.0.0/24 . 192.168.0.0/24
        add rule filter OUTPUT ip daddr { 192.168.0.0/24, 192.168.1.0/24}
    
        nft add rule filter input ip daddr 192.168.0.1-192.168.0.250 drop
        nft add rule ip filter input ip saddr { 192.168.1.1-192.168.1.200, 192.168.2.1-192.168.2.200 } drop
        nft add rule ip filter forward ip daddr { 
            192.168.1.1-192.168.1.200 : jump chain-dmz, 
            192.168.2.1-192.168.20.250: jump chain-desktop 
            } drop
    
    
  17. メタ表現
  18. nftables-2.0 からは meta を記述しなくてもよい様であるが
      記述しないとエラーになるものもある。
    
      nft filter output meta skuid root accept
       ==> nft filter output skuid root accept
    
        # meta: skb length
        add rule filter outgoing_udp udp dport @dns_port ip daddr @dns_server meta length < 256 accept
        add rule filter outgoing_udp udp dport @ntp_port udp sport @ntp_port ip daddr @ntp_server meta length 76 accept 
    
        # meta: protocol
        add rule ip filter output meta protocol 0x0800 counter
    
        # meta: iifname,oifname :: input,output iface_index
        add rule ip filter output meta iifname "eth0" counter
        add rule ip filter output meta oifname "eth0" counter
        add rule ip filter output meta iifname $ext_ifs  # define 設定の場合
      
        # meta: iif,oif :: 
        add rule ip filter output meta iif lo counter
        add rule ip filter output meta oif lo counter
        add rule ip filter output meta oif @ext_ifs   # sets 設定の場合
    
        # meta: uid
        nft add rule filter output meta skuid pablo counter
        nft add rule filter output meta skuid 1000 counter
    
        # meta: gid
        add rule ip filter output meta skgid 1000 counter
    
        # meta: mark
        add rule ip filter output meta mark 0 counter
        nft add rule filter output meta mark 123 counter
    
        # meta: secmark
        add rule ip filter output meta secmark 0 counter
    
        # meta: nftrace
        add rule ip filter output meta nftrace 1 counter
    
        # meta: rtclassid (see /etc/iproute2/rt_realms)
        add rule ip filter output meta rtclassid cosmos counter
    
    
  19. conntrack (CT)
  20. State information: new, established, related and invalid. 
      
        # ct: state
        ct state {new,established} accept
        ct state invalid drop
    
        # ct: helper 
        add rule filter tcp_helper ct helper "ftp" accept
        add rule filter tcp_helper ct helper "irc" accept
        add rule filter tcp_helper return
        add rule filter outgoing_tcp tcp dport 1024-65535 ct state {established,related} jump tcp_helper
    
        # ct: direction original/reply
        add rule ip filter output ct direction original counter
        add rule ip filter output ct direction reply counter
    
        # ct: mark
        nft add rule filter input ct mark 123 counter
        nft add rule ip filter output ct mark 0 counter
        nft filter output mark set ct mark
        nft filter output ct mark set 0x1
    
        # ct: secmark
        add rule ip filter output ct secmark 0 counter
    
        # ct: expiration
        add rule ip filter output ct expiration 30 counter
    
    
  21. log
  22. log option
       prefix string
       group number    (log-level ?)
       snaplen number
       queue-threshold number
      
        sudo modprobe xt_LOG と nft_log モジュールを事前に読込む。
    
        add rule filter incoming_icmp ct state {established,related} icmp type @icmp_incoming log prefix "Accept_icmp_incoming:" accept
    
        log prefix の長さ制限はない  (iptables:29 文字)
          Apr 21 13:42:31 dac77 kernel: [18865.439788] Accept_icmp_incoming_1234567890_12345:IN=p2p1 OUT=
          MAC=08:00:27:b0:53:68:52:54:00:12:35:02:08:00 SRC=8.8.8.8 DST=10.0.2.15 LEN=84 TOS=0x00 PREC=0x00 
          TTL=63 ID=3749 DF PROTO=ICMP TYPE=0 CODE=0 ID=15682 SEQ=3 
    
        add rule filter prerouting ip saddr @blacklists log prefix "Drop_pre_blacklist:" drop
         は 下記 iptables と同じ log を出力する
          iptables xxx -j LOG --log-prefix "Drop_pre_blacklist:" --log-ip-options
    
    
  23. sets
  24. サポートするデータタイプ
        IPv4 address
        IPv6 address
        Ethernet address
        Protocol type
        Mark type
    
    名前なし sets 
        nft add rule filter output tcp dport { 22, 23 } counter drop
    名前付 sets
        nft add set filter blacklists { type ipv4_addr;}
    
    setsの定義、格納するデータタイプを指定する
        add set ip filter eth_ifs  { type iface_index;}    # eth0
        add set ip filter dns_port { type inet_service;}   # 53,80,443
        add set ip filter icmp_outgoing { type icmp_type;} # echo-reply,echo-request
        add set ip filter blacklists { type ipv4_addr;}    # 1.2.3.4 
    
    sets の定義場所
        add set ip filter ext_ifs  { type iface_index;}
        add element filter ext_ifs { $ext_ifs }
            と定義の後、続けてデータを設定すると環境によってはエラーになる
    
         対応 1:filter 定義内に記述する
           add table ip filter {
              chain prerouting { type filter hook prerouting  priority 0;}
                ..
              set ext_ifs  { type iface_index;}
    
             }
         対応 2: 事前に別ファイルで定義する
           add set ip filter ext_ifs  { type iface_index;}  
    
    データを設定する
       define,set に要素数の制限はない (iptables の multiports はMAX 14)
    
        nft add element filter eth_ifs { eth0,eth1 }
        nft delete element filter blacklists { 192.168.1.5 }
        nft delete set filter blacklists
    
      # Concat expression
        add rule ip filter output ip daddr . tcp dport { \
    	    192.168.0.1 . 22,	\
    	    192.168.0.1 . 80,	\
          }
    
      iif or oif @eth_ifs  ( iifname @eth_ifs はダメ)
    
      setsは包含関係のみ下記はダメ
          iif < @eth_ifs 
          iif != @eth_ifs 
    
    set private_addr { type ipv4_addr;}
        192.168.0.0/16, 10.0.0.0-10.0.128.255 等なダメ
         アドレス範囲指定は define では有効
    
    
  25. map (Dictionary)
  26. 名前付 map
        add map filter verdict_map { type ipv4_addr : verdict; }
        add element filter verdict_map { 1.2.3.5 : drop}
        add element filter verdict_map { 1.2.3.4 : accept}
        add rule filter output ip daddr vmap @verdict_map
        delete element filter verdict_map 1.2.3.5
        delete set filter verdict_map
         名前で追加、削除が出来る
    
    名前なし map
        nft add rule ip filter input ip protocol vmap { \
             tcp : jump tcp-chain, \
             udp : jump udp-chain, \
             icmp : jump icmp-chain }
    
        add filter input ip saddr vmap { \
    	    10.0.0.0/24 : jump chain1, \
    	    10.0.0.0/8  : jump chain2, \
    	    8.8.8.8 : jump chain3 \
         }
    
        nft add rule filter output ip daddr vmap { \
                192.168.0.0/24 : drop, \
                192.168.0.1 : accept}
    
    
  27. Debug
  28.     ## scanner, parser, eval, netlink, mnl, proto-ctx, segtree, all
        nft --debug parser -I $nftDir -f $nftDir/nft_ip4.nft 
    
    
  29. Mark
  30.     add rule filter OUTPUT meta mark 123/0x000000ff
    
        nft filter input mark set 0x1
        nft filter input mark set mark | 0x1
           will OR the current value with 0x1.
    
        nft filter input mark set ip saddr map {
    	    192.168.0.0/24 : 0x1,
    	    192.168.1.0-192.168.1.64 : 0x2,
    	    192.168.2.1 : 0x3,
    	    * : 0x4
          }
    
    
  31. MAC address
  32.     define if1_mac = 00:1b:21:02:6f:ad
        add rule filter prer_eth iif $ext_if1 ether daddr $if1_mac return
        add rule filter prer_eth oif $ext_if1 ether saddr $if1_mac return
    
    
  33. Rate limiting
  34. Rate limiting matchings
        
        nft add rule filter input icmp type echo-request limit rate 10/second accept
        ip protocol icmp limit rate 10/second accept
        ip protocol icmp drop
        tcp dport ssh limit rate 15/minute accept
    
    
  35. NAT
  36.    include "ipv4-nat.nft" 
       nft add rule nat postrouting ip saddr $local_net oifname $ext_if snat [ xx.xx.xx.xx | xx.xx.xx.xx:port ]
    
       nft add rule nat prerouting iif $int_ifs udp dport @udp_proxies dnat $udp_proxy_ipaddr
    
    
  37. comments
  38.     nft filter input tcp dport ssh accept comment "SSH access"
    
    
  39. connlabel support
  40.     Support for connection tracking labels (connlabels) has been added.
        connlabel.conf is parsed and the values can be used as symbolic
        constants in combination with the "ct label" expression.
    
        /etc/xtables/connlabel.conf
    
        nft filter input ct label clients,servers accept
    
    
  41. tcp flags
  42. pre-defined symbolic constants:
           fin       0x01
           syn       0x02
           rst       0x04
           psh       0x08
           ack       0x10
           urg       0x20
           ecn       0x40
           cwr       0x80
    
        tcp flags & (fin|syn) == (fin|syn)  drop
        tcp flags & (syn|rst) == (syn|rst)  drop
        tcp flags & (fin|syn|rst|psh|ack|urg) < (fin) drop # == 0 would be better, not supported yet.
        tcp flags & (fin|syn|rst|psh|ack|urg) == (fin|psh|urg) drop
    
    

to Top
ホームページ へ

Last modified: 2014-07-15; First Release: 2014-04-22;