Red Hat Training

A Red Hat training course is available for RHEL 8

10.6. nftables コマンドにおける決定マップの使用

ディクショナリーとしても知られている決定マップにより、nft は一致基準をアクションにマッピングすることで、パケット情報に基づいてアクションを実行できます。

10.6.1. nftables での匿名マップの使用

匿名マップは、ルールで直接使用する { match_criteria : action } ステートメントです。ステートメントには、複数のコンマ区切りマッピングを含めることができます。

匿名マップの欠点は、マップを変更する場合には、ルールを置き換える必要があることです。動的なソリューションの場合は、nftables での名前付きマップの使用 で説明されているように名前付きマップを使用します。

たとえば、匿名マップを使用して、IPv4 プロトコルおよび IPv6 プロトコルの TCP パケットと UDP パケットの両方を異なるチェーンにルーティングし、着信 TCP パケットと UDP パケットを個別にカウントできます。

手順

  1. 新しいテーブルを作成します。

    # nft add table inet example_table
  2. example_tabletcp_packets チェーンを作成します。

    # nft add chain inet example_table tcp_packets
  3. このチェーンのトラフィックをカウントする tcp_packets にルールを追加します。

    # nft add rule inet example_table tcp_packets counter
  4. example_tableudp_packets チェーンを作成します。

    # nft add chain inet example_table udp_packets
  5. このチェーンのトラフィックをカウントする udp_packets にルールを追加します。

    # nft add rule inet example_table udp_packets counter
  6. 着信トラフィックのチェーンを作成します。たとえば、example_table に、着信トラフィックをフィルターリングする incoming_traffic という名前のチェーンを作成するには、次のコマンドを実行します。

    # nft add chain inet example_table incoming_traffic { type filter hook input priority 0 \; }
  7. 匿名マップを持つルールを incoming_traffic に追加します。

    # nft add rule inet example_table incoming_traffic ip protocol vmap { tcp : jump tcp_packets, udp : jump udp_packets }

    匿名マップはパケットを区別し、プロトコルに基づいて別のカウンターチェーンに送信します。

  8. トラフィックカウンターの一覧を表示する場合は、example_table を表示します。

    # nft list table inet example_table
    table inet example_table {
      chain tcp_packets {
        counter packets 36379 bytes 2103816
      }
    
      chain udp_packets {
        counter packets 10 bytes 1559
      }
    
      chain incoming_traffic {
        type filter hook input priority filter; policy accept;
        ip protocol vmap { tcp : jump tcp_packets, udp : jump udp_packets }
      }
    }

    tcp_packets チェーンおよび udp_packets チェーンのカウンターは、受信パケットとバイトの両方を表示します。

10.6.2. nftables での名前付きマップの使用

nftables フレームワークは、名前付きマップに対応します。テーブルの複数のルールでこのマップを使用できます。匿名マップに対する別の利点は、名前付きマップを使用するルールを置き換えることなく、名前付きマップを更新できることです。

名前付きマップを作成する場合は、要素のタイプを指定する必要があります。

  • 一致する部分に 192.0.2.1 などの IPv4 アドレスが含まれるマップの場合は ipv4_addr
  • 一致する部分に 2001:db8:1::1 などの IPv6 アドレスが含まれるマップの場合は ipv6_addr
  • 52:54:00:6b:66:42 などのメディアアクセス制御 (MAC) アドレスを含むマップの場合は ether_addr
  • 一致する部分に tcp などのインターネットプロトコルタイプが含まれるマップの場合は inet_proto
  • 一致する部分に ssh22 などのインターネットサービス名のポート番号が含まれるマップの場合は inet_service
  • 一致する部分にパケットマークが含まれるマップの場合は mark。パケットマークは、任意の正の 32 ビットの整数値 (0 ~ 2147483647) にできます。
  • 一致する部分にカウンターの値が含まれるマップの場合は counter。カウンター値は、正の値の 64 ビットであれば任意の値にすることができます。
  • 一致する部分にクォータ値が含まれるマップの場合は quota。クォータの値は、64 ビットの整数値にできます。

たとえば、送信元 IP アドレスに基づいて着信パケットを許可または拒否できます。名前付きマップを使用すると、このシナリオを設定するのに必要なルールは 1 つだけで、IP アドレスとアクションがマップに動的に保存されます。

手順

  1. テーブルを作成します。たとえば、IPv4 パケットを処理する example_table という名前のテーブルを作成するには、次のコマンドを実行します。

    # nft add table ip example_table
  2. チェーンを作成します。たとえば、example_table に、example_chain という名前のチェーンを作成するには、次のコマンドを実行します。

    # nft add chain ip example_table example_chain { type filter hook input priority 0 \; }
    重要

    シェルがセミコロンをコマンドの終わりとして解釈しないようにするには、バックスラッシュでセミコロンをエスケープする必要があります。

  3. 空のマップを作成します。たとえば、IPv4 アドレスのマッピングを作成するには、次のコマンドを実行します。

    # nft add map ip example_table example_map { type ipv4_addr : verdict \; }
  4. マップを使用するルールを作成します。たとえば、次のコマンドは、両方とも example_map で定義されている IPv4 アドレスにアクションを適用するルールを、 example_tableexample_chain に追加します。

    # nft add rule example_table example_chain ip saddr vmap @example_map
  5. IPv4 アドレスと対応するアクションを example_map に追加します。

    # nft add element ip example_table example_map { 192.0.2.1 : accept, 192.0.2.2 : drop }

    以下の例では、IPv4 アドレスのアクションへのマッピングを定義します。上記で作成したルールと組み合わせて、ファイアウォールは 192.0.2.1 からのパケットを許可し、192.0.2.2 からのパケットを破棄します。

  6. オプション: 別の IP アドレスおよび action ステートメントを追加してマップを拡張します。

    # nft add element ip example_table example_map { 192.0.2.3 : accept }
  7. オプション: マップからエントリーを削除します。

    # nft delete element ip example_table example_map { 192.0.2.1 }
  8. オプション: ルールセットを表示します。

    # nft list ruleset
    table ip example_table {
      map example_map {
        type ipv4_addr : verdict
        elements = { 192.0.2.2 : drop, 192.0.2.3 : accept }
      }
    
      chain example_chain {
        type filter hook input priority filter; policy accept;
        ip saddr vmap @example_map
      }
    }

10.6.3. 関連情報

  • nft(8) の man ページの Maps セクション