2011/01/07

DTIのVPSサービスで、Default: DROPなiptablesの設定をしてみた

OpenVZを使っているDTIのVPSサービスでは、各VM内からはカーネルモジュールを動的に読み込む事ができません。

あらかじめ準備されたカーネルにはip6tablesが使うモジュールが設定されていないために、コマンドを実行することができない事に今日になって気がつきました。

IPv6対応を謳うサービスで、サーバ用インスタンスを提供しているのであれば、セキュリティを強化するための手段が一つない事になるので、少しがっかりしました。

さて気をとりなおして、IPv4用にiptablesの設定をしたので、その作業メモです。

IPv4用にiptablesを設定する

特別な設定はしませんが、INPUT/OUTPUT/FORWARDのデフォルトルールをDROPにした上でルールを設定しています。

iptablesのログをCouchDBに入れて郵便番号情報と似たようなインタフェースで検索できるようにしていますが、サンプルで動かしている自宅の自作ブロードバンドルータのログをいろいろみていると22番ポート(ssh)と445番ポート(microsoft-ds/CIFS)へのアクセスが非常に多いのがわかります。

あとはDDoSのためにIPアドレスを詐称したパケットが捏造されているのか、ICMPパケットもありましたし、いきなりACK,SYNが送られてきているケースもあるようでした。

いくらポートを閉じているとはいえ、いろいろ迷惑をかけるのもあれなので、VPSサーバでもiptablesを設定して、積極的にDROPするようにしています。

iptables設定用スクリプト全体

#!/bin/bash

umask 022
PATH=/usr/sbin:/sbin:$PATH

## reset all settings
iptables -F
iptables -Z
iptables -X

## default rule is DROP, but all unexpected connection will be logged later.
iptables -P FORWARD DROP
iptables -P INPUT DROP
iptables -P OUTPUT DROP

## define logging rules
iptables -N loaccept
iptables -A loaccept -m limit --limit 30/minute -j LOG --log-prefix "fw local accept "
iptables -A loaccept -j ACCEPT
iptables -N fwaccept
iptables -A fwaccept -m limit --limit 30/minute -j LOG --log-prefix "fw forward accept "
iptables -A fwaccept -j ACCEPT
iptables -N fwdrop
iptables -A fwdrop -m limit --limit 30/minute -j LOG --log-prefix "fw forward drop "
iptables -A fwdrop -j DROP
iptables -N inaccept
iptables -A inaccept -m limit --limit 30/minute -j LOG --log-prefix "fw input accept "
iptables -A inaccept -j ACCEPT
iptables -N indrop
iptables -A indrop -m limit --limit 30/minute -j LOG --log-prefix "fw input drop "
iptables -A indrop -j DROP
iptables -N outaccept
iptables -A outaccept -m limit --limit 30/minute -j LOG --log-prefix "fw output accept "
iptables -A outaccept -j ACCEPT
iptables -N outdrop
iptables -A outdrop -m limit --limit 30/minute -j LOG --log-prefix "fw output drop "
iptables -A outdrop -j DROP

## allow all loopback connection
iptables -A INPUT  -i lo -j loaccept
iptables -A OUTPUT -o lo -j loaccept

## logging all connection
iptables -A INPUT -p icmp --icmp-type echo-request -j inaccept
iptables -A INPUT -p icmp --icmp-type redirect -j indrop
iptables -A INPUT -m state --state ESTABLISHED,RELATED -j ACCEPT
iptables -A INPUT -m state --state NEW -p tcp --dport 4949 -j inaccept  ## for munin
iptables -A INPUT -m state --state NEW -p tcp --dport 443 -j inaccept   ## for web
iptables -A INPUT -m state --state NEW -p tcp --dport 80 -j inaccept    ## for web
iptables -A INPUT -m state --state NEW -p tcp --dport 23 -j inaccept    ## for ssh
iptables -A INPUT -m state --state NEW -p tcp --dport 25 -j inaccept    ## for smtp
iptables -A INPUT -m state --state NEW -p tcp --dport 53 -j inaccept    ## for dns
iptables -A INPUT -m state --state NEW -p udp --dport 53 -j inaccept    ## for dns
iptables -A INPUT -j indrop
iptables -A OUTPUT -m state --state ESTABLISHED,RELATED -j ACCEPT
iptables -A OUTPUT -m state --state NEW -j outaccept
iptables -A OUTPUT -j outdrop
iptables -A FORWARD -j fwdrop

## uncomment this after checking above settings.
## iptables-save > /etc/network/iptables.restored

大抵の方はSSH用ポートが変更されているので、ここで"23"と設定しているSSH用のポート番号は3843番などに適宜変更する必要がありそうです。

一度スクリプトを実行して動作を確認してから問題がなければ、再起動後も適用されるように最後のコメントアウトを外すか、手動でiptables-saveを実行して、/etc/network/iptables.restoredファイルを更新しておきます。

そして、作成したファイルが起動時に読み込まれるように/etc/network/if-up.d/iptablesファイルを作成しておきます。

#!/bin/bash

BASEDIR="$(dirname $0)"
iptables-restore < "${BASEDIR}/../iptables.restored"

最後に実行権限を与えておきます。

$ sudo chmod 700 /etc/network/if-up.d/iptables

これでIPv4用の設定は以上で、ログの内容は /var/log/kern.log に書き出されます。

syslogの機能をフルに使うのであれば、 -j LOG行で--log-level debugなどの設定をポリシーに従って設定して、facilityを分けたり適切なメッセージを送信する事もできると思います。

0 件のコメント: