Linuxのパケットフィルタリングツール

# はじめに
本記事ではLinuxで使用可能なパケットフィルタリングツールについて記載しています。
環境はCentOS7を例に解説しています。

## ebtables
ebtablesはEthernetフレームのルールを設定するためのツールです。
ebtablesではiptablesと同様に「テーブル」、「チェイン」、「ターゲット」を用いてルールを設定します。

| テーブル       |概要        |使用可能なチェイン        |
|:-----------------|:------------------|:------------------|
| filter           |Ethernetフレームのフィルタリング|INPUT、OUTPUT、FORWARD|
| nat              |MACアドレスの変更|PREROUTING、OUTPUT、POSTROUTING|
| broute           |ブリッジとルータ機能|BROUTING|

- ルールの追加  
`# ebtables -t broute -A BROUTING -p IPv6 -j ACCEPT`
- brouteテーブルのチェインを表示  
`# ebtables -t broute -L`

```console
Bridge table: broute

Bridge chain: BROUTING, entries: 2, policy: ACCEPT
-j BROUTING_direct
-p IPv6 -j ACCEPT 

Bridge chain: BROUTING_direct, entries: 1, policy: ACCEPT
-j RETURN 
```

- brouteテーブルのチェインを表示（パケットバイトカウントも表示）  
`# ebtables -t broute -L --Lc`

```console
Bridge table: broute

Bridge chain: BROUTING, entries: 2, policy: ACCEPT
-j BROUTING_direct, pcnt = 0 -- bcnt = 0
-p IPv6 -j ACCEPT , pcnt = 0 -- bcnt = 0

Bridge chain: BROUTING_direct, entries: 1, policy: ACCEPT
-j RETURN , pcnt = 0 -- bcnt = 0
```

## iptables
Linuxのパケットフィルタリングは、Linuxカーネル内のNetfilterにより行われています。

Centos7以降ではFirewalldが使用されていますが、Firewalldの中でiptablesを呼び出し、Netfilterを動作させるための設定を行っています。本記事ではiptablesについて記載しています。

iptablesはLinuxカーネルのパケットフィルタルールを設定するためのツールです。
IPv6の場合はip6tablesを使用します。

iptablesは「テーブル」、「チェイン」、「ターゲット」を用いてルールを設定します。

| テーブル       |概要        |使用可能なチェイン        |
|:-----------------|:------------------|:------------------|
| filter           |パケットのフィルタリング|INPUT、OUTPUT、FORWARD|
| nat              |パケット変換|PREROUTING、OUTPUT、POSTROUTING|
| mangle（※）           |IPヘッダ書き換え|PREROUTING、INPUT、OUTPUT、FORWARD、POSTROUTING|
（※）カーネル 2.4.18 からは、INPUT、 FORWARD、 POSTROUTINGの3つの組み込みチェインをサポートしています。

CentOS7ではfirewalldがデフォルトになっているため、iptablesをサービスとして使用したい場合は、iptables-servicesをインストールする必要があります。なお、firewalldとiptablesの共存はできません。

- iptables-servicesのインストール   
`# yum -y install iptables-services`
- 外部から80へのアクセスを許可する設定   
`# iptables -A INPUT -p tcp --dport 80 -j ACCEPT`
- 特定のネットワークからのアクセスを破棄する設定  
`# iptables -A INPUT -s 10.0.0.0/8 -j DROP`
- 特定のIPアドレスから22に対するアクセスを許可する設定   
`# iptables -A INPUT -s 192.168.0.2 -p tcp --dport 22 -j ACCEPT`
- 内部のトラフィックを外部にマスカレードする設定   
`#  iptables -t nat -A POSTROUTING -s 192.168.0.0/24 -o enp0s8 -j MASQUERADE`
- 外部からネットワネットワークに対するアクセスを特定のアドレスにマスカレードする設定  
`# iptables -t nat -A PREROUTING -d 192.168.0/24 -i enp0s8 -j DNAT --to 192.168.10.2`

iptablesで設定したルールはOS再起動を行うと、消失してしまいます。
iptablesの設定をファイルへ保存するには、`iptables-save`コマンドで保存します。

- iptablesのバックアップ  
`# iptables-save > iptables.backup`
- iptablesのリストア  
`# iptables-restore < iptables.backup`

サーバ起動時にiptablesのサービスと、iptablesのルールを記載したスクリプトを起動することでフィルタリングの自動起動ができます。

## ipset
ipsetはIPアドレスをグループでまとめて管理するためのツールです。

- セットの作成 
`# ipset create mynetwork hash:net`

- ネットワークの登録 
`# ipset add mynetwork 10.0.0.0/24`

- 登録内容の確認
`# ipset list mynetwork`

```console
Name: mynetwork
Type: hash:net
Revision: 6
Header: family inet hashsize 1024 maxelem 65536
Size in memory: 440
References: 0
Number of entries: 1
Members:
10.0.0.0/24
```

- iptablesへの追加   
`# iptables -I INPUT -m set --match-set mynetwork src -j ACCEPT`
- iptablesの確認   
`# iptables -t filter -L`

```console
Chain INPUT (policy ACCEPT)
target     prot opt source               destination         
ACCEPT     all  --  anywhere             anywhere             match-set mynetwork src
```

ipsetで設定したルールはOS再起動を行うと、消失してしまいます。
そのため、永続的な設定を行う場合は以下のコマンドを実行し、ルールを出力してサービス化する必要があります。

- ルールの保存  
`# ipset save > /etc/ipset.conf`

ipsetのルールを削除する場合は、一度firewallのサービスを停止して以下のコマンドを実行すると削除できます。

- firewallの停止  
`# systemctl stop firewalld`
- ルールの削除  
`# ipset destroy`
- ルールの確認   
`# ipset list`

リストは以下のコマンドで実行できます。

- ipsetのリストア   
`# ipset restore < /etc/ipset.conf`

（※）入力で読み込むファイルは`ipset save`コマンドで出力したファイルを指定


## nft
nftはカーネル3.13以降に追加されたiptablesに変わるパケットフィルタリング機能です。
CentOSの場合は以下のコマンドでインストールできます。

- nftのインストール   
`# yum install -y nftables`

iptablesに比べるとパフォーマンスが向上しています。なお、iptablesと変わってテーブルやチェインをデフォルトで持たないため、自分で作成する必要があります。

nftを利用する場合は以下の手順で設定します。

1. テーブルの作成
2. チェインの作成
3. ルールの作成

- テーブルの作成 
`# nft add table ip mynetwork`

- チェインの作成 
`# nft add chain ip mynetwork localchain { type filter hook input priority 0 \; }`

- ルールの作成 
`# nft add rule ip mynetwork localchain tcp dport 22 accept`

- ルールの確認 
`# nft list ruleset`

```console
table ip TESTTABLE {
	chain testchain {
		type filter hook input priority 0; policy accept;
		tcp dport ssh accept
	}
}
table ip mynetwork {
	chain localchain {
		type filter hook input priority 0; policy accept;
		tcp dport ssh accept
	}
}
```

# おわりに
クラウドが浸透した今、Linuxのパケットフィルタリングを使う機会は減っていますが、システム管理者には必要な知識です。