iptables
iptables
「iptables」は、IPアドレスやポート番号により、通過するパケットのフィルタリングを行うプロセスです。これで何が実現できるかというと「ファイアウォール」が実現できます。(1台の専用サーバでも、もちろんこのフィルタリングは指定可能です。昨今は、防御処理を行うのは当たり前になってますので、フィルタリング処理は必要不可欠なものになっています)
これにより、不正なアクセス・使いたくない通路(ポート)はシャットアウトしてしまおう、という魂胆です。(ただし、完全に安全というわけではないという点には注意してください)パケットの入る側と出る側があり、これらは双方でフィルタリングの「ルール」を設定することが可能です。
また、ルータでの使用時などでのIPの変換機能(NAT)も備わっています。
フィルタリングの考え方
安全に行うには「すべてを拒んで、特定のを許す」という性悪説(?)で設定します。特に、リモートのサーバにてiptablesの設定をする場合、たとえばtelnetアクセス時に「iptables -F」「iptables -P INPUT DROP」などとするとすべてを拒んで(telnetアクセスすらも)「やっちゃいました!」となるので十分に注意してください。iptablesのフィルタリングはその場で反映されます。iptablesの指定は、コマンドラインで1行ずつ入力して実行してやってください。
iptables -F
にて、一度すべての情報を破棄します。この段階では「すべてがアクセスできる」状態ですので、十分に注意してください。ファイアウォール設定しているマシンの前で操作している場合(リモートからでない場合)、以下を指定して外からのアクセスを拒否状態にしてから設定しましょう。
iptables -P FORWARD ACCEPT iptables -P INPUT DROP iptables -P OUTPUT ACCEPT
これはデフォルトでどのような通過を設定するか、を指定しています。「FORWARD」にて通過(ルータとしての機能を持つ場合)の指定、「INPUT」にてサーバへの受信の指定、「OUTPUT」にてサーバからの送信の指定です。
リモートから設定している場合は、たとえばtenlet(ポート23)だけ通すようにして、INPUT(パケットの受信)を拒否にします。
iptables -A INPUT -p tcp --dport 23 -j ACCEPT iptables -A INPUT -p tcp --sport 23 -j ACCEPT iptables -P INPUT DROP
さて、ここで「INPUT」「OUTPUT」「FORWARD」などを掘り下げていきます。これらは「チェイン」と呼ばれ、サーバ内のパケットの流れにより以下のような構図になっています。関所のようなものと考えることができるかもしれません。
- INPUT
- 受信したパケットがサーバ自身のプロセスを処理する前に通ります。
- OUTPUT
- サーバ自身にて何らかの処理を行った後に、外部に出るときに通ります。
- FORWARD
- 対象サーバを経由するときにの通り道です。主にルータ機能をもったサーバでのフィルタリング設定を行います。
- PREROUTING
- パケットがサーバに入ってきたとき、パケットのアドレス変換を行う必要がある場合はここで変換処理を行います。
- POSTROUTING
- サーバからパケットが出るときに、パケットのアドレス変換を行う必要がある場合はここで変換処理を行います。
「INPUT」「OUTPUT」「FORWARD」は、IPアドレス・ポート番号によるフィルタリング処理を行います。これは、iptablesの「filter」テーブルとして使用します。
「PREROUTING」「POSTROUTING」「OUTPUT」にてIPアドレスの変換(NAT)を行います。これは、iptablesの「nat」テーブルとして使用します。
先ほどのtelnetの使用を許可する場合を元に説明してみます。
iptables -P FORWARD ACCEPT iptables -P INPUT DROP iptables -P OUTPUT ACCEPT iptables -A INPUT -p tcp --dport 23 -j ACCEPT iptables -A INPUT -p tcp --sport 23 -j ACCEPT
telnetの場合はサーバの内部での処理になりますので、「INPUT」「OUTPUT」だけに注目すればよいです。「INPUT」をデフォルトで禁止し、「OUTPUT」をデフォルトで許可することにより、パケット受信時はフィルタリングを行い、出ていくとき(送信時)はすべて通過するようにしています。
3-4行目にて「-A INPUT」ですので、ローカルのプロセス(telnet処理)を処理する前に、3行目では、送信先のポート番号が23のもの(--dport 23)の通過を許可(-j ACCEPT)しています。4行目では、送信元のポート番号が23のもの(--sport 23)の通過を許可(-j ACCEPT)しています。
では、細かく見ていきましょう。その前に、ポート番号の種類について有名なのを洗い出しておきます。
よく使うポート番号
プロトコル | ポート番号 | 意味 |
---|---|---|
icmp | 0/8 | ping(生存確認) |
udp | 53 | dns(Domain Name System) |
tcp | 20/21 | ftp(ファイル転送) |
tcp | 22 | ssh(セキュリティ(SSL)を考慮したリモートアクセス) |
tcp | 23 | telnet(リモートアクセス) |
tcp | 25 | smtp(メール送信) |
tcp | 80 | http(Webブラウザとのやりとり) |
tcp | 110 | pop3(メール受信) |
tcp | 443 | https(セキュリティ(SSL)を考慮したWebブラウザとのやりとり) |
フィルタリングする場合は、使用するサーバの目的に合わせて「必要なポートのみ空ける」ようにしましょう。
iptablesでは「--dport」「--sport」オプションとして、ポート番号でフィルタリング設定を行います。
フィルタリング情報を見る
- iptables -L
- フィルタリングの情報を一覧表示します。
- iptables -L -t nat
- NAT(IP変換)の情報を一覧表示します。
pingを許可する
iptables -A INPUT -p icmp --icmp-type 8 -j ACCEPT iptables -A INPUT -p icmp --icmp-type 0 -j ACCEPT
「-A INPUT」にて、サーバに入ってくる(つまりクライアントマシンからのアクセス)に対する制御を行います。「-p icmp」にてプロトコルタイプはICMPです。「--icmp-type 8 / --icmp-type 0」をそれぞれ指定することにより、pingの問い合わせを有効にしています。
ローカルからのアクセスを許可する
iptables -A INPUT -i lo -j ACCEPT
これは自分自身(サーバ自身)のやりとりを許可しています。
HTTPを許可する
iptables -A INPUT -p tcp --dport 80 -j ACCEPT iptables -A INPUT -p tcp --sport 80 -j ACCEPT
「-p tcp」でプロトコルTCPの指定、「--dport 80」で宛先(distination)のポート番号80、「--sport 80」で送信元(source)のポート番号80を指定しています。HTTPのポートは80ですので、これでに対するINが有効になります。
ここで、「どこから入るのを許可するか」を明確にします。たとえば、外の世界(インターネット)だと「ppp0」になりますし、NICの指定「eth0」などを指定することで制限をかけます。
iptables -A INPUT -i ppp0 -p tcp --dport 80 -j ACCEPT iptables -A INPUT -i ppp0 -p tcp --sport 80 -j ACCEPT
これにより、「どこから入ったポート何番に対するINPUTを許可する」のように固めていくことができます。
FTPを許可する
iptables -A INPUT -p tcp --dport 20 -j ACCEPT iptables -A INPUT -p tcp --sport 20 -j ACCEPT iptables -A INPUT -p tcp --dport 21 -j ACCEPT iptables -A INPUT -p tcp --sport 21 -j ACCEPT
HTTPの場合と同じです。ポート番号だけ変更してます。以下同様です。
これも発展させてセキュリティを高めてみましょう。ローカルのIPアドレス(192.168.0.xxx)しか入るのを許したくない場合、以下のように指定します。
iptables -A INPUT -s 192.168.0.0/24 -p tcp --dport 20 -j ACCEPT iptables -A INPUT -s 192.168.0.0/24 -p tcp --sport 20 -j ACCEPT iptables -A INPUT -s 192.168.0.0/24 -p tcp --dport 21 -j ACCEPT iptables -A INPUT -s 192.168.0.0/24 -p tcp --sport 21 -j ACCEPT
「-s 192.168.0.0/24」というのを新たに追加しました。「/24」はサブネットマスクで、「255.255.255.0」でマスクする、という意味になります。これにより、「192.168.0.0 - 192.168.0.255」からのINPUTを許可しています。つまり、このIPアドレス以外からのFTPアクセスは無効となります。
これはFTPだけでなく、HTTPでもTELNETでももちろん有効ですので、LANを構築する場合や外部アクセスの制限を加えたい場合にぜひとも考慮すべきかもしれません。
DNSを許可する
DNSによる名前解決には、UDPプロトコルを使用します。
iptables -A INPUT -p udp --sport 53 -j ACCEPT iptables -A INPUT -p udp --dport 53 -j ACCEPT
これでDNS(ポート53)の通過を許可しています。
今まで、常に「--sport」「--dport」の指定を対にしていましたが、一方通行でいい場合もあります。どっちが送信元(--sport)で送信先(--dport)か、というのがごっちゃになりますが 用途に合わせて使い分けるに超したことはありません。
iptablesの情報はどこにある?
なお、iptablesにて同じポートの指定を行った場合に情報は上書きされます。変更はダイレクトに反映されますが(たとえばtelnet中にtelnetのポートをiptablesで閉じてしまうと、そこで通信が途絶えてしまう(外部からの操作ができなくなる))変更は一時的なもので、サーバを再起動したときにはクリアされてしまいます。再起動しても大丈夫なようにセーブするには、以下のコマンドを実行します。
iptables-save
これでサーバを再起動してもiptablesの設定が効いてます。
service iptables save
の保存のほうが確実です。
ではもう少し踏み込んで・・・・。iptablesの情報はどこに保存されてるのでしょうか?
「/etc/sysconfig/iptables」内にテキストで記述されてます。これをフィルタリング時に見ているようです。ここをダイレクトに変更することでフィルタ変更できますが、安全のために直接は変更しないほうがいいでしょうね。あくまでも本当に設定が効いているのか、という確認のためだけに閲覧するのがよいかも。
と、iptablesによるフィルタリングについて、概要的な部分を書いてみました。主に1台のサーバでのINPUT制限でしたが、複数サーバが絡んだりルータのファイアウォールとしてのiptables設定になると、もっと複雑になります。
また、どの解説サイトでもそうですが、iptablesの設定の詳細を載せるところはありません。というのも、このiptables設定自身が「どこを固めている」というのを示すことになる、逆を返せば「それ以外は通ることができる」ですので閲覧できてしまうと穴を見つけることができてしまいます。このサイトでも汎用的な説明しかしてませんが、独自サーバで設定される場合にはiptablesの情報は漏れない(公開しない)ようにしましょう。
Future's Laboratory 技術格納庫 2004-2013 Yutaka Yoshisaka.