iptables
1. iptablesの概要と目的
iptables(アイピーテーブルズ)は、Linuxでパケットの通過・遮断を制御するための設定ツールです。
サーバーを構築すると、「SSHは特定のIPアドレスからのみ許可したい」「Webの80番と443番以外は閉じたい」といった要件が必ず出てきます。iptablesを使うと、こうしたルールをサーバー自身に設定し、不要な通信を入口の段階で遮断できます。
この章では、iptablesがどのようなものなのか、また、なぜ知っておく必要があるのかを確認します。
iptablesとは?
iptablesとは、Linuxカーネルに組み込まれたパケット処理の仕組み「netfilter」を操作するためのコマンドです。Linux 2.4で導入され、長年にわたってLinuxサーバーのファイアウォール設定の標準的な手段として使われてきました。
iptablesで設定するルールは、次の要素の組み合わせで表現されます。
「どの通信」に対して「何をするか」
(例)TCPの22番ポート宛の通信 → 許可する
実際のコマンドでは、次のように記述します。
# TCPの22番ポート(SSH)宛の通信を許可する
iptables -A INPUT -p tcp --dport 22 -j ACCEPT
ここで重要なのは、iptablesのルールが上から順に評価され、最初に一致したルールが適用されるという点です。
ルール1:22番ポートを許可 ← ここで一致したら、以降は評価されない
ルール2:すべて破棄
同じルールを並べ替えるだけで結果が正反対になるため、「何を書いたか」だけでなく「どの順で書いたか」が設定の成否を決めます。
このように、通信の条件と処理を一覧として定義し、順番に照合していく点がiptablesの大きな特徴です。
なお、現在の多くのディストリビューションでは、後継の nftables が標準となっています。ただし iptables コマンドは互換層を通じて引き続き利用でき、既存の資料や運用手順も大量に残っているため、理解しておく価値は変わりません。
iptablesはどのような場面で登場するのか?
iptablesは、主にLinuxサーバーの構築時やセキュリティ対策の場面で登場します。
例えば、次のような場面が代表的な利用例です。
- 不要なポートの遮断: 公開する必要のないサービスへの外部からの接続を閉じる。
- 接続元の制限: SSHや管理画面へのアクセスを、特定のIPアドレスからのみ許可する。
- アドレス変換(NAT): ルーターのように振る舞わせ、通信の宛先や送信元を書き換える。
- ポートの転送: 外部から特定のポートへ届いた通信を、内部の別のポートへ振り向ける。
- 障害の切り分け: 「接続できない」原因がファイアウォールの設定かどうかを確認する。
インフラ担当者にとって、iptablesはサーバーを公開するうえで最初に向き合う防御の層です。
2. iptablesの仕組み・規格・主な特徴
iptablesは、「テーブル」「チェイン」「ルール」という3階層でパケットの扱いを定義します。
パケットがサーバーに届くと、その役割に応じて決まった順序でチェインを通過し、各チェイン内のルールが上から順に照合されます。
ここでは、テーブルとチェインの構成や、実際の記述例を確認します。
テーブルとチェインの違いと特徴
iptablesのテーブルは、目的ごとに分かれています。主なものは次の3つです。
- filterテーブル: パケットを通すか破棄するかを決める、最も基本的なテーブル。テーブル名を省略した場合はここが対象になります。
- natテーブル: 送信元や宛先のアドレス・ポートを書き換えるテーブル。ポート転送やルーター的な動作で使用します。
- mangleテーブル: パケットのヘッダー情報を書き換えるテーブル。通信の優先度制御などで使われます。
それぞれのテーブルには、パケットの流れに応じた「チェイン」が用意されています。filterテーブルの場合は次の3つです。
- INPUT: このサーバー自身が宛先となっている、受信パケット。
- OUTPUT: このサーバーから送り出す、送信パケット。
- FORWARD: このサーバーを経由して、別の宛先へ転送されるパケット。
ルールの末尾で指定する処理(ターゲット)には、主に次のものがあります。
- ACCEPT: 通過させる。
- DROP: 何も返さず破棄する。送信元からは応答がないため、タイムアウトになります。
- REJECT: 拒否を通知して破棄する。送信元には即座に「接続拒否」が返ります。
- LOG: ログに記録する。記録のみで処理は終わらず、後続のルールの評価が続きます。
パケットが届いてから処理が決まるまでの流れを追うと、次のようになります。
- 受信したパケットが、natテーブルの
PREROUTINGチェインなどを通過する。 - 宛先がこのサーバー自身であれば
INPUT、別の宛先への転送であればFORWARDへ振り分けられる。 - そのチェインに登録されたルールを、上から順に照合する。
- 一致したルールのターゲット(
ACCEPTやDROP)が適用され、評価が終了する。 - どのルールにも一致しなかった場合、そのチェインに設定された既定の処理(ポリシー)が適用される。
この5のポリシーを DROP にしておくことで、「明示的に許可したものだけを通す」という設計になります。これがファイアウォール設定の基本的な考え方です。
ルールの記述
実際の設定は、コマンドを順番に実行して組み立てます。
例えば、次のような記述になります。
【記述・構造の具体例】
必要な通信だけを許可する、最小構成のルールを設定する例です。
# 既存のルールを初期化する iptables -F INPUT # 確立済みの通信と、サーバー内部の通信を先に許可する iptables -A INPUT -m conntrack --ctstate ESTABLISHED,RELATED -j ACCEPT iptables -A INPUT -i lo -j ACCEPT # 必要なサービスを許可する iptables -A INPUT -p tcp --dport 22 -j ACCEPT # SSH iptables -A INPUT -p tcp --dport 80 -j ACCEPT # HTTP iptables -A INPUT -p tcp --dport 443 -j ACCEPT # HTTPS # どのルールにも一致しなかったものを破棄する iptables -P INPUT DROP iptables -P FORWARD DROP
この構成で押さえておきたい点が3つあります。
1つ目は、確立済みの通信を許可するルールを最初に置くことです。サーバーから外部へ接続した際の応答パケットは、このルールがないと破棄されてしまいます。ソフトウェアの更新やDNSの問い合わせができなくなる原因になります。
2つ目は、ループバック(lo)を許可することです。サーバー内部のプロセス同士の通信もINPUTチェインを通るため、これを閉じるとデータベース接続などが動かなくなります。
3つ目は、ポリシーの変更を最後に行うことです。先にポリシーを DROP にしてしまうと、許可ルールを追加する前の時点でSSHの接続が切断され、作業が続けられなくなります。
なお、ルールを追加するオプションには -A(末尾に追加)と -I(先頭に挿入)があります。評価は上から順に行われるため、どちらを使うかで結果が変わります。既存の設定へ割り込ませたい場合は -I を使用します。
3. iptablesが使われる理由・メリットと活用シーン
iptablesが使われる理由は、OSのカーネルレベルで通信を遮断できるため、アプリケーションに到達する前に不要な通信を排除できることにあります。
アプリケーション側で接続元を制限する実装を用意しなくても、サーバー全体に一律の方針を適用できます。
iptablesを使うメリット
アプリケーションごとにアクセス制限を実装すると、設定が分散し、漏れが生じやすくなります。
iptablesを適切に使用することで、次のようなメリットが生まれます。
- 一元的な制御: サービスの種類にかかわらず、サーバーへの通信を一か所の方針で管理できる。
- アプリケーションへの負荷軽減: 不要な通信をカーネルの段階で破棄するため、アプリケーションまで届かない。
- 追加費用が不要: Linuxに標準で備わっており、別途のソフトウェアや機器を必要としない。
- 柔軟な条件指定: 宛先ポート、送信元アドレス、プロトコル、接続状態などを組み合わせて細かく制御できる。
- 設定の持ち運び: ルールをテキストとして出力・復元でき、複数のサーバーへ同じ設定を適用しやすい。
ただし、iptablesはIPアドレスやポート番号といった情報で判断する仕組みです。通信の中身を見て攻撃を判定するわけではないため、SQLインジェクションのようなアプリケーション層の攻撃は防げません。WAFなど別の層の対策と組み合わせる必要があります。
サーバー構築や運用で活用する
実際のサーバー運用では、以下のような場面で活用されます。
- 公開サーバーの最小化: Webサーバーであれば80番・443番とSSHのみを開け、他をすべて閉じる。
- 管理用ポートの保護: SSHやデータベースへの接続を、社内や特定の拠点のIPアドレスに限定する。
- ポート転送の設定: 外部からの特定ポートへの通信を、内部の別サーバーやポートへ振り向ける。
- 攻撃の一時的な遮断: 大量のアクセスを送ってくる特定のIPアドレスを、一時的に遮断する。
- 検証環境の隔離: 開発用サーバーへの接続を、限られた範囲からのみ許可する。
このように、「誰に、どのサービスを見せるか」を定める場面で中心的な役割を果たします。
iptablesの設定の確認方法
現在のルールは、コマンドで確認できます。
# filterテーブルのルールを、行番号とヒット数つきで確認する
sudo iptables -L -n -v --line-numbers
# natテーブルのルールを確認する
sudo iptables -t nat -L -n -v
# 設定全体を、復元可能な形式で出力する
sudo iptables-save
# IPv6側のルールも確認する
sudo ip6tables -L -n -v
ここで -n を付けるのは、IPアドレスをホスト名に逆引きさせないためです。付けない場合、名前解決の待ち時間で表示が極端に遅くなることがあります。
また、-v を付けると各ルールが処理したパケット数が表示されます。意図したルールが実際に使われているかを確かめるうえで有効です。許可ルールを追加したのにヒット数が0のままであれば、そのルールまで到達していない(手前のルールで処理されている)ことを示します。
接続を試して確認する場合は、拒否のされ方にも注目してください。即座に「接続拒否」が返る場合は REJECT か、そもそもサービスが起動していない状態です。一方、応答がなく時間切れになる場合は DROP で破棄されている可能性が高く、ファイアウォールの設定を疑うべき状況です。
Web上の確認ツールを利用すれば、外部のネットワークから自分のサーバーのポートが開いているかを確認できます。設定したつもりのルールが実際に効いているかは、サーバーの内側からは判断できないため、外部からの確認が欠かせません。
関連技術・関連用語との違い
iptablesと混同されやすい関連用語として、次のようなものがあります。
- nftables: iptablesの後継として開発された仕組み。
nftコマンドで操作します。現在の多くのディストリビューションでは、iptablesコマンドを実行しても内部的にはnftablesが動作する互換構成になっています。新規に構築する場合はnftablesが推奨されます。 - firewalld / ufw: iptablesやnftablesを扱いやすくするための管理ツール。「サービス名」や「ゾーン」といった単位で設定でき、保存も自動で行われます。ただし、これらを使っている環境でiptablesコマンドを直接実行すると設定が競合するため、どちらか一方に統一する必要があります。
- クラウドのセキュリティグループ: AWSやGCPなどが提供する、サーバーの外側で動作するフィルタリング機能。iptablesがサーバー内部の防御であるのに対し、こちらはネットワーク側の防御です。
- TCP Wrapper(hosts.allow / hosts.deny): 古くからあるアクセス制御の仕組み。対応しているアプリケーションに限られ、現在では非推奨とされています。
iptablesが「サーバー自身に設定する防御」であるのに対し、セキュリティグループは「サーバーの手前に置く防御」です。
両方を使っている環境では、通信がどちらで遮断されているのかを切り分ける必要があります。クラウド環境では、まずセキュリティグループを確認するほうが早いケースも多くあります。
4. iptablesの導入・運用時の注意点と課題
iptablesは強力な反面、設定を誤るとサーバーへ接続できなくなる、あるいは意図せず外部へ公開されてしまうという両方向のリスクがあります。
特に、設定が即座に反映される一方で、再起動すると消えてしまうという性質が事故につながりやすい点です。
ここでは、実務上注意すべきポイントを説明します。
よくあるミス・設定ミス
よくある問題の一つが、ルールの順序を誤り、追加したはずの許可ルールが評価されないことです。
# 悪い例:すべてを破棄するルールが先にある
iptables -A INPUT -j DROP
iptables -A INPUT -p tcp --dport 80 -j ACCEPT # ここへは到達しない
この設定では、1行目ですべてのパケットが破棄されるため、2行目は永久に評価されません。「許可ルールを追加したのに通らない」という症状の多くは、この順序の問題です。iptables -L -n -v でヒット数を確認すると、該当ルールが0件のままであることから判断できます。
また、次のようなミスも頻出します。
- 自分自身のロックアウト: SSHを許可する前にポリシーを
DROPにしてしまい、接続が切れて復旧できなくなります。クラウドのコンソール接続などの代替手段がない環境では、サーバーの再作成が必要になることもあります。 - 設定の保存忘れ: iptablesのルールはメモリ上にあるだけで、再起動すると消えます。動作確認後に保存の手続きを行わないと、次回の再起動で設定が失われます。
- IPv6の見落とし:
iptablesはIPv4のみを対象とします。IPv6はip6tablesで別に設定する必要があり、片方だけ閉じても防御は成立しません。 - ループバックの遮断:
loを許可し忘れると、サーバー内部のプロセス間通信が止まります。 - 確立済み通信の許可漏れ: サーバーから外部への接続の応答が返らず、更新やDNS問い合わせができなくなります。
DROPとREJECTの使い分け: 外部に対しては無応答のDROPが一般的ですが、内部向けにはREJECTのほうが切り分けが容易です。
運用・セキュリティ上の注意点
近年特に注意が必要なのが、コンテナ環境との組み合わせです。
【よくある失敗・注意点の例】
iptablesでポートを閉じたはずなのに、Dockerコンテナのポートが外部から接続できてしまう例です。
閉じたつもりの設定
Chain INPUT (policy DROP) target prot opt source destination ACCEPT all -- 0.0.0.0/0 0.0.0.0/0 ctstate RELATED,ESTABLISHED ACCEPT all -- 0.0.0.0/0 0.0.0.0/0 ACCEPT tcp -- 0.0.0.0/0 0.0.0.0/0 tcp dpt:80 ACCEPT tcp -- 0.0.0.0/0 0.0.0.0/0 tcp dpt:443ところが、外部から接続できてしまう
# コンテナのポートを公開する docker run -d -p 3306:3306 mysql$ nc -zv server.example.com 3306 Connection to server.example.com 3306 port [tcp/*] succeeded!
この例では、INPUT チェインで3306番を許可していないにもかかわらず、外部から接続できてしまっています。
原因は、Dockerがコンテナのポートを公開する際に、自らnatテーブルへ変換ルールを追加するためです。公開ポート宛の通信は宛先が書き換えられてコンテナへ転送されるため、INPUT チェインではなく FORWARD チェインを通ります。その結果、INPUT に書いた制限が適用されません。
FORWARD のポリシーを DROP にしていても防げません。Dockerは FORWARD チェインの先頭に自身の許可ルールを挿入するため、ポリシーが評価される前に通過してしまいます。
対処方法は主に次の2つです。
1つは、公開時に待ち受けアドレスを限定することです。-p 127.0.0.1:3306:3306 のように指定すれば、サーバー内部からのみ接続できる形になります。
もう1つは、Dockerが用意している DOCKER-USER チェインにルールを記述することです。このチェインはDocker自身のルールより先に評価されるため、ここでの制限が有効に働きます。
# 3306番への接続を、特定のネットワークからのみ許可する
iptables -I DOCKER-USER -i eth0 ! -s 192.0.2.0/24 -p tcp --dport 3306 -j DROP
-i には外部と接している実際のインターフェース名を指定します。また、ここでの --dport は宛先変換後のコンテナ側のポート番号を指す点に注意してください。公開ポートとコンテナ側のポートが異なる場合は、後者を指定します。
そのほか、運用面では次の点にも注意が必要です。
- 設定の永続化: ルールの保存方法はディストリビューションによって異なります。Debian系では
iptables-persistent、RHEL系ではiptables-servicesなどを用います。保存前に必ず動作を確認してください。 - 管理ツールとの競合:
firewalldやufwが稼働している環境でiptablesコマンドを直接使うと、設定が上書きされたり二重になったりします。 - ルールの肥大化: 遮断対象のIPアドレスを1件ずつ追加していくと、ルール数が増えて照合の負荷が上がります。多数のアドレスを扱う場合は
ipsetの併用を検討します。 - ログの量:
LOGターゲットを広い条件に設定すると、ログが大量に出力されてディスクを圧迫します。 - 遮断だけに頼らない設計: iptablesは通信の中身を検査しません。アプリケーション層の攻撃には、別の対策が必要です。
安全に利用するための対策
iptablesを適切に運用するためには、以下の対策が有効です。
- 許可ルールを先に追加し、ポリシーの変更は最後に行う。
- 確立済み通信(
ESTABLISHED,RELATED)とループバックの許可を、ルールの先頭に置く。 - 変更前に
iptables-saveで現在の設定を書き出し、問題が起きたときに戻せるようにする。 - 遠隔での作業時は、設定を元に戻す予約をあらかじめ入れておく。接続が切れても一定時間後に自動で復旧できます。
- IPv4とIPv6の両方を設定し、
ip6tablesの確認も忘れない。 - 動作確認が済んだら、必ず永続化の手続きを行う。
- 設定後は外部のネットワークから実際にポートへ接続を試し、意図どおりに遮断されているかを確認する。
特に、遠隔で作業する場合のロックアウト対策は欠かせません。次の手順で、万一接続が切れても自動的に復旧できる状態を作ってから作業を始めます。
# 1. 復旧用のバックアップを取得する
sudo iptables-save > /root/iptables.backup
# 2. atコマンドが使える状態かを確認する(atdが停止していると予約は実行されない)
systemctl is-active atd
# 3. 10分後に設定を元に戻す予約を入れる
echo "iptables-restore < /root/iptables.backup" | sudo at now + 10 minutes
# 4. 作業と動作確認を行う
# 5. 問題がなければ、予約を取り消す
sudo atq # 予約の一覧とジョブ番号を確認する
sudo atrm <ジョブ番号> # 該当の予約を削除する
手順5を忘れると、作業が無事に終わって永続化まで済ませた後に復元が実行され、設定が巻き戻ってしまいます。予約の取り消しまでを一連の手順として覚えておいてください。
なお、at は最小構成のイメージでは導入されていない場合があります。利用できない環境では、sleep と組み合わせたバックグラウンド実行や、クラウドのコンソール接続といった代替手段を事前に用意しておきます。
5. まとめと関連ツールのご案内
ここまで解説したiptablesについて、重要なポイントを振り返ります。
iptablesは、Linuxカーネルのnetfilterを操作し、パケットの通過・遮断を制御するコマンドである。- テーブル・チェイン・ルールの3階層で構成され、ルールは上から順に評価される。
- 評価は最初に一致したルールで終わるため、記述の順序が結果を決定する。
- 確立済み通信とループバックの許可を先頭に置き、ポリシーの変更は最後に行う。
- ルールはメモリ上にあるだけで、永続化の手続きをしないと再起動で消える。
- IPv4とIPv6は別のコマンドで管理するため、片方だけでは防御が成立しない。
- Dockerの公開ポートは
INPUTチェインを経由しないため、通常のルールでは制限できない。 - 遠隔作業では復旧の予約を入れ、作業後に取り消すまでを手順として定めておく。
- 設定が意図どおりかは、外部のネットワークから確認する必要がある。
【お役立ちツールのご案内】
ここまで解説したiptablesの設定が、外部のネットワークから見て実際に効いているかを確認したい場合は、当サイトの TCPポート開放確認ツール をぜひご活用ください。
ホスト名とポート番号を入力するだけで、外部から接続できるかどうかを確認できます。遮断したつもりのポートが開いていないか、必要なポートが誤って閉じていないかの点検にお役立てください。