次のページ 前のページ 目次へ

7. iptables を使う

個々の事項についてのもっと詳しい説明が必要なら、iptables にはかなり 詳しいマニュアルページ(man iptables)があります。 ipchains に精通している人はすぐにでも iptables と ipchains の違いを見たいにちがいありません。実際、 2つはとても似ています。

iptables を使って色々なことができます。 まず、3つの組み込み済みチェイン INPUT, OUTPUT そして FORWARD (これらは削除できません)から始めます。 では、チェインを扱う操作を見てみましょう:

  1. 新しいチェインを作る (-N)
  2. 空のチェインを削除する (-X)
  3. 組み込み済みチェインのポリシーを変更する (-P)
  4. チェイン内のルールをリストアップする (-L)
  5. チェインからルールを全て消し去る (-F)
  6. チェイン内の全てのルールのパケットとバイトのカウンターをゼロにする (-Z)

チェイン内のルールを操作するには様々な方法があります:

  1. チェインに新しいルールを追加する (-A)
  2. チェイン内のある位置に新しいルールを挿入する (-I)
  3. チェイン内のある位置のルールを置き換える (-R)
  4. チェイン内のある位置の、または記述と一致した最初のルールを削除する (-D)

7.1 コンピュータを起動したとき見るべきこと

iptables はたぶんモジュールになっています。名前は(`iptable_filter.o') で、最初に iptables を実行したときに自動的に ロードされるはずです。また、カーネルに恒常的に組み込むこともできます。

全く iptables コマンドを実行していない状態では(注意しましょう: 初期化スクリプトで iptables を実行するディストリビューションがあります)、 組み込み済みチェイン(`INPUT', `FORWARD' および `OUTPUT')のどれにも ルールは存在せず、全てのチェインのポリシーは ACCEPT です。 しかし、iptable_filter モジュールのオプションに `forward=0' を与えれば、 FORWARD チェインのポリシーの初期値を(訳注: DROP に)変えることができます。

7.2 ルールの操作

ルールを操作すること ― それはパケットフィルタリングの基本です。 ほとんどの場合、普通、あなたは追加 (-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) コマンドのときと正確に同じ オプションでなければなりません。もし、同一チェイン中に複数のマッチ するルールがあったら、最初のだけが削除されます。

7.3 フィルタリングの仕様

これまでに、プロトコルを指定する `-p' オプションと、ソースアドレスを 指定する `-s' オプションを見てきましたが、この他にもパケットの特徴を 指定する様々なオプションがあります。これから、その概要をあますところなく お話します。

ソースとあて先 IP アドレスの指定

ソース(`-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拡張性に富んでいます、その意味する ところは、カーネルと 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 拡張

TCP 拡張は `-p tcp' を指定すると自動的にロードされます。 以下のオプションが提供されています(フラグメントは決してマッチしません)。

--tcp-flags

後に `!' オプション指定可で、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番目で指定したフラグが 全てオフであることを検査します)。

--syn

前に `!' オプション指定可で、これは `--tcp-flags SYN,RST,ACK SYN' の省略表現です。

--source-port

後に `!' オプション指定可で、1つの TCP ポート、またはポートの範囲のどちらでも指定できます。ポートは /etc/services に一覧されている名前でも、番号でも指定できます。 範囲の指定は 2つのポートを `:' で区切るか、後ろに `:' を付ける (指定したポート番号以上を示す)か、前に `:' を付ける (指定したポート番号以下を示す)かのいずれかです。

--sport

は `--source-port' と同じ意味です。

--destination-port

--dport

は上記と同様で、 ソースの代わりに、単にあて先のポートとマッチするかの指定です。

--tcp-option

後に `!' オプション指定可で、数値を指定し、 パケットの TCP オプション(訳注: オプションフィールドの 1バイト目の種別) が指定値と等しいときマッチします。TCP オプションの検査をしようとする とき、パケットに 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 として)否定すること ができ、その意味は接続開始のパケットを除く全てのパケットです。

UDP 拡張

この拡張は `-p udp' を指定すると自動的にロードされます。オプションは `--source-port' または `--sport' と `--destination-port' または `--dport' が提供され、詳細は TCP と同様です。

ICMP 拡張

この拡張は `-p icmp' を指定すると自動的にロードされます。新しい オプションが 1つだけ提供されます:

--icmp-type

後に `!' オプション指定可で、ICMP の種類を名前で (例えば `host-unreachable')、または種類を数値で(例えば `3')、または種類 とコードを `/' で区切ったもの(例えば `3/3')を指定します。 ICMP の種類で指定できる名前のリストは `-p icmp --help' で得られます。

その他のマッチの拡張

netfilter パッケージのその他の拡張は実証的拡張で、インストール済み なら `-m' オプションで呼び出すことができます。

mac

このモジュールは明示的に `-m mac' または `--match mac' で指定されなければなりません。これは入って来るパケットの発信元 イーサネット(MAC)アドレスとのマッチングに使い、そのため、PREROUTING と INPUT チェインに入って来るパケットにだけ有効です。このモジュールは オプションを 1つだけ提供します:

--mac-source

後に `!' オプション指定可で、イーサネット アドレスをコロンで区切った 16進表記で指定します。例えば、 `--mac-source 00:60:08:91:CC:B7'

limit

このモジュールは明示的に `-m limit' または `--match limit' で指定されなければなりません。これはマッチするレート (頻度)を制限するために使われ、例えば、ログメッセージを抑止するために 使います。このオプションは単位時間あたりに指定された回数分だけマッチ します(初期値は 1時間あたり 3回のマッチで、バーストは 5 です)。これは 2つのオプション引数をとります:

--limit

後に数値を指定します。単位時間あたりに許される 平均マッチ回数の最大値を指定します。指定値は、`/second', `/minute', `/hour' または `/day' を使って、あるいはその一部(それで `5/second' は `5/s' と同じ)で単位を明示することができます。

--limit-burst

後に数値を指定します。これは上記の 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パケット)。

owner

このモジュールは、ローカルに生成されたパケットの作成者の各種の特質と マッチを試みます。これは OUTPUT チェインでのみ有効ですが、いくつかの パケット(例えば、ICMP ping の応答)には所有者がないので、それゆえ決して マッチしません。

--uid-owner userid

パケットを生成したプロセスの実行ユーザ id (数値)にマッチします。

--uid-owner groupid

パケットを生成したプロセスの実行グループ id (数値) にマッチします。

--pid-owner processid

パケットを生成したプロセスのプロセス id にマッチします。

--sid-owner sessionid

パケットを生成したプロセスのセッショングループにマッチします。

unclean

この実験的モジュールは `-m unclean または `--match unclean' を明示的に指定する必要があります。これはパケット について手当たりしだい様々の正当性をチェックします。このモジュール は検査されていないので、セキュリティ装置として使うべきではありません (バグがよくあるので、ことによると事態が悪化します)。オプションはありま せん。

状態のマッチ

最も役に立つマッチ判定基準は `state' 拡張によって提供され、 `ip_conntrack' モジュールのコネクション追跡の分析結果を簡単に利用 できるようにします。これは非常にお勧めです。

`-m state' を指定すると追加して `--state' オプションが指定でき、 そこにマッチすべき状態のリストをカンマで区切って指定します(`!' オプション は指定した状態にマッチしないことを示します)。状態には以下の ものがあります:

NEW

新しいコネクションを作るパケットです。

ESTABLISHED

既存のコネクションに属するパケットです (すなわち、応答パケット、あるいはコネクション確立中の応答のため 出て行くパケット)。

RELATED

既存のコネクションの一部ではなくて関係するパケット、 例えば、ICMP エラーとか、または(FTP モジュールが挿入済みなら)、ftp データコネクションの確立パケットです。

INVALID

いくつかの理由から ― これにはメモリ不足、どの コネクションにも対応するものがない ICMP エラー を含みますが、身元不明 のパケットがあります。一般的にこれらのパケットは破棄すべきです。

この強力なマッチ拡張の使用例は以下のようになります:

# iptables -A FORWARD -i ppp0 -m state ! --state NEW -j DROP

7.4 ターゲットの仕様

今や、私達はパケットに関してどんな検査ができるか知っています。 次に必要なのは検査にマッチしたパケットに対して何をするか指示する方法です。 これはルールのターゲットと呼ばれています。

とても単純な 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

ユーザ定義チェインは他のユーザ定義チェインへジャンプできます (しかし、ループしてはいけません。ループしていることが判ると パケットは破棄されます)。

iptables への拡張 ― 新しいターゲット

拡張のもう 1つの種類はターゲットです。ターゲットの拡張 はカーネルモジュールから成り、iptables へのオプションの 拡張は新しいコマンドラインオプションによって提供されます。netfilter の配布物には始めから数々の拡張があります:

LOG

このモジュールはマッチしたパケットのカーネルロギング を提供します。以下の追加オプションを提供します:

--log-level

後にレベル番号か名前を続けます。有効な名前 は(大文字小文字を問わず) `debug', `info', `notice', `warning', `err', `crit', `alert' および `emerg' で、それぞれ番号の 7 から 0 に該当します。これらのレベルの説明は syslog.conf の man ページを見て ください。初期値は `warning' です。

--log-prefix

後に最大 29文字までの文字列を続けます。 このメッセージはログメッセージの開始時に送られるので、それを識別 できます。

このモジュールは limit マッチの後で最も有効で、それはログがあふれる のを防ぎます。

REJECT

このモジュールは `DROP' と同じ効果がありますが、 送信者に ICMP の `ポート未到達' エラーメッセージを送り返すところが 違います。注記として、以下の場合(RFC 1122 を見てください) ICMP エラーメッセージは送られません:

REJECT はまた、使われる応答パケットを変更するのに `--reject-with' オプション引数をとります: マニュアルページを見てください。

特別な組み込み済みターゲット

2つの特別な組み込み済みターゲット: RETURNQUEUE があります。

RETURN はチェインの末尾まで落っこちるのと同じ効果があります ― 組み込み済みチェイン内のルールの場合は、そのチェインのポリシー が実行されます。ユーザ定義チェイン内のルールの場合は、そのチェインを 呼び出したチェインに戻り、呼び出し元のルールの直後から検査が続行されます。

QUEUE はパケットをユーザ空間で処理するためにキューに入れる という特別なターゲットです。これを有効にするには、さらに 2つの構成物が 必要です:

IPv4 iptables の標準キューハンドラーは ip_queue モジュールで、カーネル と一緒に配布され、開発中(experimental)としてマークされています。

ユーザ空間で処理するためにキューへパケットを入れる 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 のような すばらしいプロトコルは、混雑で落ちこぼれたパケットを検出して、キューが 一杯になったとき、再送を試みます。とはいえ、与えられた状況下で初期値は 小さ過ぎるかもしれないので、理想的な最大キュー長を決定するのにいくらか 実験するとよいでしょう。

7.5 チェインの操作

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)だけがポリシーを持っています。なぜなら、パケットが ユーザ定義チェインの終わりまで下り落ちると、前のチェインに戻って行く からです。

ポリシーは ACCEPTDROP のどちらかです。 例えば:

# iptables -P FORWARD DROP
#


次のページ 前のページ 目次へ