Linux × Security パケットフィルタリング編

    Linux × Security パケットフィルタリング編

    目次

      はじめに

      クラウドインテグレーション部の渡邊です。

      本記事のシリーズでは、サーバの構築・運用に最低限必要なセキュリティの体系的知識習得を目的としています。

      本シリーズの全体像と今回執筆の内容の位置づけは以下の通りです。

      環境

      Amazon Linux 2

      概要

      パケットフィルタリングとは、ファイアウォールによってパケットを通過させたり遮断したりする処理です。 これらは、送信元/宛先アドレス・ポート・プロトコルなどに基づいて、ネットワークインターフェースのデータパケットに対して処理が行われるため、OSI参照モデルで言うと L3 や L4 に該当します。

      LinuxOSの場合、Netfilterというパッケージでパケットフィルタリング機能を実現しています。Netfilterを管理するための代表的なツールとしてiptablesやfirewalldがあります。

      また、AWSで使用するセキュリティグループやネットワークACLなどのファイアウォールを設定する場合でもiptablesやfirewalldはセキュリティソフトウェア導入などで今でも設定が必要な場合があります。

      iptablesの構成

      まず、Netfilterの管理インターフェースであるiptablesですが、テーブル、チェイン、ルールの3つで構成されています。 永続的に設定を保存するためには設定ファイル/etc/sysconfig/iptablesが必要で、iptablesのサービス起動時に設定ファイルの内容がiptablesのルールとして反映されます。

      スキーマの大きい順番から以下の構成となっております。

      • テーブル・・・iptablesで実現する操作を定義するもの
      • チェイン・・・パケット操作を実行する場所(タイミング)を定義するもの
      • ルール・・・パケットの処理方法を指定する条件を定義するもの

        202308_linux_01-1

       

      テーブル種類

      一番大きい単位としてテーブルがあります。デフォルトのテーブルはfilterですが、それ以外にもnatやmangleなど別の用途で使用するテーブルがあります。 各テーブルで用途が違うため、実現する操作が適用されるタイミングが異なります。 よって、各テーブルで使えるチェインが異なります。 例えば natですと IP アドレスやポートの変換、mangleですとIPヘッダの変換などが用途です。

      テーブル名 用途 チェイン
      filter パケットフィルタ(デフォルト) INPUT/FOWARD/OUTPUT
      nat NAT 用 PREROUTING/OUTPUT/POSTROUTING
      mangle QoS/SECMARK など特別なパケット変換 PREROUTING/INPUT/FORWARD/OUTPUT/POSTROUTING

       ※rawやsecurityテーブルは割愛

       

      チェインおよびパケット処理フロー

      チェインのタイプとして5つあります。

      チェイン 説明
      INPUT マシン自体に入ってくるパケットに対するチェイン
      FORWARD マシンを経由するパケットに対するチェイン
      OUTPUT ローカルマシンで生成されたパケットに対するチェイン
      PREROUTING パケットが入ってきた場合、すぐにそのパケットを変換するためのチェイン
      POSTROUTING パケットが出て行くときに変換するためのチェイン

      表とチェインの適用タイミングの図を見てみると 主にルーティングの前後、パケットからプロセスへの入出で分類されていることがわかります。

      【チェインの適用タイミング】 

      202308_linux_02

      引用元:「Linuxセキュリティ標準教科書」 特定非営利活動法人エルピーアイジャパン p.33

      例えば、PREROUTINGは外部からのパケットをルーティングする前のタイミングで適用されます。 また、FORWARDはプロキシ経由で別のサーバーに転送するような処理で適用されます。

       

      ルールのコマンドとフィールド

      コマンド

      ルールを設定する際のコマンド例は以下の通りです。本コマンドは、外部サーバへ送信されたICMPエコーリクエストがドロップされるルールを設定しています。

      iptables -t filter -A OUTPUT  -p icmp --icmp-type echo-request -j DROP

      コマンド内のオプションの説明は以下の通りです。

      -t filter: テーブルを指定しています。テーブルとしては指定されているfilterは、パケットのフィルタリングと制御に使用されるテーブルです。

      -A OUTPUT: ルールを追加するチェインを指定します。OUTPUTチェインは、ローカルから発信されるパケットに適用されるルールを含んでいます。また、既存のルールを削除する際には-Dを指定します。

      -p icmp: プロトコルを指定します。

      --icmp-type echo-request: ICMPメッセージの種類を指定します。ここでは"echo-request"(Pingリクエスト)を指定しています。

      -j DROP: 該当したパケットの処理方法を指定します(パケットの行方=JUMP)。ここではパケットを破棄(DROP)するように指定しています。

      今回使用したオプション以外にもあるので気になる方はmanページを参考にしてください。

      フィールド

      ルールの内容はiptablesコマンドで確認することができます。

      $ sudo iptables -L INPUT --line-numbers
      Chain INPUT (policy ACCEPT)
      num target prot opt source destination
      1 DROP tcp -- anywhere anywhere tcp dpt:http

      ルールのフィールドは以下の通りです。

      フィールド名 値 / 説明
      num ルール番号
      target パケットがルールに一致する場合、targetはそのルールでどのように処理するかを指定(ACCEPT、DROP、RETURN、REJECT等)
      prot tcp、udp、icmpまたはallなどのプロトコル
      opt オプション
      source トラフィックの送信元IPアドレスまたはサブネット、またはanywhere
      destination トラフィックの宛先IPアドレスまたはサブネット、またはanywhere
      ラベルが付いていない最後の列 前列で示されていないルールの一部を表示

      ルールは番号(num)の小さい順に適用されるため、ルールに該当したパケットはそれより後方のルールによって処理されません。 また、番号変更はあとからでも可能です。

      targetの処理に関して、DROP(パケットを破棄)やREJECT(接続を拒否)などの使い分けによって、パケットに対する処理方法を細かく制御することができます。 例えば、ブラウザがタイムアウトになるような状況を作りたい場合は、DROPを使用すると良いでしょう。

      ラベルが付いていない最後の列はどのフィールドにも該当しない内容が記載されます。 例えば以下のような処理が記載されます。

      • ICMPのタイプに基づいたパケットフィルタリング
        • 例:拒否したことを接続元に通知する場合に、icmp-host-prohibitedメッセージを返すルールの場合はreject-with icmp-host-prohibitedと表示される
      • 接続状態でフィルタリング
        • 例:TCPの3-wayハンドシェイクが完了した接続に対するルールの場合はstate ESTABLISHEDと表示される

      firewalld

       

      firewalld概要

      iptables同様Netfilterの管理インターフェースとなるfirewalldは以下の特徴があります。

      • CentOS7やRHEL7から採用された
      • Firewalldの裏側ではiptablesなどが動いている
      • ゾーンと呼ばれるグループ化したフィルタリングルールをインターフェース毎に割り当てて制御を行う

      ファイアウォールの構造を見てみるとiptablesなどがバックエンドとして動いていることが分かると思います。

      202308_linux_03

      引用元:https://firewalld.org/2018/07/nftables-backend

       

      ゾーンは、グループ化されたフィルタリングルールのまとまりであり、一括でルールを適用することができます。特定のインターフェースにルールを割り当てると、そのルールが一括で適用されるため、設定が容易になります。

      例えば、WebサーバとのインターフェースはゾーンA、LANとのインターフェースはゾーンBを適用することが可能になります。

       

      ゾーンの説明

      ゾーンには以下のものがあります。

      ゾーン名 用途
      public サーバとして最低限必要な受信許可ルール
      work 業務用クライアントPCとしての利用を想定したルール
      home 家庭用クライアントPCとしての利用を想定したルール
      internal Linuxを用いてファイアウォールを構築する際に使用するルール
      (内部ネットワークのインターフェイスに対して設定)
      external 同上
      (外部ネットネットワークのインターフェイスに対して設定)
      dmz 同上
      (DMZのインターフェイスに対して設定)
      block 受信パケットを全て拒否するルール(icmp-host-prohibitedメッセージで応答)
      drop 受信パケットを全て破棄するルール(外向きネットワークコネクションだけが可能)
      trusted 全ての通信を許可するルール

      firewalld有効時のデフォルトのゾーンはpublicです。 sshなどは事前に許可されておりましたがhttp通信は許可されておりませんでした。

      # firewall-cmd --list-services --zone=public
      dhcpv6-client mdns ssh

      また、表のゾーンの中でそのゾーンの用途から設定変更不可なものがあり、以下の3つです。変更不可であるゾーンが存在することは認識しておきましょう。

      • trusted
      • drop
      • block

      参考:FirewallD/jp

       

      firewalldのルール

      firewalldのルールには通常のルールとリッチルールがあります。 各ルールの中身は以下のようになっています。

      通常のルール

      [root@ip-172-31-6-14 ~]# firewall-cmd --list-services --zone=public 
      ssh dhcpv6-client http

      リッチルール

      [root@ip-172-31-6-14 ~]# firewall-cmd --zone=public --list-rich-rules
      rule family="ipv4" source address="XXX.XXX.XXX.XXX" port port=”80" protocol="tcp" accept

      通常ルールと比べると、リッチルールはプロトコル・ポート・ソース・宛先などの多くの条件を組み合わせ、ゾーンに対して細かいルールを追加することができます。

      またリッチルールと通常のルールは同じゾーンに指定した場合 public.xml のようなゾーンの設定ファイルで一括管理されます。

      [root@ip-172-31-9-27 ec2-user]# cat /etc/firewalld/zones/public.xml
      <?xml version="1.0" encoding="utf-8"?>
      <zone>
      <short>Public</short>
      <description>For use in public areas. You do not trust the other computers on networks to not harm your computer. Only selected incoming connections are accepted.</description>
      <service name="ssh"/>
      <service name="mdns"/>
      <service name="dhcpv6-client"/>
      <rule family="ipv4">
      <source address="XXX.XXX.XXX.XXX"/>
      <port port="80" protocol="tcp"/>
      <accept/>
      </rule>
      <forward/>
      </zone>

      また、ルールを適用した後は以下のように設定の読み込みのコマンドを実行する必要がありますので注意しましょう。

      firewall-cmd --reload

       

      firewalldとiptablesの違い

        iptables firewalld
      CentOS バージョン CentOS 6以前 CentOS 7以降
      設定反映時 通信の瞬断が発生 通信の瞬断は発生しない
      設定の難易度 設定の難易度が高い 設定の難易度が比較的簡単
      運用の柔軟性 一時的なルールの設定は困難 一時的なルールと永続的なルールをそれぞれ管理可能、一時的に有効にするといったルールの設定も可能

      特に、Firewalldはpermanentをオプションにつけるだけで一時的か永続的かコントロールできる点や設定反映による瞬断が発生しない点は大きく運用負荷の軽減に寄与すると思われます。

      ポート開放の注意点

      外部から開放されているポートへ侵入されるセキュリティリスクを防ぐためにポート開放は最小限にする必要があります。 もし不要なポートが開いている場合は、関連するデーモンを終了させるなどしてポートを閉じます。

      現在開いているポート番号を確認するコマンドはssnetstatなどが挙げられます。

      # ss -t
      State Recv-Q Send-Q Local Address:Port Peer Address:Port Process
      ESTAB 0 52 XXX.XXX.XXX.XXX:ssh XXX.XXX.XXX.XXX:59129

      # netstat -ntl
      ss -t
      Active Internet connections (only servers)
      Proto Recv-Q Send-Q Local Address Foreign Address State
      tcp 0 0 0.0.0.0:22 0.0.0.0:* LISTEN
      tcp6 0 0 :::22 :::* LISTEN
      State Recv-Q Send-Q Local Address:Port Peer Address:Port Process
      ESTAB 0 588 XXX.XXX.XXX.XXX:ssh XXX.XXX.XXX.XXX:59129

      まとめ

      今回はパケットフィルタリングで以下を説明しました。

      • パケットフィルタリングとはファイアウォールでパケットを制御する処理
      • iptables
        • netfilterの管理インターフェース
        • テーブル・チェイン・ルールで構成されてる
        • テーブルはiptablesで実現する操作を定義
        • チェインはパケット操作を実行する場所(タイミング)を定義
        • ルールはパケットの処理方法を定義
      • firewalld
        • 裏側ではiptablesのようなインターフェースが動いてる
        • ゾーン単位で制御することで管理が楽

      次回の記事では権限の制御について執筆予定です。ぜひそちらも御覧ください!

       

      【参考】

      IPTABLES

      iptablesの仕組みを図解

      iptablesファイアウォールルールを一覧表示および削除する方法

      第12回:もう怖くない!ファイアーウォール(iptables)

      iptablesはDROPすべきか、REJECTか。tcp-resetという手も