連載
» 2001年09月18日 00時00分 公開

ゼロから始めるLinuxセキュリティ(2):ホストレベルセキュリティの総仕上げ (2/3)

[大貫大輔,株式会社ラック/不正アクセス対策事業本部]

ipchainsによるパケットフィルタリング

 Linuxには、パケットフィルタリング機能としてipchainsという実装があります。これは、kernel 2.2系以降に対応しているものです。Red Hat Linux 7.1Jはkernelは2.4系であり、ipchainsとは別にkernel 2.4系に対応しているiptablesという実装もあるのですが、今回はipchainsを用いたパケットフィルタリングについて説明します。iptablesを使うにはkernelの再構築が必要になりますが、ipchainsはそのまま使えるので採用しました。iptablesを使うためのkernelの再構築については、別の機会に説明させていただきます。

フィルタリングルールの設計

 まず、最初に行うのはルールを考えることです。これは、設定前に十分に考える必要があります。ルールの検討を怠ると思ったよりも甘い設定になってしまったり、逆に制限が強すぎて思いどおりにサービスを提供できなくなってしまいます。

  • 基本ポリシーとして、すべてのサービスに対して全ホストからのアクセスを不許可とする
  • どのサービスに対して、どこからのアクセスを許可するのかを決定する
  • 最後にICMPなどについて決定する

 どこからのアクセスを許可するかなどを決めるとき、まずは必要なものを紙に書き出しましょう。その後、ネットワークフロー図に起こしましょう。図にすると分かりやすくなります。

 まずは、現在のルールを確認しましょう。現在のルールの確認は以下のようにします。

# /sbin/ipchains -L -n

 ipchainsコマンドのオプションについては、man ipchainsを参照してください。

フィルタリングスクリプトの作成

 ipchainsはコマンドベースで設定します。ipchainsの設定方法についてある程度理解できたらスクリプトを作成しましょう。1つ1つのルールを設定するのに毎回コマンドを実行するのは大変ですし、人為的なミスが発生する可能性も高くなります。

 以下に簡単なスクリプト(/usr/local/bin/packetfilter)の例を挙げておくので参考にしてください。例では、対象となるサーバをSMTPサーバとしています。そして、次のような方針で設計されています。

  • すべてのサービスに対し、すべてのホストからのアクセスを拒否
  • Loopbackアドレスについてはすべて許可
  • 特定のネットワークアドレスに対し、echo reply、echo requestを許可
  • DNSサーバに対し、名前解決要求を許可
  • メンテナンスのために、特定のホストからsshサービスへの接続を許可
  • すべてのホストからSMTPサービスへの接続を許可
注:第三者による不正中継を禁止する設定などは、アプリケーション(SMTPサーバ)で行ってください。

#!/bin/sh 
 
#IPアドレス、ネットワークアドレスの情報を変数とする 
MYHOST='192.168.0.1'            #自分自身のアドレス 
LOCALNET='192.168.1.0/24'       #ローカルネットワークアドレス 
MAINTHOST='192.168.1.100'       #メンテナンス用のホスト 
ANY='0.0.0.0/0'                 #すべてのホスト 
 
#すべてのルールを削除する 
/sbin/ipchains -F input 
 
#すべてのアクセスを拒否する 
/sbin/ipchains -P input DENY 
/sbin/ipchains -P forward DENY 
/sbin/ipchains -P output DENY 
 
#Loopbackアドレスはすべて許可とする 
/sbin/ipchains -A input -s 127.0.0.1 -d 127.0.0.1 -i lo -j ACCEPT 
/sbin/ipchains -A output -s 127.0.0.1 -d 127.0.0.1 -i lo -j ACCEPT 
 
#ローカルネットワークに対しては相互にecho requestとecho replyを許可する 
/sbin/ipchains -A input -p icmp -s $MYHOST --icmp-type8 -d $LOCALNET -j ACCEPT 
/sbin/ipchains -A output -p icmp -s $LOCALNET --icmp-type 0 -d $MYHOST -j ACCEPT 
/sbin/ipchains -A output -p icmp -s $LOCALNET --icmp-type 8 -d $MYHOST -j ACCEPT 
/sbin/ipchains -A input -p icmp -s $MYHOST --icmp-type 0 -d $LOCALNET -j ACCEPT 
 
#DNSサーバに対し、名前解決を許可する 
/sbin/ipchains -A output -p udp -s $MYHOST -d $DNS 53 -i eth0 -j ACCEPT 
/sbin/ipchains -A input -p udp -d $DNS 53 -s $MYHOST -i eth0 -j ACCEPT 
 
#メンテナンス用ホストからのsshを許可する 
/sbin/ipchains -A input -p tcp -s $MAINTHOST -d $MYHOST 22 -i eth0 -j ACCEPT 
/sbin/ipchains -A output -p tcp -d $MYHOST 22 -s $MAINTHOST -i eth0 -j ACCEPT 
 
#すべてのホストからのSMTPを許可する 
/sbin/ipchains -A input -p tcp -s $ANY -d $MYHOST 25 -i eth0 -j ACCEPT 
/sbin/ipchains -A output -p tcp -d $MYHOST 25 -s $ANY -i eth0 -j ACCEPT

 このスクリプトを/usr/local/bin/packetfilterとして保存したら、スクリプトに実行権限を与えて実行します。

# chmod +x /usr/local/bin/packetfilter
# /usr/local/bin/packetfilter

 現在のルールを確認し、実際に設計どおりの設定になっているか確認してください。

# /sbin/ipchains -L -n

 ルールがきちんと設定されていたら、設定を保存しましょう。

# /sbin/ipchains-save

 以上でipchainsの設定作業は終わりです。これはあくまでも設定例ですので、環境に合わせて修正してください。

フィルタリングの動作確認

 設定作業が終わったらパケットフィルタリングの確認を行います。nmapnetcatというプログラムを使って確認してみます。

  • nmap
    ポートスキャン用のプログラムです。
  • netcat
    TCP、UDPで任意のポートでLISTENさせたりすることができます。

 MAINTHOST(192.168.1.100)からテストを行うと仮定します。このホストからは、22/TCP、25/TCPの2つのポートが空いているように見えるはずです。実際にサービスを提供しているポートが22/TCPと25/TCPしかなければ完全なテストとはいえません。ほかにもサービスを提供しているポートが存在し、かつそのポートがフィルタリングされることを確認したいからです。そこで、netcatを使います。

 netcatでTCPの1000番ポートをLISTENさせます。

# netcat -l -p 1000 &

 netstatコマンドを使って確認します。

# netstat -ant 
 
Active Internet connections (servers and established) 
Proto Recv-Q Send-Q Local Address        Foreign Address      State 
tcp        0      0 0.0.0.0:22           0.0.0.0:*            LISTEN 
tcp        0      0 0.0.0.0:25           0.0.0.0:*            LISTEN 
tcp        0      0 0.0.0.0:1000         0.0.0.0:*            LISTEN

 この状態で、nmapを使ってポートスキャンを実行します。

# nmap -sT 192.168.0.1 
 
Starting nmap V. 2.54BETA28 ( www.insecure.org/nmap/ ) 
Interesting ports on atmarkit (192.168.0.1): 
(The 1541 ports scanned but not shown below are in state: closed) 
Port       State       Service 
22/tcp     open        ssh 
25/tcp     open        smtp

 上記のような結果を得ることができれば、フィルタリングは成功です。

コラム:ipchainsのログを取る方法

 ipchainsでは、-lオプションを付けることでログを取得できます。ipchainsのルールを設定するスクリプトを編集します。ここではsshに関するルールを例にします。

/sbin/ipchains -A input -p tcp -s $MAINTHOST -d $MYHOST 22 -i eth0 -j ACCEPT -l
/sbin/ipchains -A output -p tcp -d $MYHOST 22 -s $MAINTHOST -i eth0 -j ACCEPT -l

 次に、/etc/syslog.confを修正します。

kern.info                       /var/log/ipchains.log

 touchコマンドを使って、ログ用のファイルを作成します。

# touch /var/log/ipchains.log

 最後に、syslogにハングアップシグナルを送ります。


Copyright © ITmedia, Inc. All Rights Reserved.

RSSについて

アイティメディアIDについて

メールマガジン登録

@ITのメールマガジンは、 もちろん、すべて無料です。ぜひメールマガジンをご購読ください。