概要
この文章では、iptablesを使ったパケットフィルタリングの簡単な設定の仕方を紹介しています。パケットフィルタリングの実際の運用に関しては各自で責任をお取りください。筆者は一切の責任を負いません。また内容は、2001年10月現在のものです。最新の情報も合わせて収集することをおすすめします。
セキュリティを考えて、sshやtcp_wrapperを使っている、という人は結構いるかと思います。セキュリティは多層の防御が必要です。いくら用心してもやりすぎたということはありません。もっともコストや利便性を度外視しては使えるシステムにはなりません。可用性もりっぱなセキュリティシステムに求められる性質の一つです。パケットフィルタリングでは、必要なサービスのためのパケットを通し、それ以外のパケットを遮断することを実現します。利便性を維持したままでセキュリティーを向上できるわけです。これをやらない手はありません。そこでLinux kernel 2.4で導入されたnetfilterを使って、パケットフィルタリングによる壁をつくる方法の基本を説明します。
各ディストリビューションのパッケージでインストールできる場合は次節にすすんでください。ここではソースからインストールする方法について記述しています。まず、netfilterのページにいってtar ballをおとしてきます。その後、
%
tar xvzf /some/where/iptables-1.2.2.tar.gz
%
cd iptables-1.2.2
%
./configure && make
%
su
#
make install
でインストールします。
次にkernelを再構築します。必要であれば、iptablesの配布に含まれている(そのうちkernelに含まれていない)patchをあてます。
#
cd patch-o-matic
#
./runme
付属のドキュメント、マニュアルに目を通してください。HOWTO、FAQなども参考になります。それだけで十分わかってしまえば、この文章の以降はまったく読む必要はありません。以下ではコマンドのオプション等はわかる/調べられることを前提とします。具体例をみながら、雰囲気をつかんでもらうのが狙いです。
とりあえずIP masqueradeを使いたい、という場合には次のようにします。
#
iptables -t nat -A POSTROUTING -o $PPPINTERFACE -j MASQUERADE
#
echo 1 > /proc/sys/net/ipv4/ip_forward
$PPPINTERFACEはpppのinterface(ppp0など)です。2行目のip_forwardの設定は忘れられがちなので注意してください。
セキュリティを考える時にはポリシーというものを決める必要があります。どのような通信を許すかをはっきり決めないといけません。そのためにはそのマシンがどのような目的に使われるかもはっきりさせなくてはいけません。まず、基本的なクライアントであるとします。
次にネットワーク経由ですることをずらずら並べてみます…web, mail, ftp, ssh…例えばこの4つを可能にするとします。sshはdaemonも起動されており、外からのloginを許すことにします。出ていく方のパケットはなにもしないことにして、最低限入ってくる方の制限をすることを考えます。
パケットフィルタリングでは、ルールが設定されており、入ってくるパケットを検査して、設定したルールに従って、通したり、通さなかったりします。そのルールをこれから設定していきます。どのルールにもマッチしないパケットはデフォルトのポリシーによって処理されます。そこでまずこのデフォルトのポリシーを設定します。
#
iptables -P INPUT DROP
#
iptables -P OUTPUT ACCEPT
#
iptables -P FORWARD ACCEPT
デフォルトではパケットはなにひとつ受けとりません。こうしておいて、通すパケットを明示的に指定していきます。通すパケットを最小限にすることが大事です。
次に入ってくるのを許可するパケットを指定するルールを設定します。まず、lo interfaceを通るパケットは通します。
#
iptables -A INPUT -i lo -j ACCEPT
次に、既にconnectionが張られている通信を許可します。これでconnectionをはるためにbindしたポートがわからなくてもパケットの流入を許可できます。web,mail,ssh(client)についてはこれで十分です。
#
iptables -A INPUT -m state --state ESTABLISHED,RELATED -j ACCEPT
このstateによるパケットフィルタリングはとても強力で、2.4のnetfilterの賜物です。conntrackという機構により、established(接続が確立している)なパケットはもとより、related(接続を許可したパケットのプロトコルに関連のあるftp-dataのようなパケット)の接続も許可できます。
次にicmpを許可します。これはポリシーによるので不許可にするべきな場合もあります。不正確ですがわかりやすくいうと、pingを通すか通さないかです。(ECHOなどは落してもFRAG_NEEDEDは通すようにしてください)。
#
iptables -A INPUT -p icmp -d $MYSELF -j ACCEPT
$MYSELFは自分のIP addressです。明示的にIPを指定するとbroadcastには応えなくなります。このあたりもポリシーによります。
さて、残ってるのはftpとssh(daemon)ですが、これはどちらもconnectionをこちらからはるのではなく、受けつける必要があります。sshdの方は単にいままで通りACCEPTするだけです。ftpの方は、passiveでないftp-data connectionを受けつけるのですが、これは上述のrelatedによって通すことができます(要ip_conntrack_ftp, ip_nat_ftp)。ですから、
#
iptables -A INPUT -p tcp -d $MYSELF --dport ssh -j ACCEPT
でいいことになります。
後のパケット…例えば、telnetでつないでこようとしたパケットなどは捨てられます。DROPは捨ててもエラーを示すパケットを返しません。返すようにする場合はREJECTを使います。これらの捨てられるパケットをログにとっておくとよいでしょう。ログにとるには次のようにします。
#
iptables -A INPUT -j LOG --log-prefix "Bad packet: "
外のネットワークからのパケットとローカルネットワークからのパケットとでは扱いを変えたいということはよくあることでしょう。それにはchainを用います。chainはサブルーチンみたいなもので、マッチしたパケットのtargetに書かれ、そのchainの一連のルールが適用されます。chainの終端までくると、もとのchainの次のルールからマッチを再開します。実はINPUT,OUTPUT,FORWARDもchainで特別にbuilt-in chainなどと呼ばれます。
まずchainを作ります。
#
iptables -N localnet
ローカルネットワークからのパケットを、このchainに移らせるには次のようにします。
#
iptables -A INPUT -s $MYNET -d $MYSELF -j localnet
ローカルネットワークからsunrpcへのパケットを許可するには次のようにします。
#
iptables -A localnet --dport sunrpc -j ACCEPT
ローカルネットワークからだからパケット全部素通しでいいや…という設定をするのは楽ですがおすすめできません。万が一内部のマシンが感染した時に被害が拡大してしまうからです。ローカルネットワークからのパケットといえども通すパケットは最低限に抑える設定をしてください。
ここでは、その他のいろいろな例を挙げていきます。まず、web serverである場合はどうすればいいでしょう。簡単です。www portを受けつけるようにします。
#
iptables -A INPUT -p tcp -d $MYSELF --dport www -j ACCEPT
うるさいnetbiosのパケットを通してないのはいいのですが、ログが多くて困る…そういう時は明示的にDROPします。そうすればログにとられません。
#
iptables -A INPUT -d $MYSELF --dport netbios-ns -j DROP
#
iptables -A INPUT -d $MYSELF --dport netbios-dgm -j DROP
#
iptables -A INPUT -d $MYSELF --dport netbios-ssn -j DROP
IRCのDCCで、プライベートアドレスからの接続要求はそのままでは通りません。これを使いたいという場合は、ftpのように専用のmoduleを使う必要があります。このmoduleは2.4.7現在、kernelにとりこまれてません。iptablesのpatch-o-maticを使う必要があります。IRC関連のpatchをあてて、kernelを設定して再構築してください。後はIRCのserverのportを指定してmoduleを組み込みます。portはコンマで区切って複数指定できます。
#
modprobe -k ip_nat_irc ports=6667
#
modprobe -k ip_conntrack_irc ports=6667
プライベードアドレスを持ったclientがパケットフィルタリングをしてる場合にはip_conntrack_ircだけロードしてください。そうすればrelatedで通るようになります。
kernelには他にもセキュリティに関する設定がいくつかできます。例えば、IP spoofingを防ぐrp_filterやsyn cookieなどがあります。syn cookieはkernelを設定してもdefaultでは有効になりません。以下のようにします。
if [ -f /proc/sys/net/ipv4/tcp_syncookies ]; then echo 1 > /proc/sys/net/ipv4/tcp_syncookies fi