2026年9月9日

2026年9月9日

iptablesの基本設定|WordPressサーバーのファイアウォールを締め出されずに構築する手順

iptablesでWordPressサーバーのファイアウォールを作るときは、「必要な通信(SSH・HTTP・HTTPS)を先に許可し、最後に既定の方針を拒否にする」「ルールをファイルで管理して再起動後も残す」「締め出されたときの戻し方を用意してから適用する」の3点が要になります。この記事では、Webサーバー向けの最小限のルールセットを1行ずつ理由つきで組み立て、IPv6、永続化、Dockerやクラウドのファイアウォールとの関係、動作確認までを順に解説します。

特定のポートを開け閉めするだけの操作ではなく、ゼロから「受信は原則拒否」の構成を作りたい人向けの内容です。

作業の前に確認すること

使っているのが本当にiptablesか

最近のLinuxでは、iptables コマンドの裏側がnftablesになっていることが多くあります(iptables-nft)。コマンドの書き方は同じですが、別の仕組みと混在すると動きが読めなくなるため、最初に状態を確かめます。

iptables -V
# 例: iptables v1.8.x (nf_tables)  ← nftables経由
#     iptables v1.8.x (legacy)     ← 従来方式

# 他のファイアウォール管理ツールが動いていないか
systemctl is-active firewalld ufw nftables

RHEL系(AlmaLinux、Rocky Linuxなど)は標準でfirewalld、Ubuntuはufwが用意されています。これらとiptablesを直接操作する方法を同時に使うと、片方の再読み込みでもう片方のルールが消えたり、意図しない順序になったりします。iptablesで管理すると決めたら、他のツールは停止して無効化しておきます。逆に、すでにfirewalldやufwで運用しているなら、無理にiptablesへ移る必要はありません。

締め出されたときの入り口を確保する

ファイアウォール作業で最も多い事故は、SSHを許可する前に受信を拒否してしまい、自分がサーバーに入れなくなることです。作業前に次の2つを準備します。

  • VPSやクラウドの管理画面にある「コンソール」(ブラウザから操作できる画面)が使えることを確認する
  • 現在のルールを保存しておく(sudo iptables-save > /root/iptables-before.rules)

また、本番サーバーで試す前に、同じOSの検証用サーバーで一度通しておくと安心です。

WordPress向けの基本ルールセット

1行ずつコマンドを打つと、途中の状態でSSHが切れる危険があります。ルールはファイルに書き、iptables-restore で一度に読み込む方法を勧めます。以下はDebian/Ubuntuの保存場所である /etc/iptables/rules.v4 に置く例です。203.0.113.10 は自分の接続元IPアドレスに置き換えてください。

*filter
:INPUT DROP [0:0]
:FORWARD DROP [0:0]
:OUTPUT ACCEPT [0:0]

# 1. ループバック(サーバー内部の通信)を許可
-A INPUT -i lo -j ACCEPT

# 2. 確立済みの通信への応答を許可、不正な状態のパケットは破棄
-A INPUT -m conntrack --ctstate ESTABLISHED,RELATED -j ACCEPT
-A INPUT -m conntrack --ctstate INVALID -j DROP

# 3. ping などのICMPを許可
-A INPUT -p icmp -j ACCEPT

# 4. SSHは管理用の接続元だけに許可
-A INPUT -p tcp -s 203.0.113.10 --dport 22 -m conntrack --ctstate NEW -j ACCEPT

# 5. Webサーバー(HTTP/HTTPS)は全体に公開
-A INPUT -p tcp -m multiport --dports 80,443 -m conntrack --ctstate NEW -j ACCEPT

COMMIT

各行の意味とつまずきやすい点

**既定の方針(:INPUT DROP)**は、どのルールにも当てはまらなかったパケットの扱いです。受信と転送は拒否、送信は許可にしています。WordPressは更新確認、プラグインのダウンロード、メール送信、外部APIとの連携などで外向きの通信を多用するため、OUTPUTまで絞ると原因の分かりにくい不具合が出やすくなります。送信も制限したい場合は、必要な宛先とポートを洗い出してから段階的に進めます。

ループバックを許可しないと、PHP-FPMとWebサーバーの間の通信や、同じサーバー内のMySQL/MariaDBへの接続が止まることがあります。ここは最初に書きます。

ESTABLISHED,RELATEDは、サーバーから外へ出した通信の返事を受け取るための行です。これが無いと、OUTPUTを許可していても応答が戻ってこられず、WordPressの更新やDNSの名前解決が失敗します。

ICMPをすべて止めると、経路の途中でパケットサイズを調整する仕組み(Path MTU Discovery)がうまく働かず、「一部の環境からだけページが途中で止まる」といった分かりにくい症状の原因になります。pingに応答したくない場合でも、ICMP全体を止めるのは避けたほうが無難です。

SSHの接続元制限は、総当たり攻撃への対策として効果が大きい設定です。自宅やオフィスのIPアドレスが変わる環境では、IPを限定できないこともあります。その場合は接続元を絞らずに許可し、パスワード認証を無効にして公開鍵認証に切り替える、fail2banで失敗が続くIPを一時的に遮断する、といった対策を組み合わせます。

80番と443番は訪問者向けなので接続元を絞りません。Let's EncryptのHTTP-01認証でも80番を使うため、HTTPSだけで運用していても80番を閉じると証明書の更新が失敗します。HTTP/3(QUIC)を有効にしているWebサーバーでは、UDPの443番も必要です。

ルールは上から順に評価され、最初に一致したもので処理が決まります。後から許可を追加するときに -A(末尾に追加)を使うと、手前の拒否ルールに先に当たって効かないことがあるため、順序を意識して書きます。

締め出されない適用方法

Debian/Ubuntuには、ルールを適用したあと一定時間内に確認の応答が無ければ元に戻す iptables-apply が用意されています。

# 構文チェックだけ行う(実際には適用しない)
sudo iptables-restore --test < /etc/iptables/rules.v4

# 適用し、60秒以内に確認できなければ自動で元に戻す
sudo iptables-apply -t 60 /etc/iptables/rules.v4

iptables-apply を実行したら、今のSSH接続はそのままにして、別のターミナルから新しくSSH接続できるかを確かめます。新しい接続が通ったら、元のターミナルで確認の質問に答えます。通らなければ何もせず待てば、元のルールに戻ります。

iptables-apply が無い環境では、適用前に保存したルールを数分後に自動で書き戻す処理を仕掛けておき、問題なく接続できたらその処理を取り消す、という手順で同じ考え方を実現できます。

IPv6のルールを忘れない

サーバーにIPv6アドレスが割り当てられている場合、iptables のルールはIPv6には一切効きません。IPv6は ip6tables で別に設定します。ここを忘れると、IPv4では閉じているポートがIPv6からは開いたまま、という状態になります。/etc/iptables/rules.v6 の例です。

*filter
:INPUT DROP [0:0]
:FORWARD DROP [0:0]
:OUTPUT ACCEPT [0:0]
-A INPUT -i lo -j ACCEPT
-A INPUT -m conntrack --ctstate ESTABLISHED,RELATED -j ACCEPT
-A INPUT -m conntrack --ctstate INVALID -j DROP
# IPv6では近隣探索などにICMPv6が不可欠
-A INPUT -p ipv6-icmp -j ACCEPT
-A INPUT -p tcp -s 2001:db8::10 --dport 22 -m conntrack --ctstate NEW -j ACCEPT
-A INPUT -p tcp -m multiport --dports 80,443 -m conntrack --ctstate NEW -j ACCEPT
COMMIT

IPv6ではICMPv6が近隣のアドレス解決にも使われるため、これを止めると通信そのものが成り立たなくなります。管理用のIPv6アドレスが無い場合は、SSHの行を削除してIPv4からだけ接続する運用にできます。

再起動後もルールを残す

iptables で入れたルールはメモリ上にあるだけで、再起動すると消えます。ディストリビューションごとに永続化の方法が異なります。

# Debian / Ubuntu
sudo apt install iptables-persistent
sudo netfilter-persistent save     # 現在のルールを rules.v4 / rules.v6 に保存
sudo systemctl enable netfilter-persistent

# RHEL系(firewalldを止めてiptablesで管理する場合)
sudo dnf install iptables-services
sudo systemctl disable --now firewalld
sudo service iptables save         # /etc/sysconfig/iptables に保存
sudo systemctl enable --now iptables ip6tables

保存したら、一度サーバーを再起動してルールが戻っているかを確認しておくと、障害時の再起動で慌てずに済みます。

Dockerとクラウドのファイアウォールに注意

Dockerは独自のチェーンを作り、公開したコンテナのポートへの通信をINPUTではなくFORWARD側で処理します。そのため、INPUTで拒否していてもコンテナのポートは外から届くことがあります。コンテナへのアクセスを制限したいときは、Dockerが用意している DOCKER-USER チェーンにルールを書くか、ポートを 127.0.0.1:8080:80 のようにローカルだけに公開してWebサーバーから中継します。Dockerの再起動でルールの並びが変わることもあるため、適用後の確認を習慣にします。

クラウドやVPSの管理画面のファイアウォール(セキュリティグループなど)は、サーバーの外側にある別の層です。両方で許可しないと通信は通らないため、「iptablesでは開けたのに届かない」場合は外側の設定も確かめます。

設定後の確認方法

ルールの状態は次のコマンドで確認します。

# パケット数つきで表示(どのルールに当たっているかが分かる)
sudo iptables -L INPUT -n -v --line-numbers

# 設定ファイルと同じ形式で表示
sudo iptables -S
sudo ip6tables -S

-v で表示されるパケット数を見ると、許可したはずの通信が実際にそのルールを通っているか、拒否方針に落ちているかが分かります。外からの確認は、自分の管理するサーバーに対して、別の回線から nc -zv サーバーのIP 443 などで行います。他人のサーバーへのポートスキャンは行わないでください。

最後に、WordPress側の動作も確認します。管理画面の「ツール」→「サイトヘルス」で外部への通信やループバックの項目にエラーが出ていないか、プラグインの更新確認が通るか、問い合わせフォームのメールが届くかを見ておくと、ファイアウォールが原因の不具合を早く見つけられます。メニューの表記はWordPressのバージョンによって変わることがあります(2026年10月現在)。

まとめ

  • iptablesの裏側がnftablesかを確認し、firewalldやufwと同時に使わない
  • ループバック、確立済み通信、ICMP、SSH、80/443の順に許可し、既定の方針を拒否にする
  • ルールはファイルで管理し、iptables-apply や事前保存で締め出しに備えてから適用する
  • IPv6は ip6tables で別に設定し、ICMPv6は止めない
  • 永続化の方法はディストリビューションごとに異なるので、再起動して確かめる
  • Dockerの公開ポートとクラウド側のファイアウォールは別に確認する

お気軽にご相談ください

お見積りへ お問い合わせへ
▲