個々の事項についてのもっと詳しい説明が必要なら、iptables にはかなり
詳しいマニュアルページ(man iptables
)があります。
ipchains に精通している人はすぐにでも
iptables と ipchains の違いを見たいにちがいありません。実際、
2つはとても似ています。
iptables
を使って色々なことができます。
まず、3つの組み込み済みチェイン INPUT
, OUTPUT
そして FORWARD
(これらは削除できません)から始めます。
では、チェインを扱う操作を見てみましょう:
チェイン内のルールを操作するには様々な方法があります:
iptables はたぶんモジュールになっています。名前は(`iptable_filter.o')
で、最初に iptables
を実行したときに自動的に
ロードされるはずです。また、カーネルに恒常的に組み込むこともできます。
全く iptables コマンドを実行していない状態では(注意しましょう: 初期化スクリプトで iptables を実行するディストリビューションがあります)、 組み込み済みチェイン(`INPUT', `FORWARD' および `OUTPUT')のどれにも ルールは存在せず、全てのチェインのポリシーは ACCEPT です。 しかし、iptable_filter モジュールのオプションに `forward=0' を与えれば、 FORWARD チェインのポリシーの初期値を(訳注: DROP に)変えることができます。
ルールを操作すること ― それはパケットフィルタリングの基本です。 ほとんどの場合、普通、あなたは追加 (-A) と削除 (-D) コマンドを使うこと になるでしょう。残りのコマンド(挿入の -I と置換の -R )はこれらの概念を 単純に延長したものです。
各々のルールには、パケットが満たすべき条件のセットと、条件が満たされた ときにすること(‘ターゲット’)を指定します。例えば、IP アドレス 127.0.0.1 からやって来る全ての ICMP パケットを破棄したいとします。その場合の条件は プロトコルが ICMP でソースアドレスが 127.0.0.1 で、ターゲットは `DROP' です。
127.0.0.1 は‘ループバック’インターフェイスで、それはあなたのマシンが 実際のネットワークに繋がっていなくても存在します。`ping' プログラムは そのようなパケットを発生させるのに使います(ping は 単純に ICMP タイプ 8 (エコー要求)を送り、全ての協力的なホストは親切にも ICMP タイプ 0 (エコー応答)のパケットでそれに応えます)。これはテストに役立ちます。
# ping -c 1 127.0.0.1
PING 127.0.0.1 (127.0.0.1): 56 data bytes
64 bytes from 127.0.0.1: icmp_seq=0 ttl=64 time=0.2 ms
--- 127.0.0.1 ping statistics ---
1 packets transmitted, 1 packets received, 0% packet loss
round-trip min/avg/max = 0.2/0.2/0.2 ms
# iptables -A INPUT -s 127.0.0.1 -p icmp -j DROP
# ping -c 1 127.0.0.1
PING 127.0.0.1 (127.0.0.1): 56 data bytes
--- 127.0.0.1 ping statistics ---
1 packets transmitted, 0 packets received, 100% packet loss
#
ご覧のとおり最初の ping が成功しています(`-c 1' は ping にパケットを 1個だけ送るように指示しています)。
次にルールを `INPUT' チェインに追加 (-A) します。ルールの指定は、 127.0.0.1 から (`-s 127.0.0.1') でプロトコル ICMP (`-p icmp') のパケットは、DROP へジャンプする (`-j DROP') です。
それから 2番目の ping でルールをテストします。帰って来ない応答を待つのを ping が止めるまで少しの間があるでしょう。
ルールを削除するには 2通りの方法があります。1番目は、例えば、input チェインにはルールが 1個だけしかないのを分っている場合では、番号を 使って以下のように削除できます:
# iptables -D INPUT 1
#
INPUT チェインのルール番号 1 を削除。
2番目の方法は -A コマンドをそっくり写して -A を -D に置き換えたものです。 これはルールが複雑なチェインの場合で、例えば、取り除きたいのがルール 37 だと探し当てるためにルールを数えたくない場合に有効です。この場合、 次のように使います:
# iptables -D INPUT -s 127.0.0.1 -p icmp -j DROP
#
-D の書き方は、-A (または -I か -R) コマンドのときと正確に同じ
オプションでなければなりません。もし、同一チェイン中に複数のマッチ
するルールがあったら、最初のだけが削除されます。
これまでに、プロトコルを指定する `-p' オプションと、ソースアドレスを 指定する `-s' オプションを見てきましたが、この他にもパケットの特徴を 指定する様々なオプションがあります。これから、その概要をあますところなく お話します。
ソース(`-s', `--source' または `--src') および、あて先(`-d', `--destination' または `--dst') IP アドレスは 4通りの指定方法が あります。もっとも一般的な方法は完全に記述された名前(FQDN)を使うことで、 例えば、`localhost' とか `www.linuxhq.com' です。2番目の方法は `127.0.0.1' のような IP アドレスを指定する方法です。
3番目と 4番目の方法は IP アドレスのグループを指定する方法で、 `199.95.207.0/24' とか `199.95.207.0/255.255.255.0' のように書きます。 両方とも 199.95.207.0 から 199.95.207.255 までのどの IP アドレスも 含まれる指定で、数字のあとの `/' は IP アドレスのどの部分まで有効かを 示しています。省略時は `/32' または `/255.255.255.255' (IP アドレスの 完全一致)です。どんな IP アドレスでもよい場合は、以下のように `/0' が 使えます:
[ 注記: `-s 0/0' はここでは冗長です。]
# iptables -A INPUT -s 0/0 -j DROP
#
上記の効果は `-s' オプションを指定しないのと全く同じなので、 こんな使い方はめったにしません。
`-s' (または `--source') や `-d' (`--destination') オプション を含めて多くのオプションは、`!' (否定の宣言)を その引数の前に置くことができます。`-s' や `-d' の場合は与えられた アドレスと等しくないアドレスとマッチします。 例えば、`-s ! localhost' は localhost からでないパケットと マッチします。
プロトコルは `-p' (または `--protocol') オプションで指定します。 プロトコルの値は番号(あなたが IP のプロトコルの数値番号を知って いる場合)か `TCP', `UDP' または `ICMP' という特定の名称で指定します。 大文字小文字の区別はしませんから、`tcp' も `TCP' と同じ働きをします。
プロトコル名称はそれを否定するために `!' を前に付けることができます。 例えば、`-p ! TCP' は TCP でないパケットを指定します。
`-i' (または `--in-interface') と `-o' (または `--out-interface') オプションはマッチすべきインターフェイスの名前を指定します。 インターフェイスとは、パケットが入って来る (`-i') または出て行く (`-o') 物理デバイスです。`ifconfig' コマンドを使って `up' である (すなわち、今動いている)インターフェイスをリストアップできます。
INPUT
チェインに入って来るパケットには output インターフェイス
が無いので、このチェインで `-o' を使ったルールは決してマッチしません。
同様に、OUTPUT
チェインに入って来るパケットには
input インターフェイスが無いので、このチェインで `-i' を使ったルールは
決してマッチしません。
FORWARD
チェインに入って来るパケットだけが、input と output
の両方のインターフェイスを持っています。
現在存在していないインターフェイスを指定することは全く問題がありません
が、指定したインターフェイスが up して来るまでルールがマッチすることは
ありません。これはダイアルアップ PPP リンク(通常インターフェイスは
ppp0
)や同様のものについて非常に有効です。
特別なケースとして、インターフェイス名の後ろに `+' を付けたものはその
文字列から始まる全てのインターフェイス(現在存在してようとなかろうと)
にマッチします。例えば、全ての PPP インターフェイスにマッチするルール
の指定は、-i ppp+
オプションを使います。
指定したインターフェイスと一致しないパケットにマッチするように
インターフェイス名の前には前後に空白を挟んで `!' を置くことができます。
例えば、-i ! ppp+
とします。
ときどきパケットが、一度にケーブルに送り出すには大き過ぎることがあります。 こんなときは、パケットはフラグメントに分割され、複数のパケットで送られ ます。受信点でこれらのフラグメントを再び集めて完全なパケットに再構成 します。
フラグメントの問題点は、先頭のフラグメントには完全な ヘッダーフィールド(IP + TCP, UDP および ICMP)があり検査できますが、 後続のパケットにはヘッダー全てが揃っていません(IP ヘッダーだけで 追加のプロトコルフィールドは無し)。従って後続のフラグメントの プロトコル固有ヘッダー(TCP, UDP および ICMP で拡張された)をのぞき込む ことはできません。
もし、コネクション追跡や NAT を行っているなら、全てのフラグメントは パケットフィルタリングのコードに届く前にマージされて元通りにされる ので、フラグメントについて心配する必要はありません。
そうでなければ、フィルタリングルールがフラグメントをどのように扱うか
を理解することが重要です。情報が無ければどんなフィルタリングルールも
マッチしません。この意味するところは 1番目のフラグメントは
他のパケットと同じように扱われます。2番目以降のフラグメントは異なり
ます。従って -p TCP --sport www
というルール(ソースポートが
`www' の指定)はフラグメント(1番目のフラグメント以外)と決してマッチ
しません。同様に否定のルール -p TCP --sport ! www
もマッチ
しません。
とはいえ、`-f' (または `--fragment')オプションを使って 2番目以降の
フラグメントを特定するルールを指定できます。また、` ! ' を `-f' の
前に付けて(訳注: ! -f
として) 2番目以降のフラグメントと適合
しないルールの指定もできます。
通常、フィルタリングは 1番目のフラグメントに効力があるので、目的の ホストでのフラグメントの再組み立てを妨げるため、2番目以降のフラグメント を通過させることは安全とみなされています。とはいえ、フラグメントを送る ことにより簡単にマシンをクラッシュさせることができるバグが知られて います。調べてくださいね。
ネットワーク管理者のための注記: 異常なパケット(TCP, UDP および ICMP の パケットで短すぎてファイアーウォールのコードがポート番号または ICMP の コードと種類を読めないもの)はそれらの検査が試みられるとき破棄されます。 それで TCP パケットのフラグメントの位置は最低でも 8 から始まります。
例えば、次のルールは 192.168.1.1 へ行くフラグメントはどれでも破棄します:
# iptables -A OUTPUT -f -d 192.168.1.1 -j DROP
#
iptables
は拡張性に富んでいます、その意味する
ところは、カーネルと iptables ツールの両方が新しい機能を提供するために
拡張可能であると言うことです。
これらの拡張には標準的なものもありますが、もっと風変わりなものも あります。私達以外の人々が拡張を作って特殊な利用者に個別に配布する ことができます。
カーネルの拡張は、通常カーネルモジュールのサブディレクトリ、 例えば /lib/modules/2.4.0-test10/kernel/net/ipv4/netfilter に存在します。 それらはカーネルが CONFIG_KMOD をセットしてコンパイルされていれば要求時にロードされます。
iptables プログラムへの拡張は、共有ライブラリで通常は /usr/local/lib/iptables/ に存在します。ディストリビューションに よっては /lib/iptables または /usr/lib/iptables に置かれます。
拡張には 2種類あります: 新しいターゲット、そして新しいマッチです (新しいターゲットについては、もう少し後でお話します)。いくつかの プロトコルは自動的に新しい検査を提供します: 現在のところ以下に示す TCP, UDP および ICMP があります。
これらは `-p' オプションで拡張がロードされ、その後のコマンドラインで 新しい検査を指定できます。新しい検査を指定するには、`-m' オプションを 使うと拡張がロードされて、拡張されたオプションが有効になります。
拡張のヘルプを見るには、拡張をロード(`-p', `-j' または `-m')した後に `-h' または `--help' オプションを使います。例えば:
# iptables -p tcp --help
#
TCP 拡張は `-p tcp' を指定すると自動的にロードされます。 以下のオプションが提供されています(フラグメントは決してマッチしません)。
後に `!' オプション指定可で、2つのフラグ文字列 をとり、指定した TCP フラグでフィルターできます。1番目の文字列はマスク するフラグで、検査したいフラグを書き並べます。2番目の文字列は(訳注: 1番目の文字列のうちで)セットされているべきフラグを指定します。例えば、
# iptables -A INPUT --protocol tcp --tcp-flags ALL SYN,ACK -j DROP
これは全てのフラグを検査し(`ALL' は `SYN,ACK,FIN,RST,URG,PSH' と同じ 意味)、SYN と ACK だけがセットされているべきことを示しています。 また `NONE' はどのフラグもセットされていないことを意味します (訳注: `NONE' を使うのは普通、2番目の文字列で、1番目で指定したフラグが 全てオフであることを検査します)。
前に `!' オプション指定可で、これは `--tcp-flags SYN,RST,ACK SYN' の省略表現です。
後に `!' オプション指定可で、1つの TCP ポート、またはポートの範囲のどちらでも指定できます。ポートは /etc/services に一覧されている名前でも、番号でも指定できます。 範囲の指定は 2つのポートを `:' で区切るか、後ろに `:' を付ける (指定したポート番号以上を示す)か、前に `:' を付ける (指定したポート番号以下を示す)かのいずれかです。
は `--source-port' と同じ意味です。
と
は上記と同様で、 ソースの代わりに、単にあて先のポートとマッチするかの指定です。
後に `!' オプション指定可で、数値を指定し、 パケットの TCP オプション(訳注: オプションフィールドの 1バイト目の種別) が指定値と等しいときマッチします。TCP オプションの検査をしようとする とき、パケットに TCP ヘッダーが完全に含まれていなければパケットは 自動的に破棄されます。
一方向だけ TCP コネクションを許可し、他方は許可しないようにすることは 往々にして有効です。例えば、あなたが外部の WWW サーバーと接続したいが、 そのサーバーからの接続を許可したくないときです。
そのサーバーから来る TCP パケットをブロックすることは自然な方法です。 残念なことに、TCP コネクションにはとにかく両方向のパケットが行き来する ことが必要です。
その解決方は、接続を要求するパケットだけをブロックすることです。 このようなパケットは SYN パケットと呼ばれています(オーケー、 技術的には SYN フラグがセットされていて、RST と ACK フラグがクリア されているパケットですが、短縮して SYN パケットと呼んでいます)。 これらのパケットだけ許可しないようにすれば、パケットを逆にたどって 接続して来るのを止めることができます。
`--syn' オプションはこのために使われます。このオプションは TCP プロトコルが 指定されているルールにだけ有効です。例えば、192.168.1.1 からの TCP 接続 の試みの指定:
-p TCP -s 192.168.1.1 --syn
このオプションは `!' を前に付けて(訳注: ! --syn
として)否定すること
ができ、その意味は接続開始のパケットを除く全てのパケットです。
この拡張は `-p udp' を指定すると自動的にロードされます。オプションは `--source-port' または `--sport' と `--destination-port' または `--dport' が提供され、詳細は TCP と同様です。
この拡張は `-p icmp' を指定すると自動的にロードされます。新しい オプションが 1つだけ提供されます:
後に `!' オプション指定可で、ICMP の種類を名前で (例えば `host-unreachable')、または種類を数値で(例えば `3')、または種類 とコードを `/' で区切ったもの(例えば `3/3')を指定します。 ICMP の種類で指定できる名前のリストは `-p icmp --help' で得られます。
netfilter パッケージのその他の拡張は実証的拡張で、インストール済み なら `-m' オプションで呼び出すことができます。
このモジュールは明示的に `-m mac' または `--match mac' で指定されなければなりません。これは入って来るパケットの発信元 イーサネット(MAC)アドレスとのマッチングに使い、そのため、PREROUTING と INPUT チェインに入って来るパケットにだけ有効です。このモジュールは オプションを 1つだけ提供します:
後に `!' オプション指定可で、イーサネット アドレスをコロンで区切った 16進表記で指定します。例えば、 `--mac-source 00:60:08:91:CC:B7'
このモジュールは明示的に `-m limit' または `--match limit' で指定されなければなりません。これはマッチするレート (頻度)を制限するために使われ、例えば、ログメッセージを抑止するために 使います。このオプションは単位時間あたりに指定された回数分だけマッチ します(初期値は 1時間あたり 3回のマッチで、バーストは 5 です)。これは 2つのオプション引数をとります:
後に数値を指定します。単位時間あたりに許される 平均マッチ回数の最大値を指定します。指定値は、`/second', `/minute', `/hour' または `/day' を使って、あるいはその一部(それで `5/second' は `5/s' と同じ)で単位を明示することができます。
後に数値を指定します。これは上記の limit が 作動し始める手前の最大バースト値(訳注: 許容できる突発的な増大係数で、 平均レートの倍数)を指定します。
このマッチは、しばしばログのレート(頻度)制限をするために LOG ターゲット と共に使われます。どのように働くのか理解するために、初期値の limit パラメータでパケットをログする次のルールを見てみましょう:
# iptables -A FORWARD -m limit -j LOG
最初にこのルールに達したとき、パケットはログされます。実際、初期値の バーストは 5 なので、最初の 5パケットがログされます。このあと、何個の パケットが届くかには関係なく、20分間はこのルールによりログされることは ありません。そして、20分経過する毎にマッチするパケットがなければ、 バーストは 1 づつ回復します。もし、100分間にルールにヒットするパケット がなければ、バーストは完全に回復し、始めと同じに戻ります。
注記: 現在のところ約 59時間を超える回復時間のルールは作れないので、 もし、平均レートを 1日 1回に設定した場合、バーストレートは 3 未満で なくてはなりません。
このモジュールは、また、速いレートの感応性を高めることで、各種の サービス拒否攻撃(DoS)を防ぐことができます。
SYN パケット溢れへの防御:
# iptables -A FORWARD -p tcp --syn -m limit --limit 1/s -j ACCEPT
こっそり覗きのポートスキャナー:
# iptables -A FORWARD -p tcp --tcp-flags SYN,ACK,FIN,RST RST -m limit --limit 1/s -j ACCEPT
Ping of death:
# iptables -A FORWARD -p icmp --icmp-type echo-request -m limit --limit 1/s -j ACCEPT
このモジュールは、下のグラフに示すように、“ヒステリシスドア” のように働きます。
レート(パケット数/秒)
^ .---.
| / DoS \
| / \
DoSの始まり -|......:.........\.......................
= (limit * | /: \
limit-burst) | / : \ .-.
| / : \ / \
| / : \ / \
DoSの終わり -|./....:..............:.../.......\..../.
= limit |/ : :`-' `--'
-------------+------+--------------+------------------> 時間 (秒)
論理 ⇒ マッチ| マッチしない | マッチ
例えば、1秒あたり 1パケットでバーストが 5パケットのマッチを指定している ところに、1秒あたり 4パケットがやって来て 3秒間続き、それから、3秒間で 再びパケットがやって来るとします。
←―溢れ 1―→ ←― 溢れ 2 ―→
トータル^ _― ̄ YNNN
パケット| ライン_― YNNN
数 | レート_― YNNN
10 | 最大 _― Y
| _― Y
| _― Y
| _― YNNN
|- YNNN
5 | Y
| Y キー: Y ⇒ ルールにマッチする
| Y N ⇒ ルールにマッチしない
| Y
|Y
0 +--------------------------------------------------> 時間 (秒)
0 1 2 3 4 5 6 7 8 9 10 11 12
最初の 5パケットは 1秒に 1パケットを超えるのに許可されていますが、 その後、制限が働いていることが分かります。もし、少し途絶えていれば、 ルールに設定された最大レートの範囲内で、またバーストが許されます (バースト作動後は 1秒 1パケット)。
このモジュールは、ローカルに生成されたパケットの作成者の各種の特質と マッチを試みます。これは OUTPUT チェインでのみ有効ですが、いくつかの パケット(例えば、ICMP ping の応答)には所有者がないので、それゆえ決して マッチしません。
パケットを生成したプロセスの実行ユーザ id (数値)にマッチします。
パケットを生成したプロセスの実行グループ id (数値) にマッチします。
パケットを生成したプロセスのプロセス id にマッチします。
パケットを生成したプロセスのセッショングループにマッチします。
この実験的モジュールは `-m unclean または `--match unclean' を明示的に指定する必要があります。これはパケット について手当たりしだい様々の正当性をチェックします。このモジュール は検査されていないので、セキュリティ装置として使うべきではありません (バグがよくあるので、ことによると事態が悪化します)。オプションはありま せん。
最も役に立つマッチ判定基準は `state' 拡張によって提供され、 `ip_conntrack' モジュールのコネクション追跡の分析結果を簡単に利用 できるようにします。これは非常にお勧めです。
`-m state' を指定すると追加して `--state' オプションが指定でき、 そこにマッチすべき状態のリストをカンマで区切って指定します(`!' オプション は指定した状態にマッチしないことを示します)。状態には以下の ものがあります:
新しいコネクションを作るパケットです。
既存のコネクションに属するパケットです (すなわち、応答パケット、あるいはコネクション確立中の応答のため 出て行くパケット)。
既存のコネクションの一部ではなくて関係するパケット、 例えば、ICMP エラーとか、または(FTP モジュールが挿入済みなら)、ftp データコネクションの確立パケットです。
いくつかの理由から ― これにはメモリ不足、どの コネクションにも対応するものがない ICMP エラー を含みますが、身元不明 のパケットがあります。一般的にこれらのパケットは破棄すべきです。
この強力なマッチ拡張の使用例は以下のようになります:
# iptables -A FORWARD -i ppp0 -m state ! --state NEW -j DROP
今や、私達はパケットに関してどんな検査ができるか知っています。 次に必要なのは検査にマッチしたパケットに対して何をするか指示する方法です。 これはルールのターゲットと呼ばれています。
とても単純な 2つの組み込み済みターゲット: DROP と ACCEPT があります。 これらについては前に述べました。もし、ルールがパケットにマッチし、 ターゲットがこれら 2つのどちらか一方なら、パケットの運命が決定されて、 これ以上ルールが調べられることはありません。
組み込み済みターゲット以外に 2種類のターゲット: 拡張ターゲット とユーザ定義チェインがあります。
ipchains
から継承した iptables
の強力な特徴の 1つ
は、3つの組み込み済みチェイン(INPUT, FORWARD そして OUTPUT)に加えて、
ユーザが新しいチェインを作ることができるということです。慣例で、
ユーザ定義チェインは組み込み済みチェインと区別するために小文字に
します(新しいユーザ定義チェインの作り方は、以下の
チェインの操作で説明します)。
パケットがルールにマッチし、そのターゲットがユーザ定義チェインであれば、 パケットはそのユーザ定義チェインに移り、ルールの検査を始めます。その ユーザ定義チェインでの検査が全て終ってもパケットの運命が決まらなければ、 現在のチェインに戻り、その次のルールから検査を再開します。
ASCII アートの時間です。2つの(おばかさんな)チェイン: INPUT
(組み込み済みチェイン)と test
(ユーザ定義チェイン)で考えま
しょう。
`INPUT' `test'
┌─────────────┐ ┌─────────────┐
│ルール 1: -p ICMP -j DROP │ │ルール 1: -s 192.168.1.1 │
├─────────────┤ ├─────────────┤
│ルール 2: -p TCP -j test │ │ルール 2: -d 192.168.1.1 │
├─────────────┤ └─────────────┘
│ルール 3: -p UDP -j DROP │
└─────────────┘
192.168.1.1 から来て 1.2.3.4 へ向かう TCP パケットについて考えましょう。
パケットは INPUT
チェインに入り、まず、ルール 1 が検査されます
― マッチしません。ルール 2 がマッチして、そのターゲットは test
なので、次に検査されるルールは test
の先頭です。test
のルール 1 はマッチしますが、ターゲットを指定していないので、次のルール
であるルール 2 が検査されます。これはマッチしないので、チェインの終わりに
達しました。先程検査したルール 2 のある INPUT
チェインに戻り、
それで今度はルール 3 が検査されますが、これもまたマッチしません。
それで、パケットの経路は次のようになります:
v __________________________
`INPUT' | / `test' v
┌───────────|─/ ┌──────────|─┐
│ルール 1 | /│ │ルール 1 | │
├───────────|/-┤ ├──────────|─┤
│ルール 2 / │ │ルール 2 | │
├───────────-─┤ └──────────v─┘
│ルール 3 /─┼─\_______________________/
└───────────|─┘
v
ユーザ定義チェインは他のユーザ定義チェインへジャンプできます (しかし、ループしてはいけません。ループしていることが判ると パケットは破棄されます)。
拡張のもう 1つの種類はターゲットです。ターゲットの拡張
はカーネルモジュールから成り、iptables
へのオプションの
拡張は新しいコマンドラインオプションによって提供されます。netfilter
の配布物には始めから数々の拡張があります:
このモジュールはマッチしたパケットのカーネルロギング を提供します。以下の追加オプションを提供します:
後にレベル番号か名前を続けます。有効な名前 は(大文字小文字を問わず) `debug', `info', `notice', `warning', `err', `crit', `alert' および `emerg' で、それぞれ番号の 7 から 0 に該当します。これらのレベルの説明は syslog.conf の man ページを見て ください。初期値は `warning' です。
後に最大 29文字までの文字列を続けます。 このメッセージはログメッセージの開始時に送られるので、それを識別 できます。
このモジュールは limit マッチの後で最も有効で、それはログがあふれる のを防ぎます。
このモジュールは `DROP' と同じ効果がありますが、 送信者に ICMP の `ポート未到達' エラーメッセージを送り返すところが 違います。注記として、以下の場合(RFC 1122 を見てください) ICMP エラーメッセージは送られません:
REJECT はまた、使われる応答パケットを変更するのに `--reject-with' オプション引数をとります: マニュアルページを見てください。
2つの特別な組み込み済みターゲット: RETURN
と QUEUE
があります。
RETURN
はチェインの末尾まで落っこちるのと同じ効果があります
― 組み込み済みチェイン内のルールの場合は、そのチェインのポリシー
が実行されます。ユーザ定義チェイン内のルールの場合は、そのチェインを
呼び出したチェインに戻り、呼び出し元のルールの直後から検査が続行されます。
QUEUE
はパケットをユーザ空間で処理するためにキューに入れる
という特別なターゲットです。これを有効にするには、さらに 2つの構成物が
必要です:
ユーザ空間で処理するためにキューへパケットを入れる iptables の使い方の 簡単な例を以下に示します:
# modprobe iptable_filter
# modprobe ip_queue
# iptables -A OUTPUT -p icmp -j QUEUE
このルールでは、ローカルに生成された外に出て行く ICMP パケット(例えば、
ping で生成された)は ip_queue モジュールに渡されます。それから、ip_queue
はパケットをユーザ空間のアプリケーションに届けようとします。もし、待機
しているユーザ空間アプリケーションが無ければ、パケットは破棄されます。
ユーザ空間アプリケーションを書くためには、libipq API を使います。 これは iptables と一緒に配布されています。実例のコードは CVS 中の testsuite ツール(例えば、redirect.c)の中で見つけられます。
ip_queue の状態は以下でチェックできます:
/proc/net/ip_queue
キューの最大長(すなわち、ユーザ空間に届けられていて、まだ判定がなされて
いないパケットの数)は以下でコントロールできます:
/proc/sys/net/ipv4/ip_queue_maxlen
キューの最大長の初期値は 1024 です。一旦この限界値に達したら、キューの
長さが限界値より低くなるまで新しいパケットは破棄されます。TCP のような
すばらしいプロトコルは、混雑で落ちこぼれたパケットを検出して、キューが
一杯になったとき、再送を試みます。とはいえ、与えられた状況下で初期値は
小さ過ぎるかもしれないので、理想的な最大キュー長を決定するのにいくらか
実験するとよいでしょう。
iptables
のとても有効な特徴は、チェイン中の関連するルールを
グループ化できることです。お望みのチェインは何でも呼び出せますが、
組み込み済みチェインやターゲットと混同を避けるため小文字を使う
ことをお勧めします。チェインの名前は最大 31文字まで使えます。
新しいチェインを作りましょう。私はとっても創造力に富んだ野郎なので、
それを test
と名付けます。`-N' または `--new-chain' オプション
を使います:
# iptables -N test
#
これは簡単です。今や、あなたはこれまで詳細に述べてきたように、これに ルールを入れることができます。
チェインを削除するのも同様に簡単で、`-X' または `--delete-chain' オプションを使います。なぜ `-X' かって? うーん、よい文字が全て 取られてたんです。
# iptables -X test
#
チェインを削除するには 2つの制限があります ― そのチェインは空である必要 があり(下記の チェインを空にするを見てくださ い)、しかも、決してどのルールのターゲットにもなっていないことです。 組み込み済みの 3つのチェインはどれも削除できません。
もし、チェイン名を指定しなければ、全てのユーザ定義チェインが 可能な限り削除されます。
チェインから全てのルールを取り去り空にするのは簡単で、`-F' (または `--flush') コマンドを使います。
# iptables -F FORWARD
#
もし、チェイン名を指定しなければ、全てのチェインを空にします。
チェイン中の全てのルールをリストアップするには、`-L' (または `--list') コマンドを使います。
各々のユーザ定義チェインに表示される `refcnt' は、それをターゲットに 指定しているルールの数です。この数が 0 でないと(かつチェインが空である こと)、そのチェインを削除することはできません。
もし、チェイン名を指定しなければ、空のも含めて全てのチェインについて リストアップされます。
`-L' には 3つのオプションがあります。
(たいていの人々は DNS を使っていますが) DNS が適切に設定
されていない場合や DNS の要求をフィルターアウトしている場合は、
iptables
が IP アドレスを調べようとするときに長く待たされます。
それを防ぐのに `-n' (数値)オプションはとても有効です。このオプションは
また、TCP や UDP ポートを名前ではなく番号で表示します。
`-v' オプションはルールの詳細を全て、例えば、パケットやバイトの カウンター、TOS マスク、そしてインターフェイス、を表示します。 このオプションを指定しなければ、これらの値は省略されます。
注記として、パケットとバイトのカウンターは、1000, 1,000,000 および 1,000,000,000 を、それぞれ `K', `M' および `G' の接尾辞を使って表示 します。`-x' (拡張数値)オプションを使うと、値の大きさにかかわらず完全な数値 を同様に表示します。
カウンターをリセットできると便利です。これは `-Z' (または `--zero') オプションでできます。
以下について考えてみましょう:
# iptables -L FORWARD
# iptables -Z FORWARD
#
上記の方法では、`-L' から `-Z' コマンドまでの間に いくつかのパケットが通過するかもしれません。そのため、カウンターを 読むと同時にリセットするには、`-L' と `-Z' を同時に使います。
以前にパケットがどのようにチェインを通り抜けるのか論じたとき、パケットが
組み込み済みチェインの終わりに達したとき何が起きるのか大体述べました。
この場合、チェインのポリシーがそのパケットの運命を決定します。
組み込み済みチェイン(INPUT
, OUTPUT
および
FORWARD
)だけがポリシーを持っています。なぜなら、パケットが
ユーザ定義チェインの終わりまで下り落ちると、前のチェインに戻って行く
からです。
ポリシーは ACCEPT
か DROP
のどちらかです。
例えば:
# iptables -P FORWARD DROP
#