nftables (日本語)

From ArchWiki
Revision as of 06:09, 23 March 2014 by Kusakata (Talk | contribs)

Jump to: navigation, search

Template:Related articles start (日本語)

  • ファイアウォール
  • iptables
  • </ul></div> nftables は既存の ip-, ip6-, arp-, ebtables フレームワークを置き換える netfilter のプロジェクトです。新しいパケットフィルタリングフレームワーク、新しいユーザースペースユーティリティ (nft)、そして ip- と ip6tables の互換レイヤーを提供します。現行のフック、接続追跡システム、ユーザースペースのキューイングコンポーネント、そして netfilter のログサブシステムを使っています。

    最初のリリースは Linux 3.13 から使うことが可能で、このカーネルは現在 [core] リポジトリに入っています (linux)。(ユーザースペースコンポーネントの) nftables は [community] リポジトリから利用でき (nftables)、AUR には nftables-gitAUR パッケージがあります。

    概要

    nftables は3つのメインコンポーネントから構成されています: カーネルの実装、libnl netlink communication そして nftables ユーザースペースフロントエンド。カーネルは netlink の設定インターフェイスだけでなく、小さなクラス言語インタプリタを使用するランタイムのルールセットの評価も提供します。libnl にはカーネルと通信するためのローレベルな関数が含まれています。nftables フロントエンドはユーザーが対話するものです。

    nft

    nftables のユーザースペースユーティリティ nft は現在カーネルのためにルールセットを処理する前にほとんどのルールセットの評価を行います。そのため、nftables はデフォルトのテーブルやチェインを提供していません。しかしながらユーザーが iptables のような設定をエミュレートすることが可能です。

    ifconfig や iproute2 と同じような感じで動作します。iptables のように引数のスイッチを使う代わりに、長く構造化された連続のコマンドになります。例えば:

    nft add rule ip6 filter input ip saddr ::1 accept
    

    add はコマンドです。ruleadd のサブコマンドです。ip6rule の引数で、ip6 family を使うことを宣言しています。filterinputrule の引数で、それぞれ使用するテーブルとチェインを指定しています。残りはルールの定義で、マッチ (ip) とパラメータ (saddr)、パラメータの引数 (::1) そしてジャンプ (accept) からなります。

    以下は nft で利用できるコマンドの不完全なリストです:

    list
      tables [family]
      table [family] <name>
      chain [family] <table> <name>
    
    add
      table [family] <name>
      chain [family] <table> <name> [chain definitions]
      rule [family] <table> <chain> <rule definition>
    
    table [family] <name> (shortcut for `add table`)
    
    insert
      rule [family] <table> <chain> <rule definition>
    
    delete
      table [family] <name>
      chain [family] <table> <name>
      rule [family] <table> <handle>
    
    flush
      table [family] <name>
      chain [family] <table> <name>
    

    family は任意ですが、デフォルトは ip になります。

    テーブル

    テーブルの用途はチェインを保持することです。iptables のチェインと違って、nftables には初めから組み込まれているテーブルはありません。テーブルは指定の4つの family のうちどれか一つを持つことができ、それによって様々な iptables のユーティリティを一つに統一します:

    • ip (iptables)
    • ip6 (ip6tables)
    • arp (arptables)
    • bridge (ebtables)

    ip がデフォルトの family です。Linux 3.15 では ip と ip6 family を統一してルールを簡単に定義できるようにする5番目の family が予定されています。

    表示

    family の現在のテーブルは nft list コマンドで一覧できます。

    # nft list tables
    # nft list tables ip6
    

    テーブルの名前を指定することで完全なテーブルの定義を一覧できます:

    # nft list table foo
    # nft list table ip6 foo
    

    作成

    テーブルは2つのコマンド (片方はもう片方のショートカットです) で追加することができます。以下は foo という名前の ip テーブルと foo という名前の ip6 テーブルを追加する例です:

    # nft add table foo
    # nft table ip6 foo
    

    family が異なっていれば同じ名前のテーブルを作ることが可能です。

    削除

    テーブルを削除することができるのはチェインが存在しない場合だけです。

    # nft delete table foo
    # nft delete table ip6 foo
    

    チェイン

    The purpose of chains is to hold rules. Unlike chains in iptables, there are no built-in chains in nftables. This means that if no chain uses any types or hooks in the netfilter framework, packets that would flow through those chains will not be touched by nftables, unlike iptables.

    表示

    You can list the current chains in a chain with the nft list command, using the same method as listing a table. You can also list rules from an individual chain.

    # nft list chain foo bar
    # nft list chain ip6 foo bar
    

    These commands will list the bar chains in the ip and ip6 foo tables.

    作成

    Chains can be added when a table is created in a file definition or one at time via the nfc add chain command.

    # nft add chain foo bar
    # nft add chain ip6 foo bar
    

    These commands will add a chain called bar to the ip and ip6 foo tables.

    プロパティ

    Because nftables has no built-in chains, it allows chains to access certain features of the netfilter framework.

    # nft add chain filter input { type filter hook input priority 0; }
    

    This command tells nftables to add a chain called input to the filter table and defines its type, hook, and priority. These properties essentially replace the built-in tables and chains in iptables.

    タイプ

    チェインには3つのタイプがあり、iptables で使われているテーブルと対応しています:

    • filter
    • nat
    • route (mangle)
    フック

    チェインは5つのフックを使うことができ、iptables で使われているチェインと対応しています:

    • input
    • output
    • forward
    • prerouting
    • postrouting
    プライオリティ
    Note: Priorities do not currently appear to have any effect on which chain sees packets first.
    Note: Since the priority seems to be an unsigned integer, negative priorities will be converted into very high priorities.

    Priorities tell nftables which chains packets should pass through first. They are integers, and the higher the integer, the higher the priority.

    削除

    Chains can only be deleted if there are no rules in them.

    # nft delete chain foo bar
    # nft delete chain ip6 foo bar
    

    These commands delete the bar chains from the ip and ip6 foo tables.

    ルール

    The purpose of rules is to identify packets (match) and carry out tasks (jump). Like in iptables, there are various matches and jumps available, though not all of them are feature-complete in nftables.

    表示

    You can list the current rules in a table with the nft list command, using the same method as listing a table. You can also list rules from an individual chain.

    # nft list chain foo bar
    # nft list chain ip6 foo bar
    

    These commands will list the rules in the bar chains in the ip and ip6 foo tables.

    作成

    Rules can be added when a table is created in a file definition or one at time via the nfc add rule command.

    # nft add rule foo bar ip saddr 127.0.0.1 accept
    # nft add rule ip6 foo bar ip saddr ::1 accept
    

    These commands will add a rule to the bar chains in the ip and ip6 foo tables that matches an ip packet when its saddr (source address) is 127.0.0.1 (IPv4) or ::1 (IPv6) and accepts those packets.

    マッチ

    There are various matches available in nftables and, for the most part, coincide with their iptables counterparts. The most noticeable difference is that there are no generic or implicit matches anymore. A generic match was one that was always available, such as --protocol or --source. Implicit matches were protocol-specific, such as --sport when a packet was determined to be TCP.

    The following is an incomplete list of the matches available:

    • meta (meta properties, e.g. interfaces)
    • icmp (ICMP protocol)
    • icmpv6 (ICMPv6 protocol)
    • ip (IP protocol)
    • ip6 (IPv6 protocol)
    • tcp (TCP protocol)
    • udp (UDP protocol)
    • sctp (SCTP protocol)
    • ct (connection tracking)

    The following is an incomplete list of match arguments:

    meta:
      oif <output interface INDEX>
      iif <input interface INDEX>
      oifname <output interface NAME>
      iifname <input interface NAME>
    
      (oif and iif accept string arguments and are converted to interface indexes)
      (oifname and iifname are more dynamic, but slower because of string matching)
    
    icmp:
      type <icmp type>
    
    icmpv6:
      type <icmpv6 type>
    
    ip:
      protocol <protocol>
      daddr <destination address>
      saddr <source address>
    
    ip6:
      daddr <destination address>
      saddr <source address>
    
    tcp:
      dport <destination port>
      sport <source port>
    
    udp:
      dport <destination port>
      sport <source port>
    
    sctp:
      dport <destination port>
      sport <source port>
    
    ct:
      state <new | established | related | invalid>
    

    ジャンプ

    ジャンプは iptables と同じように使うことができますが、ひとつのルールで複数のジャンプを使用できるようになっています。

    # nft add rule filter input tcp dport 22 log accept
    

    以下はジャンプの未完成なリストです:

    • accept (accept a packet)
    • reject (reject a packet)
    • drop (drop a packet)
    • snat (perform source NAT on a packet)
    • dnat (perform destination NAT on a packet)
    • log (log a packet)
    • counter (keep a counter on a packet; counters are optional in nftables)
    • return (stop traversing the chain)

    挿入

    nft insert rule コマンドでチェインにルールを挿入することができます。

    # nft insert rule filter input ct state established,related accept
    

    削除

    Individual rules can only be deleted by their handles. The nft --handle list command must be used to determine rule handles. Note the --handle switch, which tells nft to list handles in its output.

    The following determines the handle for a rule and then deletes it. The --number argument is useful for viewing some numeric output, like unresolved IP addresses.

    # nft --handle --numeric list chain filter input
    table ip filter {
         chain input {
              type filter hook input priority 0;
              ip saddr 127.0.0.1 accept # handle 10
         }
    }
    
    # nft delete rule filter input handle 10
    

    All the chains in a table can be flushed with the nft flush table command. Individual chains can be flushed using either the nft flush chain or nft delete rule commands.

    # nft flush table foo
    # nft flush chain foo bar
    # nft delete rule ip6 foo bar
    

    The first command flushes all of the chains in the ip foo table. The second flushes the bar chain in the ip foo table. The third deletes all of the rules in bar chain in the ip6 foo table.

    ファイル定義

    Warning: The nft -f command, despite what the netfilter wiki says, is NOT atomic. This means you will have a small window between deleting the old tables and when the new ruleset is loaded where all packets will be accepted.
    Note: You must delete all conflicting tables before using the nft -f command.

    File definitions can be used by the nft -f command, which acts like the iptables-restore command.

    /etc/nftables/filter.rules
    table ip filter {
         chain input {
              type filter hook input priority 0;
              ct state established,related accept
              ip saddr 127.0.0.1 accept
              tcp dport 22 log accept
              reject
         }
    }
    

    はじめに

    iptables のようなチェインを設定するには、まず備え付けの IPv4 フィルターファイルを使う必要があります:

    # nft -f /etc/nftables/ipv4-filter
    

    To list the resulting chain:

    # nft list table filter
    

    Drop output to a destination:

    # nft add rule ip filter output ip daddr 1.2.3.4 drop
    

    Drop packets destined for local port 80:

    # nft add rule ip filter input tcp dport 80 drop
    

    Delete all rules in a chain:

    # nft delete rule filter output
    

    サンプル

    シンプルな IP/IPv6 ファイアウォール

    firewall.rules
    # A simple firewall
    
    table firewall {
      chain incoming {
        type filter hook input priority 0;
    
        # established/related connections
        ct state {established, related} accept
    
        # invalid connections
        ct state invalid drop
    
        # loopback interface
        iifname lo accept
    
        # icmp
        ip protocol icmp accept
    
        # open tcp ports: sshd (22), httpd (80)
        tcp dport {ssh, http} accept
    
        # everything else
        reject
      }
    }
    
    table ip6 firewall {
      chain incoming {
        type filter hook input priority 0;
    
        # established/related connections
        ct state {established, related} accept
    
        # invalid connections
        ct state invalid drop
    
        # loopback interface
        iifname lo accept
    
        # icmp
        ip6 nexthdr icmpv6 accept
    
        # open tcp ports: sshd (22), httpd (80)
        tcp dport {ssh, http} accept
    
        # everything else
        reject
      }
    }
    

    Limit rate と tcp flags の IP/IPv6 ファイアウォール

    firewall.2.rules
    table firewall {
        chain incoming {
            type filter hook input priority 0;
    
            # bad tcp -> avoid network scanning:
            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
    
            # no ping floods:
            ip protocol icmp limit rate 10/second accept
            ip protocol icmp drop
    
            ct state {established, related} accept
            ct state invalid drop
    
            iifname lo accept
    
    	# avoid brute force on ssh:
            tcp dport {ssh} limit rate 15/minute accept
    
            reject
        }
    }
    
    table ip6 firewall {
        chain incoming {
            type filter hook input priority 0;
    
            # bad tcp:
            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
    
            # no ping floods:
            ip6 nexthdr icmpv6 limit rate 10/second accept
            ip6 nexthdr icmpv6 drop
    
            ct state {established, related} accept
            ct state invalid drop
    
            # loopback interface
            iifname lo accept
    
    	# avoid brute force on ssh:
            tcp dport {ssh} limit rate 15/minute accept
    
            reject
        }
    }
    

    Priority-based Atomic Fix

    If priorities ever actually take effect, this may be a workaround for nft -f's lack of true atomicness (being able to replace all the current rules with new ones in one go):

    atomic.rules
    table atomic {
      chain incoming {
        type filter hook input priority 0;
        ct state new reject
      }
    }
    
    table ip6 atomic {
      chain incoming {
        type filter hook input priority 0;
        ct state new reject
      }
    }

    Set the priority of other chains that hook input to higher than 0. This should block new connections while no other input chains are loaded.

    Rules Script with Atomic Fix

    Because using nft -f to reload rulesets is time consuming, it's far easier to script it. This will include an atomic fix not based on priorities. It uses the two rules files from above.

    firewall.sh
    #!/bin/sh
    
    # Load atomic rules first
    nft -f atomic.rules
    
    # New incoming traffic should now be stopped
    
    # Get rid of both the ip and ip6 firewall tables
    
    nft flush table firewall 2>/dev/null
    nft delete chain firewall incoming 2>/dev/null
    nft delete table firewall 2>/dev/null
    
    nft flush table ip6 firewall 2>/dev/null
    nft delete chain ip6 firewall incoming 2>/dev/null
    nft delete table ip6 firewall 2>/dev/null
    
    # Reload the firewall rules
    nft -f firewall.rules
    
    # Get rid of both the ip and ip6 atomic tables
    
    nft flush table atomic 2>/dev/null
    nft delete chain atomic incoming 2>/dev/null
    nft delete table atomic 2>/dev/null
    
    # New incoming IP traffic should be working
    
    nft flush table ip6 atomic 2>/dev/null
    nft delete chain ip6 atomic incoming 2>/dev/null
    nft delete table ip6 atomic 2>/dev/null
    
    # New incoming IPv6 traffic should be working

    This should take anywhere from 100ms to 400ms, which is clearly unacceptable, but the only apparent solution.

    Systemd

    システムの起動時にルールを自動的にロードするために、AUR の nftables-systemd-gitAUR を使うことができます。 インストール方法は github のページを見て下さい。

    参照