iptables は Linux カーネル・ファイアウォールのテーブルを管理するアプリケーションです。iptables を使用する場合、ファイアウォールの変更や一般的なシステム管理作業を行う上で、カーネルやカーネル内にある実際のテーブルについて事前に理解している必要がありません。
一部の Linux ディストリビューションではデフォルトで iptables が有効になっています。しかし経験の浅いユーザーの場合は、ネットワークに関する問題を避けるために iptables を完全に無効にするように推奨することが一般的です。この記事を読むことで、必要に応じて iptables を簡単に設定して操作できるようになるはずです。
iptables と言うと、Linux カーネル・レベルのコンポーネントを指す場合がありますが、この記事で iptables と言う場合はすべて、Linux ディストリビューションで使用されるプロトコル (ipv4、ipv6、ARP テーブルなど) を制御するアプリケーションのみを指すものとします。
他の Linux アプリケーションと同様、コマンドライン・インターフェースまたはプレーンテキスト・ファイルで iptables を構成することができます。そのため、テキスト・エディターで iptables を編集することができます。iptables の構成を変更するのは簡単ですが、平均的なファイアウォール・アプライアンスでは大半の設定や構成がグラフィカル・インターフェースによって行われるため、それらに比べると iptables の構成の変更は面倒に思えるかもしれません。iptables を使用してグラフィカル・インターフェースでファイアウォールを管理するアプリケーションもありますが、この記事ではネイティブ環境で、つまり Linux のターミナル・ソフトで iptables を構成する方法について説明します。
Linux のターミナル・ソフト (コンソールやターミナル・エミュレーターとも呼ばれます) を苦もなく使えるレベルの開発者であれば、これから説明する例や構成方法を活用できるはずです。コマンドライン・インターフェースは iptables の構成をするための主要な手段であり、ターミナル・ソフトはコマンドラインにアクセスするためのアプリケーションです。
この記事で紹介するファイアウォール・ルールの大部分は、とても簡単に理解することができ、また他のサーバーに容易に移植することができます。iptables を使用すれば、こうした特徴のおかげで、応答しなくなったハードウェアに対処する際の時間を大幅に節約することができます。
この記事の話題の中心は iptables であり、おそらく皆さんの環境には既に iptables がインストールされていることと思いますが、この記事では nmap という強力なアプリケーションも使用します。
この先に進む前に、nmap がインストールされていることを確認してください。この効果的なネットワーク・スキャナーは Debian や Ubuntu にインストールすることができます。
リスト 1. Debian や Ubuntu に nmap をインストールする
sudo apt-get install nmap |
ここではカーネル・レベルで変更を行うため、ルート権限が必要です。
リスト 2 はサーバーに現在適用されているルールを示しています。この記事では、現在使用されているルールを確認したり、変更に成功したことを確認したりするために、リスト 2 のコマンドを繰り返し使用します。
リスト 2. 現在適用されているルール
root@desktop:~# iptables -L Chain INPUT (policy ACCEPT) target prot opt source destination Chain FORWARD (policy ACCEPT) target prot opt source destination Chain OUTPUT (policy ACCEPT) target prot opt source destination |
リスト 2 は iptables に対し、ファイアウォールに現在適用されているルールをすべて表示するように指示しています。その指示は -L フラグによって行われます。
出力にはチェーン (Chain) も表示されています。iptables のチェーンは、特定のタイプのトラフィックを許可するためのファイアウォール内のセクションと考えることができます。例えばプライベート・ネットワークからインターネットへのトラフィックをすべてブロックするためには、そのルールを OUTPUT チェーンに設定します。同様に、受信トラフィックに影響するルールはすべて INPUT チェーンに含める必要があります。
これら 3 つのチェーンはそれぞれファイアウォール内の 1 つのタイプのアクティビティーに適用されます。この段階では、まだ何も設定されていません。つまり何も制限がないため、すべてのネットワーク・トラフィックを送受信することができます。
Chain INPUTChain FORWARDChain OUTPUT
この先を続ける前に、サーバーをロックダウンした後と比較するために、サーバーのどのポートが開いているかを確認しておく必要があります。先ほど触れたように、nmap はネットワークのセキュリティー情報を得るための強力なコマンドライン・ツールです。リスト 3 はネットワーク上のリモート・サーバーで nmap を実行した場合の出力を示しています。
リスト 3. nmap を使用してネットワークをスキャンする
~ $ nmap 10.0.0.120 Starting Nmap 5.35DC1 ( http://nmap.org ) at 2010-11-21 20:44 EST Nmap scan report for 10.0.0.120 Host is up (0.012s latency). Not shown: 991 closed ports PORT STATE SERVICE 22/tcp open ssh 25/tcp open smtp 53/tcp open domain 80/tcp open http 631/tcp open ipp 3306/tcp open mysql 4001/tcp open unknown 5900/tcp open vnc 8080/tcp open http-proxy Nmap done: 1 IP address (1 host up) scanned in 6.57 seconds |
たくさんのポートが開いています。これから説明する何ステップかで iptables を構成すると、上記の結果が変わる様子がわかります。
iptables にファイアウォール・ルールを設定する方法には、直接ルールを編集、追加する方法と、プレーンテキスト・ファイルでルールを編集し、そのファイルをルールとして提供する方法があります。私の好みはテキスト・ファイルを使用して変更を適用する方法です。テキスト・ファイルとして作成すると、ほとんどの場合は構文エラーを容易に見つけることができます。直接ルールを編集、追加する方法には、サーバーをリブートすると、編集内容が保存されずに消えてしまうという問題があります。ファイルを編集する前に、現在のルールをエクスポートするように iptables に指示することで、エクスポートされたファイルを初期テンプレートとして使用するようにしてください。
リスト 4. ルールをファイルに保存する
root@desktop:~# iptables-save > /etc/iptables.rules root@desktop:~# cat /etc/iptables.rules # Generated by iptables-save v1.4.4 on Sun Nov 21 14:48:48 2010 *filter :INPUT ACCEPT [732:83443] :FORWARD ACCEPT [0:0] :OUTPUT ACCEPT [656:51642] COMMIT # Completed on Sun Nov 21 14:48:48 2010 |
ここでは iptables-save コマンドを使用し、その出力を /etc ディレクトリーのテキスト・ファイルにリダイレクトしました。また、続けてファイルの内容を表示することで、このファイルが私のマシンでどのように表示されるかを皆さんが理解できるようにしました。
ルールの設定で最初に必要なことの 1 つは、確立されている接続でトラフィックを受信できるようにすることです。ファイアウォールの背後にあるプライベート・ネットワーク内から、制約なしにネットワーク・データを送受信できるようにしたい場合には、これが必要になります。リスト 5 では、iptables に対してコマンドを発行することで直接ルールを指定し、その後でファイアウォールの状態を検証しています。
リスト 5. セッション・ルールを確立する
root@desktop:~# iptables -A INPUT -m conntrack --ctstate ESTABLISHED,RELATED -j ACCEPT root@desktop:~# iptables -L Chain INPUT (policy ACCEPT) target prot opt source destination ACCEPT all -- anywhere anywhere ctstate RELATED,ESTABLISHED Chain FORWARD (policy ACCEPT) target prot opt source destination Chain OUTPUT (policy ACCEPT) target prot opt source destination |
どんなコマンドが発行されたのかがよくわかるように、このコマンドを分解して各部分を説明します。
-A INPUT: このルールを INPUT チェーンに追加します。
-m conntrack: 現在のパケットあるいは接続に対して接続状態を追跡し、この部分に続くパラメーターで指定される状態と接続状態が一致するか突き合わせを行います。
-ctstate ESTABLISHED, RELATED:
ルールの適用対象となる接続状態を指定します。この場合、ESTABLISHED
は、パケットが既に両方向で送受信されている接続状態を表し、RELATED は既存の接続と関連するパケットが新しい接続を開始している状態を表します。
-j ACCEPT: この前の部分で記述した接続を受け付けるようにファイアウォールに指示します。-j フラグの設定として、もう 1 つ有効な値は DROP です。
また、SSH プロトコルを使用してサーバーに接続しています。そのためリスト 6 のルールでは、サーバーをロックダウンする前に、SSH の受信トラフィックをすべて許可します。ネットワーク・プロトコルのタイプとして tcp を指定し、同時に SSH サービスと関連付けられているポートを指定しています。必要に応じてポート番号を直接指定することもできます。
リスト 6. SSH によるインバウンド接続を受け付ける
root@desktop:~# iptables -A INPUT -p tcp --dport ssh -j ACCEPT root@desktop:~# iptables -L Chain INPUT (policy ACCEPT) target prot opt source destination ACCEPT all -- anywhere anywhere ctstate RELATED,ESTABLISHED ACCEPT tcp -- anywhere anywhere tcp dpt:ssh Chain FORWARD (policy ACCEPT) target prot opt source destination Chain OUTPUT (policy ACCEPT) target prot opt source destination |
最後に、他のすべてをブロックするようにファイアウォールを設定します。以下のコマンドを発行する際には特に注意が必要です。このコマンドが他のすべてのルールよりも前に配置されると、このコマンドはサーバーへのトラフィックをすべてブロックしてしまうからです。iptables は手続き型で (上から下へ) ルールを読み取り、ある 1 つのルールがマッチした後は残りのどのルールも評価しません。
リスト 7. 受信トラフィックをすべてブロックする
root@desktop:~# iptables -A INPUT -j DROP root@desktop:~# iptables -L Chain INPUT (policy ACCEPT) target prot opt source destination ACCEPT all -- anywhere anywhere ctstate RELATED,ESTABLISHED ACCEPT tcp -- anywhere anywhere tcp dpt:ssh DROP all -- anywhere anywhere Chain FORWARD (policy ACCEPT) target prot opt source destination Chain OUTPUT (policy ACCEPT) target prot opt source destination |
リスト 7 を見るとルールが適切な順序で記述されていますが、ここでは変更を行えるように、これらのルールをファイルに保存し、続けてその内容を調べてみましょう (リスト 8)。
リスト 8. ファイアウォールの構成を検証する
root@desktop:~# iptables-save > /etc/iptables.rules root@desktop:~# cat /etc/iptables.rules # Generated by iptables-save v1.4.4 on Sun Nov 21 15:10:42 2010 *filter :INPUT ACCEPT [1234:120406] :FORWARD ACCEPT [0:0] :OUTPUT ACCEPT [1522:124750] -A INPUT -m conntrack --ctstate RELATED,ESTABLISHED -j ACCEPT -A INPUT -p tcp -m tcp --dport 22 -j ACCEPT -A INPUT -j DROP COMMIT # Completed on Sun Nov 21 15:10:42 2010 |
iptables-save コマンドは変更をプレーンテキスト・ファイルに保存しています。リスト 8 は単純にコマンドラインでルールを表示する場合と少し異なるように見えますが、実際はまったく同じです。先ほどとまったく同じように、INPUT、FORWARD、OUTPUT という 3 つのセクションがあります。最初に指定したルールは INPUT 接続に関するルールであったため、追加したルールはこのセクションに配置されます。
この時点でサーバーはロックダウンされ、構成がファイルに保存されましたが、ネットワーク・スキャンを実行すると何が起こるのでしょう。このサーバーに対して nmap を再度実行し、その結果を調べてみましょう (リスト 9)。
リスト 9. ロックダウンされたサーバーをネットワーク・スキャンする
~ $ nmap 10.0.0.120 Starting Nmap 5.35DC1 ( http://nmap.org ) at 2010-11-21 20:56 EST Note: Host seems down. If it is really up, but blocking our ping probes, try -Pn Nmap done: 1 IP address (0 hosts up) scanned in 3.04 seconds ~ $ nmap -Pn 10.0.0.120 Starting Nmap 5.35DC1 ( http://nmap.org ) at 2010-11-21 20:56 EST Nmap scan report for 10.0.0.120 Host is up (0.017s latency). Not shown: 999 filtered ports PORT STATE SERVICE 22/tcp open ssh Nmap done: 1 IP address (1 host up) scanned in 12.19 seconds |
最初に nmap がサーバーの IP アドレスに対してスキャンを試みたときには、開いているポートを調べられなかったことに注意してください。これは、開いている SSH ポート以外のすべてをブロックするようにファイアウォールを設定しているためです。この単に IP アドレスを指定する方法では、nmap はあるネットワーク・プロトコルを使用してホストが起動されているかどうかを確認しており、この確認に失敗しています。-Pn を指定した 2 回目の試みは成功し、SSH のみが開いており、他のポートはどれも開いていない、という結果が示されています。たった 3 行のルールで、実質的にサーバーをロックダウンすることができたのです。
この前のセクションで、テキスト・ファイルにルールを保存しました。しかし、だからといってルールをロードする必要があるとサーバーに指示したことにはなりません。またサーバーをリブートすると、それまでの構成はすべて失われます。
コマンドラインを使ってルールを追加している人であれば、それらの変更をテキスト・ファイルに保存する方法は既に十分理解しているはずです。リスト 10 は、ファイアウォール・ルールを保存する方法を示しています。
リスト 10. ファイアウォール・ルールを保存する
iptables-save > /etc/iptables.rules |
起動時にこれらのルールをロードする方法が、使用されているオペレーティング・システムに応じていくつかあります。簡単な方法としては、パブリック・ネットワークに面しているインターフェースに対して、そのインターフェースを起動する前にそれらのルールをロードするように指示する方法があります。リスト 11 を見てください。
リスト 11. パブリック・ネットワーク・インターフェースにルールをロードする
<![CDATA[ auto eth0 iface eth0 inet static address 99.99.99.0 netmask 255.255.255.0 pre-up iptables-restore < /etc/iptables.rules ]]> |
この場合は eth0 というインターフェースを使用し、このインターフェースを起動する前に先ほどのルールをロードすることを宣言しています。ご想像のとおり、これらのコマンドを使用すると、ファイルからロードしたファイアウォール・ルールを編集し、その更新内容をファイルに保存することができます。
少し前のことですが、私はファイアウォール・アプライアンスを管理する立場にありました。私は定期的にルールと構成のバックアップをとるようにしていましたが、これらのバックアップが独自フォーマットであり、私の持っていたアプライアンスのモデルでしか読み取れないことに気付きませんでした。もちろん、ブランド、モデル、ファームウェア・バージョンがすべて同じであるアプライアンスを 2 つ持っていれば、それは問題にはなりません。しかし小規模のビジネスではよくあることですが、それは予算の面から無理でした。
ある日、そのアプライアンスが動作しなくなり、私はできるだけ信頼性の高い (つまりできるだけ優れた) 何らかの機器を大急ぎで実装しなければなりませんでした。私は、アプライアンスの構成は人間が読んで理解できるものを用意し、障害から即座に復旧できるようにしておくことが非常に重要であると痛感しました。
幸いなことに、私はいくつかのネットワーク・インターフェースを持つ状態の良い古いサーバーを見つけ、動作しなくなったアプライアンスと交換することができました。
この私の経験の話は、障害発生時に任意のサーバーに容易に適用できるルールのコピーを持っておくことに関するものでしたが、次のセクションではファイアウォールを小規模なホーム・ネットワークやビジネス・ネットワークのメイン・ゲートウェイにする方法について説明します。
iptables をパーソナル・コンピューターで実行する場合には、ここまでに説明した内容で十分です。しかしオフィス全体が 1 つのインターネット接続を共有する必要がある場合には、ここまでの内容はあまり意味がありません。オフィスのためのセットアップを適切に行うためには、iptables の構成を少し行います。
ここではサーバーに eth0 (パブリック) と eth1 (プライベート) という 2 つの物理ネットワーク・インターフェースがあるものとします。ネットワーク・トラフィックが一方のインターフェースから他方のインターフェースにスムーズに流れるように、この 2 つのインターフェースを NAT で接続する必要があります。プライベート・ネットワークのサブネットは 192.168.0.0/255.255.0.0 なので、転送機能を持つ NAT ルールがどのようなものになるかを見てみましょう (リスト 12)。
リスト 12. NAT ルールと転送ルール
iptables -A FORWARD -s 192.168.0.0/255.255.0.0 -i eth0 -o eth1 -m\ conntrack --ctstate NEW -j ACCEPT iptables -A FORWARD -m conntrack --ctstate RELATED,ESTABLISHED -j ACCEPT iptables -A POSTROUTING -t nat -j MASQUERADE |
リスト 13 は proc の設定を少し変更してサーバー内で転送する方法を示しています。
リスト 13. サーバー内で転送する
sh -c "echo 1 > /proc/sys/net/ipv4/ip_forward" |
proc の変更は一時的なものであるため、どのような変更もサーバーをリブートすると失われてしまいます。リブート後にも変更を有効にする方法はいくつかあります。Debian や Ubuntu ディストリビューションの場合には、実行が必要な行を /etc/rc.local に追加します。
最後にもう 1 つ、リスト 14 に示すように、実行時のカーネル・パラメーターを変更する設定変更があります (sysctl)。これらの構成は通常、既に sysctl.conf に含まれていますが、コメントアウトされています。それらのコメントを解除します (あるいは、これらの構成がディストリビューションに含まれていない場合には、これらの構成を追加します)。
リスト 14. sysctl あるいはカーネルでの転送設定
net.ipv4.conf.default.forwarding=1 net.ipv4.conf.all.forwarding=1 |
Linux サーバーをゲートウェイとして実行すると、DNS (Domain Name System) に関連する特定の問題が発生します。カーネルは IP アドレスのマッピング・テーブル (ARP (Address Resolution Protocol) テーブル) を保持するように設計されていますが、エントリーの最大数が決まっており、大量のトラフィックには適していません。エントリーが最大数に達すると、ホストから DNS への問い合わせに対して Linux サーバーが応答しなくなります。クライアントが少ない場合には、そうしたしきい値に達することは稀ですが、このファイアウォールを経由するクライアントの数が 30 を超えると、問題が発生することになります。
環境によって多少の調整が必要かもしれませんが、リスト 15 に示す値を使用すれば、こうした問題が発生するまでの余裕ができるはずです。
リスト 15. ARP キャッシュ・サイズを大きくする
echo 1024 > /proc/sys/net/ipv4/neigh/default/gc_thresh1 echo 2048 > /proc/sys/net/ipv4/neigh/default/gc_thresh2 echo 4096 > /proc/sys/net/ipv4/neigh/default/gc_thresh3 |
リスト 16 のようなメッセージが表示されないか注意してください。このメッセージは指定した ARP キャッシュのサイズを大きくする必要があるという警告をしています。
リスト 16. システム・ログで ARP キャッシュのオーバーフローが警告される
Nov 22 11:36:16 firewall kernel: [92374.325689] Neighbour table overflow. Nov 22 11:36:20 firewall kernel: [92379.089870] printk: 37 messages suppressed. Nov 22 11:36:20 firewall kernel: [92379.089876] Neighbour table overflow. Nov 22 11:36:26 firewall kernel: [92384.333161] printk: 51 messages suppressed. Nov 22 11:36:26 firewall kernel: [92384.333166] Neighbour table overflow. Nov 22 11:36:30 firewall kernel: [92389.084373] printk: 200 messages suppressed. |
この記事では、iptables を適切に実行させ、Linux サーバーを安全にロックダウンするための簡単なステップについて説明しました。この記事で適用したルールを見ると、iptables をファイアウォールとして使用するサーバーでどんなことが行われるのかについての感覚をつかめるはずです。皆さんも iptables を試してみてください。ファイアウォール・アプライアンスを利用していて、詳細な制御が必要な場合や、人間が読んで理解できる構成を簡単に複製したい場合には、特に iptables を試すことをお勧めします。
この記事では単純なルールを使用しており、iptables の柔軟性と複雑な機能については触れませんでしたが、iptables で数多くの複雑なルールを組み合わせることによって、安全かつ制御可能なファイアウォール環境を構築することができます。
iptables の高度な機能の中で興味深い機能の一例がロード・バランシングです。Web サービスの高可用性を検討する場合、そのほとんどにおいてロード・バランシングのソリューションを追求します。iptables の場合、random フラグと nth フラグによってロード・バランシングの設定と構成を行うことができます。
また、時間に基づくルールを設定することもできます。スモール・オフィスの環境では、月曜日から金曜日までは特定のサービスを制限し、土曜日と日曜日にはファイアウォールの動作を変更すると有効かもしれません。そうした場合に便利なフラグが --timestart、--timestop、--days などです。
私が経験した問題として、ファイアウォールを 2 つ同時に用意して何らかのフェイルオーバー機能を持たせる、ということができませんでした。そうしたシステムを作り出すことは簡単ではありませんが、いくつかの方法が考えられます。最も容易な方法は、ルーターを活用し、まったく同じ 2 つのファイアウォール・サーバーによってロード・バランシングを行う方法です。オフィスやスモール・ビジネスのようにネットワーク環境が不可欠の資産である場合には、そうした選択肢を検討することをお勧めします。
私はかつて iptables によって救われました。iptables によって皆さんも救われることを祈っています。
学ぶために
- Netfilter プロジェクト: このプロジェクトのページには iptables に関するすべての資料が揃っています。
- Ubuntu で iptables を使用する方法: 高度な構成を含め、Ubuntu で iptables を使用する方法について詳細に説明しています。
- CentOS で iptables を使用する方法。
- 「Introduction
to netfilter/iptables」: この developerWorks の記事は iptables の内部動作を解説しています。
- 「共通テーマ:
iptablesダイナミック・ファイアウォール」を読んでください。
- nmap: nmap はネットワークをスキャンするための優れたツールです。
- developerWorks の Open source ゾーン: オープンソース技術を使用した開発や、IBM 製品でオープンソース技術を使用するためのハウ・ツー情報やツール、プロジェクトの更新情報など、豊富な情報が用意されています。
- 関心のあるイベント: IBM オープンソース開発者にとって関心のある、今後開催されるカンファレンスや展示会、ウェブキャスト、その他のイベントについて調べてみてください。
- developerWorks podcasts: ソフトウェア開発者のための興味深いインタビューや議論を聞いてください。
- developerWorks demos: IBM とオープンソース技術、製品機能について学ぶために、無料のデモをご覧ください。
- developerWorks on Twitter: 最新のニュースをフォローしてください。
製品や技術を入手するために
- IBM ソフトウェア製品を評価する: 試用版のダウンロードからクラウドでホストされる製品に至るまで、特に開発者のために用意されたソフトウェアを使用して皆さんの次期オープンソース開発プロジェクトを革新することができます。
議論するために
- developerWorks
コミュニティー: 開発者向けのブログ、フォーラム、グループ、ウィキなどを利用しながら他の developerWorks
ユーザーとやり取りしてください。developerWorks のコミュニティー、Real world open source グループの構築を支援してください。

Alfredo Deza はソフトウェア技術者であり、元プロスポーツ選手であり、オリンピック選手であり、システム管理に豊富な経験を持っています。彼はオープンソース・ソフトウェアを熱心に支持し、また地域の技術グループや PyCon などの国際会議で頻繁に講演を行っています。彼は時間のあるときには写真の腕を磨き、またオープンソース・プロジェクトへの貢献を楽しんでいます。