[Home] [Kuri] [Sysad] [Internet?] [Blog] [Java] [Windows] [Download] [Profile] [Flash] [+]

ipchains で フィルタリング、NAPT

ipchains は、Linux の標準的なフィルタリング等を行うための設定ツール です。
2.4 からは iptables が主流になっていますが、引続き ipchains も使用 できるようになっています。
ここでは、簡単な ipchains の使用方法について述べます。2.4 上で動作 確認をしていますが、2.2 などでも同様に動作するのではないかと思います。
# …が、確認をしたわけではありません。

目次


1. 環境

RedHat Linux 7.1J (カーネルは 2.4.2) で試しました。
ipchains は 1.3.10, 1-Sep-2000 です。(ipchains --version)

2. 前準備

2.1 カーネル

CONFIG_NETFILTER 等が設定されている必要があります。 設定されていなければ、カーネルを再構築する必要があります。

  # cd /usr/src/linux (もしくはカーネルのソースのディレクトリ)
  # make mrproper
  # make menuconfig (xconfig でも config でもお好きなものを)
    Networking options ->
      Network packet filtering (replaces ipchains) を選択
      IP: Netfilter Configuration ->
        Connection tracking (required for masq/NAT) を選択
        ipchains (2.2-style) support を選択
        Full NAT を選択(NAPT(IP masquarade)か透過 proxy が必要なら)
          MASQUERADE target support を選択(NAPT(IP masquarade)が必要なら)
          REDIRECT target support を選択(透過 proxy が必要なら)
  # make dep
  # make clean
  # make bzImage

できたカーネル(arch/i386/boot/bzImage)を /boot などにコピーし、lilo を実行し(できれば /etc/lilo.conf を編集して前のカーネルでも実行でき るようにしたほうがいいと思います)、OS を再起動します。
# make modules および make modules_install が必要になる場合もあります。

2.2 ipchains を有効にする

ipchains をモジュールで組み込んだ場合、そのままでは動作しませんので、 あらかじめモジュールを組み込む必要があります。
# /etc/init.d/ipchains は、必要ならモジュールを組み込んでくれます。

  # ipchains -L
  ipchains -L
  ipchains: Incompatible with this kernel

と言われたら、以下のようにして組み込みます。

  # modprobe ipchains
  # ipchains -L
  Chain input (policy ACCEPT):
  Chain forward (policy ACCEPT):
  Chain output (policy ACCEPT):

最終的には、OS 起動時に ipchains を起動するようにしておいた方がいい かもしれません。そうしたいなら、chkconfig --list を実行して、ipchains がオフになっていたらオンにします。

  # chkconfig --list
  ...前略
  ipchains        0:オフ  1:オフ  2:オフ  3:オフ  4:オフ  5:オフ  6:オフ
  ...後略
  # chkconfig ipchains on
  # chkconfig --list
  ...前略
  ipchains        0:オフ  1:オフ  2:オン  3:オン  4:オン  5:オン  6:オフ
  ...後略


3. 設定方法

RedHat の場合、起動時に /etc/sysconfig/ipchains があれば、それを読み 込むようになっています。ここでは、このファイルに設定を書いていきます。

3.1 フィルタリング

他のフィルタリングするものと同様、設定ファイル(/etc/sysconfig/ipchains) に、1行に1つのルールを書いていきます。
デフォルトでは、最初に該当するルールが適用されます。ルールに該当しな い場合は通します。 「簡単な」書式は以下の通りです。

 -[ADCRI] chain [-p protocol][-s source] [-d destination][-j target][-i interface] [-f][-l][-t mask][-y]

設定ファイルを ipchains-restore コマンドの標準入力に渡すか、1行1行を ipchains コマンドの引数として指定することで、反映されます。

キーワード意 味 な ど
-A 指定したchainの最後にルールを追加する。
-D 指定したchainのルールを削除する。
-R 指定したchainのルールを変更する。
-I 指定したchain(の手前)にルールを追加する。
-C 指定したchainのチェックを行う。
chain チェインの指定。input,output,forward が もともとあるが、ユーザが新たに定義することもできる。
-p protocol プロトコルの指定。tcp,udp,icmp,all, あるいは数値(/etc/protocols を参照のこと)のいずれか。
-s source 送信元のアドレス、ポートの指定。書式は後述。
-d destination 宛先のアドレス、ポートの指定。書式は後述。
-j target 処理の仕方の指定。ACCEPT,DENY,REJECT, MASQ,REDIRECT, あるいはユーザが定義したchain のいずれか。 REJECT は ICMP メッセージを返す。 MASQ は NAPT(IP masquerade) で使用。 REDIRECT は透過 proxy で使用。
-i interface インタフェースの指定。! で否定になる。
-f フラグメントの指定。フラグメントされたパケットの場合に該当。
-l このルールに該当した場合、printk() 経由でログに残す。
-t mask TOS フィールドの解釈。and の mask と xor の mask の2つを指定 する。最初の mask との and をとり、2つ目の mask との xor を とって、該当するかどうかを判断する。(た、たぶん…)
-y TCP の SYN が立っていて ACK と FIN が落ちている場合に該当する。

source および destination の書式は以下の通りです。

 [!] address[/mask] [!] [port[:port]]

mask はネットワークアドレスのビット数の指定で、例えば、 192.168.1.0/24 だと、192.168.1.0〜255 が該当します。
port は、: でポートを2つ指定することで、範囲指定になります。
また、! は否定です。 まずは、デフォルトの /etc/sysconfig/ipchains の中を見てみます。
たしか、インストール時に、ワークステーションのファイアウォールを中で 指定したものだと思います。TCP の接続要求(SYN パケット)や UDP のほとんど を拒否していますので、クライアントとしてしか機能しないように思います。
# のところがコメントですが、実際は ipchains-restore 自体はコメントと 見なしてくれないと思います。
# /etc/init.d/ipchains が、# の行を grep -v して ipchains-restore に 渡してくれます。

 # input, forward, output をすべて許可にします。
 # これは ipchains-restore が解釈します。デフォルトの動作の指定です。
 ## 実際には、ipchains -P input ACCEPT などが実行されます。
 :input ACCEPT
 :forward ACCEPT
 :output ACCEPT
 # インタフェース lo から来るものはすべて許可にします。
 # 0/0 だとすべて該当します。
 -A input -s 0/0 -d 0/0 -i lo -j ACCEPT
 # TCP のポート 0〜1023 の SYN パケットを REJECT します。
 # つまり TCP の接続要求を拒否(ICMP Port Unreachable を返す)します。
 -A input -p tcp -s 0/0 -d 0/0 0:1023 -y -j REJECT
 # TCP のポート 2049(nfs) の SYN パケットを REJECT します。
 -A input -p tcp -s 0/0 -d 0/0 2049 -y -j REJECT
 # UDP のポート 0〜1023 を REJECT します。
 -A input -p udp -s 0/0 -d 0/0 0:1023 -j REJECT
 # UDP のポート 2049(nfs) を REJECT します。
 -A input -p udp -s 0/0 -d 0/0 2049 -j REJECT
 # TCP のポート 6000〜6009(X) の SYN パケットを REJECT します。
 -A input -p tcp -s 0/0 -d 0/0 6000:6009 -y -j REJECT
 # TCP のポート 7100(font server) の SYN パケットを REJECT します。
 -A input -p tcp -s 0/0 -d 0/0 7100 -y -j REJECT

次に、IPFW のところで書いた
ルールと 同様のものを書いてみます。
自マシンへの TCP のポート 80 と 21 への接続は許しますが、それ以外は DENY します。また、自マシンからのアクセスは許可します。

  -A input -s 0/0 -d 0/0 -i lo -j ACCEPT
  -A input -p tcp -s 0/0 -d 192.47.224.211 80 -y -j ACCEPT
  -A input -p tcp -s 0/0 -d 192.47.224.211 21 -y -j ACCEPT
  -A input -p tcp -s 0/0 -d 192.47.224.211 -y -j DENY
  -A input -p tcp -s 0/0 -d 192.47.224.211 ! -y -j ACCEPT
  -A input -s 0/0 -d 0/0 -j DENY

これらはすべて、input に関するルールです。output に関しては、すべて 通す(外に出ていく)設定になっています。
1行目は、lo に対しては全て通すという設定です。もともとデフォルトは 通すことになるので、書かなくても同様になると思いますが、念のために 書いておきます。
2〜4行目は、自マシンへの 80 および 21 への接続要求(SYN パケット)を通し、 それ以外の接続要求は DENY (ICMP も返さず捨てる)するという設定です。
5行目では、接続要求でない自マシン宛の TCP パケットは通すという設定 です。output に関してはすべて通しますので、自マシンからの接続要求は もちろんすべてのパケットが出ていきます。 そして、外部からの接続要求以外の TCP パケット(SYN+ACK も含む)はみな 自マシンに取り込まれますので、自マシンからの接続要求は許されることに なります。
6行目は、1〜5行目に該当しないものはすべて DENY するという意味になり ます。つまり、ICMP, UDP はすべて通さない設定になっています。
ちなみに、4行目は5行目と全く逆なので、4行目がなくても6行目が適用 されて外部からの接続要求が DENY されるはずですが、念のため入れてあり ます。
また、デフォルトを DENY にして、6行目をなくす方法も考えられます。

  :input DENY
  -A input -s 0/0 -d 0/0 -i lo -j ACCEPT
  -A input -p tcp -s 0/0 -d 192.47.224.211 80 -y -j ACCEPT
  -A input -p tcp -s 0/0 -d 192.47.224.211 21 -y -j ACCEPT
  -A input -p tcp -s 0/0 -d 192.47.224.211 -y -j DENY
  -A input -p tcp -s 0/0 -d 192.47.224.211 ! -y -j ACCEPT

3.2 NAPT(IP masquerade)

まず、IP forwarding が有効になっている必要があります。

  echo 1 > /proc/sys/net/ipv4/ip_forward

とすれば有効になりますし、起動時に有効になるよう仕組んだ方が楽かも しれません(rc.local に書くとか?)。
さて、設定ですが、同じく設定ファイル(/etc/sysconfig/ipchains) に 1行1ルールを書いていきます。

 :forward DENY
 ...中略
 -A forward -i external-IF -j MASQ

external-IF には、外部インタフェースを指定します。
最初の1行目は、ipchains-restore が解釈して、デフォルトの動作を DENY にします。つまり、ルールに該当しない場合は捨てられます。
# デフォルトでは ACCEPT になっていて、ルールに該当しない場合は通され ます。

4. 動作確認

4.1 コマンドでチェックする

ipchains コマンドでチェックを行うことができます。
例えば、以下のようなルールが設定されているとします。

  # ipchains -L
  Chain input (policy ACCEPT):
  target     prot opt     source                destination           ports
  DENY       tcp  ------  0.0.0.0/0            172.30.152.212        * ->   8888
  Chain forward (policy ACCEPT):
  Chain output (policy ACCEPT):

ここで、ipchains の -C オプションで確認をします。
書式は
前述 の通りですが、細かく指定する 必要があります。
# 足りない場合は、これが足りないと指摘してくれます。

  # ipchains -C input -p tcp -i eth0 -s 192.168.1.1 20000 -d 172.30.152.212 8888
  denied
  # ipchains -C input -p udp -i eth0 -s 192.168.1.1 20000 -d 172.30.152.212 8888
  accepted

1回目の場合、ルールにマッチしますので、denied という結果になります。
2回目の場合、プロトコルが udp のためマッチしません。よって、accepted という結果になります。
設定が間違っている場合は修正し、以下のように再設定を行います。

  /etc/init.d/ipchains restart

4.2 実際にアクセスしてチェックする

話を簡単にするため、デフォルトの状態から1つだけルールを設定します。
そのルールは、自マシンの 8888/tcp へのアクセスを DENY するものです。

  # ipchains -A input -p tcp -s 0/0 -d 172.30.152.212 8888 -j DENY
  # ipchains -L
  Chain input (policy ACCEPT):
  target     prot opt     source                destination           ports
  DENY       tcp  ------  anywhere             tamayo                any ->   8888
  Chain forward (policy ACCEPT):
  Chain output (policy ACCEPT):
  # cat /proc/net/ip_fwchains 
      input 00000000/00000000->AC1E98D4/FFFFFFFF - 10 0 6 0         0 \
      0       0         0-65535 8888-8888 AFF X00 00000000 0 0      DENY

/proc/net/ip_fwchains から読み込むと、設定されたルールの情報が得られ ます。

  チェイン名 送信元IP/マスク->宛先IP/マスク インタフェース fw_flg fw_invflg \
  プロトコル パケット数(上位32bit 下位32bit) バイト数(上位32bit 下位32bit) \
  送信元ポートの範囲 宛先ポートの範囲 TOSフィールドのマスク(and xor) \
  リダイレクションポート fw_mark 出力サイズ ターゲット

詳細は割愛しますが(net/ipv4/netfilter/ipchains_core.c や include/linux/netfilter_ipv4/ipchains_core.h などをご覧ください −実はよくわからなかったりしますが…)、パケット数とバイト数に注目し ます。ここで、DENY なところにアクセスしてから再度読み出してみます。

  # telnet 172.30.152.212 8888
  Trying 172.30.152.212...

  # cat /proc/net/ip_fwchains
      input 00000000/00000000->AC1E98D4/FFFFFFFF - 10 0 6 0         1 \
      0         60        0-65535 8888-8888 AFF X00 00000000 0 0      DENY

動作としても、DENY なので Trying ... のままになっていますが、パケット 数とバイト数がそれぞれ 1 と 60 になっており、ルールが適用されている ことがわかります。
設定が間違っている場合は修正し、前述のように再設定を行います。

Powered by Apache PostgreSQL Usupi Logo Kuri Logo
[Home] [Kuri] [Sysad] [Internet?] [Blog] [Java] [Windows] [Download] [Profile] [Flash] [-]
usu@usupi.org Last modified : Wed May 8 00:43:12 2002