iptables

Takekawa Hiroshi [FAMILY Given]

概要

この文章では、iptablesを使ったパケットフィルタリングの簡単な設定の仕方を紹介しています。パケットフィルタリングの実際の運用に関しては各自で責任をお取りください。筆者は一切の責任を負いません。また内容は、2001年10月現在のものです。最新の情報も合わせて収集することをおすすめします。


目次

iptablesの簡単な使い方
まずインストール
なにはなくともmasquerade
ポリシーを決める
ルールを設定する
chainを活用
具体例いろいろ
その他
改訂履歴

iptablesの簡単な使い方

セキュリティを考えて、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なども参考になります。それだけで十分わかってしまえば、この文章の以降はまったく読む必要はありません。以下ではコマンドのオプション等はわかる/調べられることを前提とします。具体例をみながら、雰囲気をつかんでもらうのが狙いです。

なにはなくともmasquerade

とりあえず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を用います。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

改訂履歴

2001/10/19: 第一版

2006/01/06: 第二版 (Akira Ueda さんの指摘による訂正。ついでに読み直して加筆)