iptablesによるファイアウォール
iptables とは、パケットフィルタを行うソフトウェアです。外部から来るデータ(パケット)や、外部へ出るパケットを検査し、通過を許可・拒否したり、NAT(アドレス変換)を実現する事が可能です。パケット通過の許可・拒否を適切に設定してやる事により、ファイヤウォールとして活用する事が出来ます。Linuxマシンをルータとして使用する時によく使用されます。
ファイヤーウォールとは、外部から侵入されるのを防ぐ為のシステムです。悪意ある接続(インターネットなどの外部ネットワークを通じて第三者が侵入し、データやプログラムの盗み見・改ざん・破壊などが行なわれることや、ワームなどの感染)から守るために外部との境界を流れるデータを監視し、不正なアクセスを検出・遮断することができます。
市販のルータを使えばファイアウォールは標準で組み込まれているでしょうが、有って困ることも無いでしょうし、よりセキュアな環境を構築する為、あえてサーバにも組み込みます。
※よりセキュアな環境を構築したいならば「SELinux」を利用する事をおすすめします。
iptablesの概要
iptablesでは、IPパケットをどのように処理するかを決めるルールのかたまりを「チェイン」と呼び、パケットを処理するタイミングによって5つのチェインに分けられます。
【チェイン】
| チェイン | 説明 |
| PREROUTING | 自ホストに届いたパケットを最初に処理するチェイン |
| INPUT | 最終的なパケットの受け取り先である場合に処理するチェイン |
| OUTPUT | 自ホストから発せられたパケットを処理するチェイン |
| FORWARD | 転送するパケットを処理するチェイン |
| POSTROUTING | 自ホストから出ていくパケットを最後に処理するチェイン |
ちなみに、これらのチェインを「組み込みチェイン」と呼び、ユーザが自分で定義するチェインを「ユーザ定義チェイン」と呼びます。
iptablesで処理されるパケットは以下の3種類に分けられ、それぞれ処理されるチェインが異なります。
(1) 自ホストのプロセスから他ホストへと送信されるパケット
[PREROUTING]→[OUTPUT]→[POSTROUTING]
(2) 他ホストから自ホストへと送信されてきたパケット
[PREROUTING]→[INPUT]→[POSTROUTING]
(3) 他ホストから別の他ホストへと転送されるパケット
[PREROUTING]→[FORWARD]→[POSTROUTING]
パケットの処理において、処理の目的別に3つに分けられ、コレを「テーブル」と呼びます。
【テーブル】
| テーブル | 対象チェイン | 説明 |
| filter | INPUT,FORWARD,OUTPUT | 通常のパケットフィルタリング |
| nat | PREROUTING,POSTROUTING,OUTPUT | アドレス変換 |
| mangle | PREROUTING,OUTPUT | 特殊なパケット変換 |
また、パケットの処理方法を「ターゲット」と呼び、いくつか種類が有りまが、ここではファイアウォールで使用されるモノを抜粋して紹介します。
【ターゲット】
| ターゲット | 説明 |
| ACCEPT | パケットを許可し、受け入れる |
| DROP | パケットを無視し、破棄する |
| REDIRECT | パケットの宛先アドレスを自ホストに書き換え、指定したポートに転送する |
| REJECT | パケットを拒否し、送信元にICMPパケットを送信する |
| RETURN | そのチェインの以降のルールを評価せず、終了する |
各チェインには、組み込みチェインやユーザ定義チェインにおいて、ルールの評価を停止するターゲットが存在しない場合の処理方法、つまりデフォルトのターゲットを指定でき、これを「ポリシー」と呼びます。ポリシーに設定可能なターゲットはACCEPTとDROPです。
iptablesの設定
1,現在の(デフォルト)ルールの確認
# iptables -L
@
Chain INPUT (Policy DROP)
target prot opt source destination
A
Chain FORWARD (Policy DROP)
target prot opt source destination
B
Chain OUTPUT (Policy ACCEPT)
target prot opt source destination
|
@INPUT(入ってくるパケット)についての条件
AFORWARD(転送するパケット)についての条件
BOUTPUT(出て行くパケット)についての条件
各チェインの()内にある、Policy [ACCEPT / DROP] は基本的なポリシーを定義しています。
2,基本ポリシー設定
上記の例では、外部からのパケット(INPUT)を一切拒否(DROP)してしまいますので、一時的にACCEPT(許可)にします。
FORWARD(転送)は使いませんので、DROP(拒否)、OUTPUT(出て行くパケット)は全面的に許可(ACCEPT)するように基本ポリシーを設定します。
# iptables -P INPUT ACCEPT @
# iptables -P FORWARD DROP A
# iptables -P OUTPUT ACCEPT B
|
@入ってくるパケットを(一時的に)全面的に許可
A転送するパケットは(使わないので)全面的に拒否
B出て行くパケットは全面的に許可
3,個別ルールの削除
個別に通過させるパケットを設定する前に、余計な設定があるといけませんので、一応個別のルールを全て削除します。
4,個別ルールの全体的な設定
まずは全体的な設定として、icpm( ping )、tcp 、udp を許可します。
これは、全てのポートを許可するというワケではありません。最終的にどのポートを許可(もしくは拒否)するかは、個別に設定しなければなりません。
# iptables -A INPUT -p icmp -j ACCEPT
# iptables -A INPUT -p tcp -j ACCEPT
# iptables -A INPUT -p udp -j ACCEPT
|
5,個別ルールの詳細な設定
自分自身からの入力を全面的に許可します。
# iptables -A INPUT -i lo -j ACCEPT
|
プロトコル毎に個別の設定を行います。
@
# iptables -A INPUT -p tcp --dport 80 -j ACCEPT
# iptables -A INPUT -p tcp --sport 80 -j ACCEPT
A
# iptables -A INPUT -p tcp --dport 20 -j ACCEPT
# iptables -A INPUT -p tcp --sport 20 -j ACCEPT
# iptables -A INPUT -p tcp --dport 21 -j ACCEPT
# iptables -A INPUT -p tcp --sport 21 -j ACCEPT
B
# iptables -A INPUT -p tcp --dport 110 -j ACCEPT
# iptables -A INPUT -p tcp --sport 110 -j ACCEPT
C
# iptables -A INPUT -p tcp --dport 25 -j ACCEPT
# iptables -A INPUT -p tcp --sport 25 -j ACCEPT
D
# iptables -A INPUT -s 192.168.0.0/24 -p tcp --dport 10000 -j ACCEPT
# iptables -A INPUT -s 192.168.0.0/24 -p tcp --sport 10000 -j ACCEPT
E
# iptables -A INPUT -s 192.168.0.3 -p tcp --dport 22 -j ACCEPT
# iptables -A INPUT -s 192.168.0.3 -p tcp --sport 22 -j ACCEPT
F
# iptables -A INPUT -p tcp --dport 53 -j ACCEPT
# iptables -A INPUT -p tcp --sport 53 -j ACCEPT
# iptables -A INPUT -p udp --dport 53 -j ACCEPT
# iptables -A INPUT -p udp --sport 53 -j ACCEPT
|
@Web ( 80 番 )の通過を許可
AFTP ( 20 番と 21 番 )の通過を許可
BPOP ( 110 番 )の通過を許可
CSMTP ( 25 番 )の通過を許可
D特定のネットワークアドレスを持つホストからのみWebmin の接続を許可(Webminのポート:10000)
E特定のホストからのアクセスしか認めない( SSH:22番ポート )
FDNSサーバの運用がある場合
攻撃への対処
※syn 信号を大量に送信されたり(synフラッド)、PINGを大量に送信されると、Linux はフリーズしてしまうらしいです。そのフリーズを回避する為に、syn 信号や PING は1秒に1回だけ受信する様に設定します。
# iptables -A INPUT -i ppp+ -p tcp --syn -m limit --limit 1/s -j ACCEPT
# iptables -A INPUT -i ppp+ -p icmp --icmp-type echo-request -m limit --limit 1/s -j ACCEPT
|
6,個別ルールの削除方法
個別に設定したルールが間違っていた場合や、変更したい場合など、設定したルールを消す事も可能です。方法としては上記で個別に追加したコマンドの「-A」オプションを「-F」へと変更するだけです。
例えば、SSHに対してのルールを削除する場合は以下の様に行います。
# iptables -F INPUT -s 192.168.0.3 -p tcp --dport 22 -j ACCEPT
# iptables -F INPUT -s 192.168.0.3 -p tcp --sport 22 -j ACCEPT
|
7,基本ルールの再定義
個別に設定したルール以外の INPUT は全て拒否する為に、2,(基本ポリシー設定)で設定したINPUTチェインをACCEPT(全面的に許可)からDROP(拒否)に変更します。
iptablesの運用
設定を保存し、iptablesを再起動します。
入力した個別のルールも、このままではサーバ機を再起動すると消えてしまいます。サーバ機の起動の度にルールを入力するのは面倒なので、以下のコマンドで設定を保存します。
# /etc/init.d/iptables save
現在のルールを/etc/sysconfig/iptablesに保存中: [ OK ]
保存出来たら、iptables を再起動します。
# service iptables restart
現在のすべてのルールとユーザ定義チェインを初期化中: [ OK ]
現在のすべてのルールとユーザ定義チェインを破棄中: [ OK ]
iptablesファイアウォールルールを適用中: [ OK ]
[ OK ]
|
以上でパケットフィルタが可能になりましたが、「絶対に侵入されない」訳では有りません。定期的にセキュリティポリシーの見直しを行うなど、常に「現時点で考えうる最高のセキュリティ環境」を意識する事が大切です。
iptablesコマンド
○iptablesコマンドの主なオプション
iptables -L [-v]
現在の設定を確認
「-v」オプションを合わせて指定することで、パケットカウンタ、バイトカウンタの値を表示できる
iptables -P <チェイン> <ターゲット>
指定チェインのポリシーを設定
iptables -A <チェイン> <条件> -j <ターゲット>
指定チェインへに個別のルールを追加する
iptables -F <チェイン> [<条件> -j <ターゲット>]
指定チェイン内の全てのルールを削除
チェイン指定を省略すると全てのルールを削除
条件を指定した場合は個別ルールの削除
iptables -X <チェイン>
ユーザ定義チェインを削除
iptables -N <チェイン>
ユーザ定義チェインを作成
iptables -E <旧チェイン> <新チェイン>
チェイン名の変更
iptables -D <チェイン> <ルール番号>
チェイン内のルールを番号指定で削除
iptables -Z <チェイン>
チェイン内のバイトカウンタ、パケットカウンタの値をクリア
○チェインの種類
| チェイン | 説明 |
| PREROUTING | 自ホストに届いたパケットを最初に処理するチェイン |
| INPUT | 最終的なパケットの受け取り先である場合に処理するチェイン |
| OUTPUT | 自ホストから発せられたパケットを処理するチェイン |
| FORWARD | 転送するパケットを処理するチェイン |
| POSTROUTING | 自ホストから出ていくパケットを最後に処理するチェイン |
○ターゲットの種類
| ターゲット | 説明 |
| ACCEPT | パケットを許可し、受け入れる |
| DROP | パケットを無視し、破棄する |
| REDIRECT | パケットの宛先アドレスを自ホストに書き換え、指定したポートに転送する |
| REJECT | パケットを拒否し、送信元にICMPパケットを送信する |
| RETURN | そのチェインの以降のルールを評価せず、終了する |
○条件を設定するための基本的なオプション
| -p <プロトコル> | プロトコルの種類。tcp、udp、icmp、allのいずれか |
| -s | 送信元のIPアドレス |
| -d | 送信先のIPアドレス |
| -i <インターフェイス名> | 入力インターフェイス名。INPUT、FORWARD、PREROUTINGのみ指定可能 |
| -o <インターフェイス名> | 出力インターフェイス名。OUTPUT、FORWARD、POSTROUTINGのみ指定可能 |
| -f | フラグメントパケット(分割されたパケットの2番目以降のパケット) |
| --syn | シンクパケット(コネクションの開始時に送信されるパケット)。tcpプロトコルのみ指定可能 |
| --sport <ポート番号> | 送信元のポート番号。tcp、udpプロトコルのみ指定可能 |
| --dport <ポート番号> | 送信先のポート番号。tcp、udpプロトコルのみ指定可能 |
| -m state --state <ステート> | コネクションの状態。INVALID(不当な接続)、ESTABLISHED(確立済みのコネクション)、NEW(新しいコネクション)、RELATED(新しいコネクションだが、FTPデータ転送やICMPエラーのように既存の接続に関係している) |