ホストレベルセキュリティの総仕上げ:ゼロから始めるLinuxセキュリティ(2)(2/3 ページ)
今回は、前回から行っているホストレベルのセキュリティ対策を完成させる。Linuxでファイアウォールを構築するには、まずホストレベルのセキュリティが重要になる。セキュリティホールだらけのファイアウォールなど何の役にも立たないからだ。
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サービスへの接続を許可
#!/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の設定作業は終わりです。これはあくまでも設定例ですので、環境に合わせて修正してください。
フィルタリングの動作確認
設定作業が終わったらパケットフィルタリングの確認を行います。nmapとnetcatというプログラムを使って確認してみます。
- 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.