iptables まとめ

# iptables とは
* ~~平たく言うとLinuxに標準で搭載されているFirewallですよね？~~
* CentOSに標準で搭載されているFirewallですか！！~~（CentOS7の標準はFirewalld）~~
* Firewalldはiptablesを管理するフロントエンドのようですね！？

# 環境
* CentOS6.6
* iptables 1.4.7

# 経緯
* 今まで`iptables`ちゃんといじったことなかったのでこれを機に整理しようと一念発起！

# アジェンダ
* 書式について
* テーブルについて
* チェインについて
* コマンドについて
* パラメータについて
* 「-j」で指定するターゲットについて
* 拡張パラメータについて
 - 「-p」オプションによって（暗示的に）呼び出されるタイプ
 - 「-m」オプションを付けることで（明示的に）呼び出されるタイプ
* ポリシーについて
* 設定の確認方法

# `iptables` まとめ
## 書式について

```shell-session:iptables書式
[root@centos6 ~]# iptables [-t テーブル] コマンド [マッチ] [ターゲット/ジャンプ]
```

## テーブルについて
* iptablesではパケットを、4つのテーブルに分けて、それぞれのタイミングで制御します。
* テーブルには「**filterテーブル**」「**natテーブル**」「**mangleテーブル**」「**rawテーブル**」があります。

### **filterテーブル**
filterテーブルではパケットの通過や遮断といった制御をします。
通常ほとんどの設定はこのテーブルに記述します。
下の例にあるように、設定ファイルを直接編集する際は、行頭に「*（アスタリスク）」を付けて、最後は「COMMIT」で指定。その間に書かれた設定がfilterテーブルのルールとなります。

```shell-session:/etc/sysconfig/iptables
*filter
 #ここにfilter関係の記述
COMMIT
```

```shell-session:【Ex1】コマンドでfilterテーブルにポート80のパケットを破棄するルールを追加する
[root@centos6 ~]# iptables -t filter -p tcp --dport 80 -j -DROP
```

```shell-session:【Ex2】filterテーブルはデフォルトのため省略可能
[root@centos6 ~]# iptables -p tcp --dport 80 -j -DROP
```

### **natテーブル**
NAT（ネットワークアドレス変換機能）を担当します。
送信先や送信元といったパケットの中身を書き換える際に利用します。
各通信をローカルネットワーク上のサーバへ振り分けるルーターとして機能させることができます。

```shell-session:/etc/sysconfig/iptables
*nat
 #ここにnat関係の記述
COMMIT
```

```shell-session:【Ex1】IPマスカレードの指定
[root@centos6 ~]# iptables -t nat -A POSTROUTING -s 192.168.1.0/24 -j MASQUERADE
```

### **mangleテーブル**
TOS（Type Of Service）フィールド等の値を書き換えます。
TOSはパケット処理の優先度付けを行い、通信品質を制御する際に利用されます。
また特定の通信マークを置き換える事もできます。

```shell-session:/etc/sysconfig/iptables
*mangle
 #ここにmangle関係の記述
COMMIT
```

```shell-session:【Ex1】ポート80の通信のTOSを高スループットのものへ書き換え
[root@centos6 ~]# iptables -t mangle -A PREROUTING -p tcp --dport 80 -j TOS --set-tos Maximize-Throughput
```

### **Rawテーブル**

特殊なテーブルとしてRawテーブルというものも存在します。
用途はmangleテーブルのように特定のパケットにマークを付けることですが、Rawテーブルでは追跡を除外するようマークを付けます。
つまり、特定の通信をファイアウォールで処理せずに他の機材へ通したりといった経路制御する場合に利用します。

例えば通信が1秒間に数千といった高負荷の場合、全ての通信を1台のサーバで扱うことが難しくなります。

高負荷の原因がDNSサーバへの問い合わせだったと仮定します。
負荷分散のために「DNSのパケットに関しては、別サーバで処理させたい」そのような際に、
ポート53の通信にNOTRACKマークを付けます。

するとiptablesはNOTRACKマークの付いたパケットを、記録したり処理をせずに、別のサーバへ通します。
そうすることで、DNSの問い合わせを行うサーバと、それ以外の通信を処理するサーバに分けることができます。

```shell-session:/etc/sysconfig/iptables
*raw
 #ここにraw関係の記述
COMMIT
```

```shell-session:【Ex1】ポート53のUDPを通ったパケットの受信時と送信時にNOTRACKマークを付ける
[root@centos6 ~]# iptables -t raw -I PREROUTING -p udp --dport 53 -j NOTRACK
[root@centos6 ~]# iptables -t raw -I OUTPUT -p udp --dport 53 -j NOTRACK
```


## チェインについて
### チェインの種類

|種類|説明|
|:---|:---|
|INPUT|入力（受信）に対するチェイン|
|OUTPUT|出力（送信）に対するチェイン|
|FORWARD|フォワード（転送）に対するチェイン|
|PREROUTING|受信時に宛先アドレスを変換するチェイン。<br>タイミングとしてはfilterで適用されるルールより手前。|
|POSTROUTING|送信時に送信元アドレスを変換するチェイン。<br>これもfilterの後でパケットが送信される直前。|

### テーブルとチェインの対応表

|テーブル|対応するチェイン|
|:---|:---|
|filterテーブル|INPUT、OUTPUT、FORWARD|
|natテーブル|POSTROUTING、PREROUTING、OUTPUT|
|mangleテーブル|POSTROUTING、PREROUTING、INPUT、OUTPUT、FORWARD|
|Rawテーブル|PREROUTING、OUTPUT|

## コマンドについて
### よく使うコマンド

|指定方法|内容|
|:---|:---|
|-A（--append）|指定チェインに1つ以上の新しいルールを追加|
|-D（--delete）|指定チェインから1つ以上のルールを削除|
|-P（--policy）|指定チェインのポリシーを指定したターゲットに設定|
|-N（--new-chain）|新しいユーザー定義チェインを作成|
|-X（--delete-chain）|指定ユーザー定義チェインを削除|
|-I（--insert）|指定したチェーンにルール番号を指定してルールを挿入する。<br>（ルール番号を省略した際にはルール番号は1に設定され、チェーンの先頭に挿入される。）|

## パラメータについて
### よく使うパラメータ
|指定方法|内容|
|:---|:---|
|-s (--source)|パケットの送信元を指定。特定のIP（192.168.0.1）や範囲（192.168.0.0/24）を指定する。|
|-d (--destination)|パケットの宛先を指定。指定方法は-sと同じ。|
|-p (--protocol)|チェックされるパケットのプロトコル。 指定できるプロトコルは、 tcp、udp、icmp、allのいずれか1つか、数値。|
|-i (--in-interface)|パケットを受信することになるインターフェース名。eth0、eth1など。|
|-o (--out-interface)|送信先インターフェース名を指定。|
|-j (--jump)|ターゲット（ACCEPT、DROP、REJECT）を指定|

## 「-j」で指定するターゲットについて
### ターゲットの一覧
|指定方法|内容|
|:---|:---|
|ACCEPT|パケットの通過を許可|
|DROP|パケットを破棄。応答を返さない。|
|REJECT|パケットを拒否し、ICMPメッセージを返信|
|REDIRECT|特定ポートにリダイレクト|
|LOG|マッチしたパケットのログを記録|


## 拡張パラメータについて
### 「-p」オプションによって（暗示的に）呼び出されるタイプ

|指定方法|内容|
|:---|:---|
|--sport|Source Port。送信側（クライアント側）のポート番号を指定。-p tcp か -p udp の後に指定します。|
|--dport|Destination Port。受信側（サーバ側）のポート番号を指定-p tcp か -p udp の後に指定します。|
|--tcp-flags|TCP のときだけ指定することができる。<br>第1引数に評価されるTCPフラグを指定し、第2引数に設定されていなければならないフラグを指定します。<br>指定可能なフラグは、SYN、ACK、FIN、RST、URG、PSH、ALL、NONE です。<br>複数指定する場合はカンマで区切り、引数の間は半角スペースで区切ります。<br>（--tcp-flags SYN,RST,ACK SYN）|
|--syn|TCP のときだけ指定することができる。SYNビットがセットされた、<br>いわゆるTCPの接続確立時に、正規のスリーハンドシェイク手順を踏んだ通信を指定します。<br>上記のSYN,RST,ACK SYNの省略形。|
|--icmp-type|ICMP のタイプを指定。pingに限定した指定をする際などに指定します。|

##### コマンド例
```shell-session:【Ex1】ポート80で受信したTCPの受信パケットを破棄
[root@centos6 ~]# iptables -A INPUT -p tcp --dport 80 -j DROP
```

```shell-session:【Ex2】ポート80で受信したTCPかつ、SYN、RST、ACKのうちSYNフラグだけを持った受信パケットを許可
[root@centos6 ~]# iptables -A INPUT -p --tcp-flags SYN,RST,ACK SYN --dport 80 -j ACCEPT
```

### 「-m」オプションを付けることで（明示的に）呼び出されるタイプ
#### **リミット拡張モジュール**

|指定方法|内容|
|:---|:---|
|limit|リミット拡張モジュールを読み込み。|
|--limit|時間あたりに何パケットまで許可するかを指定する。<br>second（秒）、minute（分）、hour（時）、day（日）を指定することができます。<br>--limit の初期値は 3/hour|
|--limit-burst|上記のリミットが有効になる通信の回数を指定。<br>「○回受信したら1時間に1回に制限」という際の「○回」の部分を指定する。<br>初期値は5。|

##### コマンド例
```shell-session:【Ex1】TCPのポート80宛の受信パケットを、ハッシュリミットで5回まで無条件で受け入れ、それ以上のパケットを1分間に1度だけ許可する
[root@centos6 ~]# iptables -A INPUT -p tcp --dport 80 -m hashlimit --hashlimit-burst 5 --hashlimit 1/m --hashlimit-mode srcip -j ACCEPT
```

#### **length拡張モジュール**

|指定方法|内容|
|:---|:---|
|length|length拡張モジュールを読み込み。パケットのサイズをフラグとしてマッチさせることができる。|
|--length|「○:○」という書式で「前半の○から、後半の○サイズまで」と指定する。<br>後半の指定を外せば○以上、前半の指定を外せば○以下という指定も可能。|

##### コマンド例
```shell-session:【Ex1】85から65535バイトまで一致
[root@centos6 ~]# iptables -A INPUT -p tcp --dport 80 -m length --length 85:65535
```

```shell-session:【Ex2】85バイト以下に一致
[root@centos6 ~]# iptables -A INPUT -p tcp --dport 80 -m length --length :85
```

#### **state拡張モジュール**

|指定方法|内容|
|:---|:---|
|state|state拡張モジュールを読み込み。<br>パケットを追跡することでステートフル・パケットインスペクションが可能になります。|
|--state|追跡しているパケットの状態を指定。新規か、既に許可をしたものか、などを指定する。|

#### **state拡張で指定可能なパラメータ**

|指定方法|内容|
|:---|:---|
|NEW|全くの新参の接続|
|ESTABLISHED|既に許可された接続|
|RELATED|新参ではあるが許可された接続|
|INVALID|パラメータの不明な無効な接続|

##### コマンド例
```shell-session:【Ex1】filterテーブルの受信はすべて破棄。送信はすべて許可
[root@centos6 ~]# iptables -A INPUT -p tcp -m state --state NEW -j DROP
```

## ポリシーについて
### ポリシーとは
ポリシーとは**チェイン全体に適用されるルール**のことです。
ポリシーの設定は「-P」オプションを使って記述します。

### ポリシーの適応パターン
* **ポリシーでは2つのパターンが考えられる**
 1. 全て拒否してから特定の通信だけ許可する場合。許可するポートが少ない場合に向いています。
 2. 全て許可してから特定の通信だけ拒否する場合。拒否するポートが少ない場合に向いています。

### コマンド例
**ほとんどの場合、INPUTチェインに関しては安全性を考えて1番の「拒否してから許可」で運用します。**

```shell-session:【Ex1】TCPの受信パケットの内、新規の接続に関しては破棄
[root@centos6 ~]# iptables -t filter -P INPUT DROP
[root@centos6 ~]# iptables -t filter -P OUTPUT ACCEPT
```

ポリシーはその後のルールも適応されるため、後に記述するルールで上書きすることができます。

```shell-session:【Ex2】ポリシーでINPUT全体を破棄した後に、ポート80を許可する
[root@centos6 ~]# iptables -P INPUT DROP
[root@centos6 ~]# iptables -A INPUT -m --dport 80 -j ACCEPT
```

## 設定の確認方法
### 書式
```shell-session:iptables設定確認コマンド書式
[root@centos6 ~]# iptables [サブコマンド] [パラメータ]
```

### サブコマンド
|指定方法|内容|
|:---|:---|
|-L, --list [CHAIN]|チェインCHAIN（省略した場合はすべて）のルールを一覧表示する|

### パラメータ
|指定方法|内容|
|:---|:---|
|-v, --verbose|詳細に出力する|
|-n, --numeric|名前解決せずIPアドレスやポートを数値で出力する|
|-x, --exact|正確な数値を表示する|



# 参考
[こちら](http://oxynotes.com/?p=6361)と[こちら](http://itpro.nikkeibp.co.jp/article/COLUMN/20140512/556022/)を参考にさせていただきました。
奥が深すぎてついていけません！