iptablesでLinuxファイアウォールを設定する入門

Linuxサーバーのセキュリティを強化するなら、iptablesの基本設定から始めましょう。初心者でも30分で主要なルールを作成し、不要なポートを遮断して不正アクセスを防げるようになります。本記事では、iptablesのインストールから具体的なルール設定、保存方法までを段階的に解説します。実務で即活用できる実践的な内容に特化しています。


目次


iptablesとは何か?基本概念を理解する

iptablesは、Linuxカーネルに組み込まれたパケットフィルタリング機能です。ネットワークトラフィックを制御し、不要な通信を遮断するファイアウォール機能を提供します。具体的には、以下のような機能を実現します。

  • ポートベースのアクセス制御:特定のポート(22/SSH、80/HTTP、443/HTTPSなど)へのアクセスを許可/拒否
  • IPアドレスベースの制限:特定のIPアドレスからのアクセスを許可/拒否
  • ステートフルパケットインスペクション:接続状態を追跡し、不正なパケットを検出
  • NAT(Network Address Translation):プライベートIPとパブリックIPの変換

iptablesは、NetfilterというLinuxカーネルのフレームワーク上で動作します。Netfilterは、ネットワークパケットを処理する際のフックポイントを提供し、iptablesはそのフックポイントでルールを適用します。

主な特徴は以下の通りです。

特徴詳細
カーネル統合Linuxカーネルに組み込まれており、高速なパケット処理が可能
柔軟なルール設定複雑な条件(送信元/宛先IP、ポート、プロトコル、ステート)を組み合わせたルールが作成可能
低リソース消費ハードウェアリソースをほとんど消費せず、サーバーのパフォーマンスに影響を与えない
互換性ほとんどのLinuxディストリビューション(Ubuntu、CentOS、Debianなど)で標準搭載

iptablesは、コマンドラインインターフェースで操作します。GUIツールはありませんが、その分、自動化やスクリプト化が容易です。また、永続化(再起動後もルールを維持)が必要な点に注意が必要です。


iptablesのインストールと確認方法

多くのLinuxディストリビューションでは、iptablesはデフォルトでインストールされています。しかし、古いバージョンや一部のディストリビューションでは、明示的にインストールする必要があります。以下に、主要なディストリビューションごとのインストール手順を示します。

Ubuntu/Debian系

UbuntuやDebianでは、通常iptablesはデフォルトでインストールされています。確認とインストールは以下のコマンドで行います。

# インストールされているか確認
sudo iptables --version

インストールされていない場合(まれ)

sudo apt update sudo apt install iptables

インストール後、以下のコマンドで現在のルールを確認できます。

sudo iptables -L -n -v

出力例:

Chain INPUT (policy ACCEPT 0 packets, 0 bytes)
 pkts bytes target     prot opt in     out     source               destination

Chain FORWARD (policy ACCEPT 0 packets, 0 bytes)
 pkts bytes target     prot opt in     out     source               destination

Chain OUTPUT (policy ACCEPT 0 packets, 0 bytes)
 pkts bytes target     prot opt in     out     source               destination

CentOS/RHEL系

CentOS 7以前ではiptablesが標準でインストールされていますが、CentOS 8以降ではfirewalldがデフォルトのファイアウォール管理ツールになっています。iptablesを使用する場合は、以下の手順でインストールします。

# firewalldを停止し、iptablesを有効化
sudo systemctl stop firewalld
sudo systemctl disable firewalld

iptables-servicesをインストール

sudo yum install iptables-services -y

iptablesを起動

sudo systemctl enable iptables sudo systemctl start iptables

現在のルールを確認

sudo iptables -L -n -v

CentOS 8以降でiptablesを使用する場合、iptables-nftという互換レイヤーを使用します。これは、iptablesコマンドをnftables(次世代のNetfilter)に変換して実行する仕組みです。互換性は高いですが、一部の高度な機能は制限される可能性があります。

その他のディストリビューション

AlmaLinux、Rocky Linux、Fedoraなどでも、基本的な手順はCentOSと同様です。主な違いはパッケージマネージャー(dnf/yum)の違いです。

# AlmaLinux/Rocky Linux/Fedora
sudo dnf install iptables-services -y

iptablesのバージョ…

使用しているiptablesのバージョンを確認するには、以下のコマンドを実行します。

sudo iptables --version

出力例:

iptables v1.8.7 (nf_tables)

バージョンによって、使用可能なオプションや機能が異なる場合があります。特に、nf_tablesと併記されている場合は、nftablesとの互換モードで動作していることを示します。この場合、一部の古いiptablesコマンドは動作しない可能性があります。

注意事項:

  • iptablesはLinuxカーネルに依存しているため、カーネルのバージョンによって動作が異なる場合があります。
  • 古いカーネル(例:Linux 2.4系)では、iptablesではなくipchainsが使用されています。
  • 最新のLinuxディストリビューションでは、nftablesへの移行が推奨されています。詳細は後述の比較表を参照してください。

iptablesの基本概念とテーブル/チェーン

iptablesを効果的に使用するためには、テーブルチェーンの概念を理解することが不可欠です。これらは、iptablesがルールを整理し、パケットを処理するためのフレームワークを提供します。

テーブル(Tables)

iptablesには、主に4つのテーブルがあります。各テーブルは異なる目的に特化しており、ルールを適用するタイミングが異なります。

テーブル名主な用途処理順序
filterパケットの許可/拒否/ドロップを制御(デフォルトのテーブル)3番目
natIPマスカレード、ポートフォワーディング、DNAT/SNAT1番目
mangleパケットのヘッダー情報(TTL、マークなど)を変更2番目
rawパケットの追跡(ステートフル)を無効化(高速化用)最初

各テーブルの処理順序は、raw → mangle → nat → filter です。これは、パケットがネットワークを通過する際の処理順序を反映しています。

チェーン(Chains)

各テーブルには、チェーンと呼ばれるルールの集合体があります。チェーンは、パケットが通過する際の処理ポイントを定義します。主なチェーンは以下の通りです。

チェーン名テーブル処理タイミング説明
INPUTfilterローカルプロセス宛てのパケットサーバーに直接送信されるパケットを処理
OUTPUTfilterローカルプロセス発のパケットサーバーから送信されるパケットを処理
FORWARDfilterルーティングされるパケットサーバーを経由して他のホストに送信されるパケットを処理
PREROUTINGnat, mangle, rawルーティング前のパケットパケットがルーティングされる前に処理(主にNAT用)
POSTROUTINGnat, mangleルーティング後のパケットパケットがルーティングされた後に処理(主にNAT用)

例えば、INPUTチェーンは、サーバーに直接送信されるパケット(SSH接続、HTTPリクエストなど)を処理します。一方、FORWARDチェーンは、サーバーを経由して他のホストに送信されるパケット(ルーターとして動作する場合など)を処理します。

ルールの構造

iptablesのルールは、以下のような構造で定義されます。

iptables [-t テーブル名] コマンド [マッチング条件] [ターゲット/アクション]

具体的な例を見てみましょう。

iptables -A INPUT -p tcp --dport 22 -j ACCEPT

このコマンドの内訳は以下の通りです。

  • -A INPUT:INPUTチェーンにルールを追加(Append)
  • -p tcp:TCPプロトコルのパケットにマッチ
  • –dport 22:宛先ポートが22(SSH)のパケットにマッチ
  • -j ACCEPT:マッチしたパケットを許可(Accept)

このルールは、SSH(ポート22)への接続を許可するものです。ただし、このルールだけでは他のポートが遮断されていないため、セキュリティは不十分です。

デフォルトポリシーの設定

iptablesでは、各チェーンにデフォルトポリシーを設定できます。デフォルトポリシーは、ルールにマッチしないパケットに対して実行されるアクションです。一般的には、以下のいずれかを設定します。

  • ACCEPT:すべてのパケットを許可(セキュリティ上危険)
  • DROP:すべてのパケットを拒否(推奨)
  • REJECT:拒否し、拒否メッセージを返す

デフォルトポリシーを設定するには、以下のコマンドを使用します。

# INPUTチェーンのデフォルトポリシーをDROPに設定
sudo iptables -P INPUT DROP

OUTPUTチェーンのデフォルトポリシーをACCEPTに設定

sudo iptables -P OUTPUT ACCEPT

注意: OUTPUTチェーンのデフォルトポリシーをDROPに設定すると、サーバーからの通信がすべて遮断されます。通常は、OUTPUTはACCEPTに設定します。


よく使うiptablesコマンド一覧

iptablesを操作するための主要なコマンドを以下にまとめます。これらのコマンドを組み合わせることで、柔軟なファイアウォールルールを作成できます。

ルールの追加・削除・確認

コマンド説明使用例
-A, –appendチェーンの末尾にルールを追加iptables -A INPUT -p tcp –dport 80 -j ACCEPT
-I, –insertチェーンの指定位置にルールを挿入iptables -I INPUT 1 -p tcp –dport 22 -j ACCEPT
-D, –deleteチェーンからルールを削除iptables -D INPUT -p tcp –dport 22 -j ACCEPT
-R, –replace既存のルールを置き換えiptables -R INPUT 1 -p tcp –dport 22 -j DROP
-L, –listチェーンのルールを表示iptables -L INPUT -n -v
-F, –flushチェーンのルールをすべて削除iptables -F INPUT
-X, –delete-chainカスタムチェーンを削除iptables -X CUSTOM_CHAIN
-P, –policyチェーンのデフォルトポリシーを設定iptables -P INPUT DROP

マッチング条件

ルールを適用するパケットを特定するためのマッチング条件です。以下に主要なオプションを示します。

オプション説明使用例
-p, –protocolプロトコルを指定(tcp, udp, icmp, all)-p tcp
–sport送信元ポートを指定–sport 1024:65535
–dport宛先ポートを指定–dport 80
-s, –source送信元IPアドレスを指定-s 192.168.1.100
-d, –destination宛先IPアドレスを指定-d 10.0.0.1
-i, –in-interface入力インターフェースを指定-i eth0
-o, –out-interface出力インターフェースを指定-o eth1
-m, –match拡張モジュールを使用-m state –state ESTABLISHED,RELATED

ターゲット/アクション

マッチしたパケットに対して実行するアクションです。

ターゲット説明使用例
ACCEPTパケットを許可-j ACCEPT
DROPパケットを破棄(拒否メッセージなし)-j DROP
REJECTパケットを拒否し、拒否メッセージを返す-j REJECT –reject-with icmp-port-unreachable
LOGパケットをログに記録-j LOG –log-prefix “IPTABLES-DROPPED: “
RETURNカスタムチェーンから呼び出し元に戻る-j RETURN
DNAT宛先NAT(ポートフォワーディング)-j DNAT –to-destination 192.168.1.100:80
SNAT送信元NAT(IPマスカレード)-j SNAT –to-source 1.2.3.4

ステートフルパケットインス…

iptablesは、ステートフルパケットインスペクションをサポートしています。これにより、接続の状態(新規、確立済み、関連)に基づいてルールを適用できます。主なステートは以下の通りです。

  • NEW:新しい接続
  • ESTABLISHED:確立済みの接続
  • RELATED:関連する接続(例:FTPデータ接続)
  • INVALID:無効なパケット

ステートを使用したルール例:

# 既存の接続を許可
iptables -A INPUT -m state --state ESTABLISHED,RELATED -j ACCEPT

新規SSH接続を許可

iptables -A INPUT -p tcp --dport 22 -m state --state NEW -j ACCEPT

注意:ステートフルパケットインスペクションを使用するには、connection trackingモジュールが有効になっている必要があります。通常、Linuxカーネルではデフォルトで有効です。

拡張モジュール

iptablesには、さまざまな拡張モジュールが用意されており、高度なルールを作成できます。主な拡張モジュールは以下の通りです。

モジュール名説明使用例
state接続の状態に基づくルール-m state –state ESTABLISHED
multiport複数のポートを一度に指定-m multiport –dports 80,443,8080
limitパケットのレート制限-m limit –limit 3/minute
macMACアドレスに基づくルール-m mac –mac-source 00:1A:2B:3C:4D:5E
ownerローカルプロセスのUID/GIDに基づくルール-m owner –uid-owner 1000

例えば、limitモジュールを使用して、特定のポートへのアクセスをレート制限することで、DoS攻撃を軽減できます。

# HTTP(80番ポート)へのアクセスを1分間に3回までに制限
iptables -A INPUT -p tcp --dport 80 -m limit --limit 3/minute -j ACCEPT

実践的なファイアウォールルール設定

ここからは、具体的なシナリオに基づいたファイアウォールルールの設定方法を解説します。実務で頻繁に使用されるルールパターンを中心に、セキュリティを強化するためのベストプラクティスを紹介します。

基本的なセキュリティルール

まずは、基本的なセキュリティルールを設定します。これらのルールは、ほとんどのLinuxサーバーに適用できます。

1. デフォルトポリシーの設定

すべてのチェーンのデフォルトポリシーを設定します。INPUTチェーンはDROPに、OUTPUTとFORWARDはACCEPTに設定します。

# デフォルトポリシーを設定
sudo iptables -P INPUT DROP
sudo iptables -P OUTPUT ACCEPT
sudo iptables -P FORWARD DROP

この設定により、サーバーへの不要な接続はすべて遮断され、サーバーからの通信は許可されます

2. 既存の接続を許可

サーバーとの通信が途切れないように、ESTABLISHED(確立済み)とRELATED(関連)の接続を許可します。

# 既存の接続を許可
sudo iptables -A INPUT -m state --state ESTABLISHED,RELATED -j ACCEPT

このルールは、サーバーが既に確立した接続(例:SSHセッション、HTTPレスポンス)を維持します。

3. ローカルループバック(localhost)を許可

サーバー内部の通信(localhost)を許可します。

# ローカルループバックを許可
sudo iptables -A INPUT -i lo -j ACCEPT
sudo iptables -A OUTPUT -o lo -j ACCEPT

これにより、localhost(127.0.0.1)間の通信が正常に動作します。

4. ICMP(ping)を許可

ネットワークの疎通確認に使用されるICMP(ping)を許可します。

# ICMP(ping)を許可
sudo iptables -A INPUT -p icmp --icmp-type echo-request -j ACCEPT
sudo iptables -A OUTPUT -p icmp --icmp-type echo-reply -j ACCEPT

これにより、pingコマンドによる疎通確認が可能になります。

SSH(ポート22)のセキ…

SSHはリモート管理に必須ですが、攻撃の対象になりやすいため、セキュアな設定が必要です。

1. SSH接続を許可

SSH(ポート22)への接続を許可します。特定のIPアドレスからのみ接続を許可することを推奨します。

# 特定のIPアドレスからのSSH接続を許可(例:192.168.1.100)
sudo iptables -A INPUT -p tcp --dport 22 -s 192.168.1.100 -j ACCEPT

他のIPアドレスからのSSH接続を拒否

sudo iptables -A INPUT -p tcp --dport 22 -j DROP

この設定により、許可されたIPアドレスからのみSSH接続が可能になります。IPアドレスは、グローバルIPまたは信頼できるネットワークのIPを指定します。

2. SSHポートの変更(セキュリティ向上)

SSHのデフォルトポート(22)を変更することで、自動化された攻撃を回避できます。ポート番号は1024〜65535の範囲で選択します。

# SSHポートを2222に変更
sudo iptables -A INPUT -p tcp --dport 2222 -s 192.168.1.100 -j ACCEPT

古いポート(22)を拒否

sudo iptables -A INPUT -p tcp --dport 22 -j DROP

注意:ポートを変更する場合は、sshd_configファイルも更新する必要があります。

# /etc/ssh/sshd_configを編集
sudo vi /etc/ssh/sshd_config

以下の行を変更

Port 2222

SSHサービスを再起動

sudo systemctl restart sshd

3. SSH接続のレート制限

SSHへのブルートフォース攻撃を防ぐために、接続試行回数を制限します。

# SSH接続を1分間に3回までに制限
sudo iptables -A INPUT -p tcp --dport 22 -m limit --limit 3/minute -j ACCEPT

これにより、過剰な接続試行を防ぎ、サーバーの負荷を軽減できます。

Webサーバー(HTTP/…

Webサーバー(Apache、Nginxなど)を運用する場合、HTTP(80)とHTTPS(443)へのアクセスを許可します。

1. HTTP(80)とHTTPS(443)を許可

# HTTP(80)を許可
sudo iptables -A INPUT -p tcp --dport 80 -j ACCEPT

HTTPS(443)を許可

sudo iptables -A INPUT -p tcp --dport 443 -j ACCEPT

これにより、Webサイトへのアクセスが可能になります。

2. 特定のIPアドレスからのみWebアクセスを許可

Webサイトを特定のユーザーや組織に限定する場合、IPアドレスベースの制限を設定します。

# 特定のIPアドレスからのHTTP/HTTPSアクセスを許可
sudo iptables -A INPUT -p tcp -m multiport --dports 80,443 -s 192.168.1.0/24 -j ACCEPT

この設定により、192.168.1.0/24ネットワーク内のIPアドレスからのみWebアクセスが可能 【編集・制作ポリシー】
本記事はRoute Bloom編集部が各ベンダー公式ドキュメント・エンジニア監修をもとに作成しています。インフラ・クラウド構築は環境により異なります。本番環境への適用前に必ずテストを実施してください。情報の正確性には万全を期していますが、最新情報は各公式ドキュメントをご確認ください。