サーバーのファイアウォール設計 — ufw/iptablesとクラウドの使い分け
本記事はアフィリエイト広告(A8.net)を含みます。価格・仕様は2026年6月時点の目安です。最新は各公式サイトでご確認ください。
TL;DR
VPSのファイアウォール設計で最初に押さえるべき原則は「デフォルト拒否・必要なポートだけ最小開放」の1点です。Ubuntu/Debianなら ufw でこの原則を数コマンドで実現できます。より細かい制御が必要な場合は iptables または nftables を使います。
クラウド(ConoHa VPS・Xserver VPS など)はOSのファイアウォールに加えてコントロールパネル側にもセキュリティグループ(ファイアウォールルール)を持っています。この2層構成を理解して使い分けることが、実務上の抜け漏れを防ぐポイントです。
本記事は自分が管理するサーバーへのファイアウォール設定を対象にした技術解説です。ルール変更時はSSHセッションを別ウィンドウで保持したまま作業してください。設定ミスでSSHを遮断するとコンソールからの回復作業が必要になります。VPSの初期セキュリティ設定全般はVPSを借りたら最初にやるセキュリティ設定10項目も参照してください。
ファイアウォールの基本概念
デフォルト拒否・最小開放の原則
ファイアウォールの設定方針は大きく2つあります。
| 方針 | 内容 | 採用すべき場面 |
|---|---|---|
| デフォルト拒否(許可リスト方式) | 明示的に許可したもの以外はすべて遮断 | サーバー全般・推奨 |
| デフォルト許可(拒否リスト方式) | 明示的に拒否したもの以外はすべて通す | 管理コストを優先するLAN内機器等 |
サーバー用途では必ずデフォルト拒否を採用します。これにより、新しいサービスを追加したときに「意図せずポートが開きっぱなし」になる事故を防げます。
ステートフルインスペクション
現代のLinuxファイアウォール(iptables/nftables/ufw)はすべてステートフル(状態追跡)です。つまり、確立済みの接続(ESTABLISHED)と関連パケット(RELATED)は、明示的なルールがなくても返り通信が許可されます。
クライアント → サーバー: 新規接続(NEW)→ ルールでチェック
サーバー → クライアント: 返り通信(ESTABLISHED)→ 自動的に通過
このため「インバウンドはSSH/HTTP/HTTPSだけ許可、アウトバウンドは全許可」という一般的な構成で、サーバーから外部APIへのHTTPSアクセスなどは問題なく機能します。
ufw — シンプルな設定・日常管理に向く
ufw(Uncomplicated Firewall)はUbuntu/Debian系での標準的なフロントエンドです。iptables を内部で使いますが、コマンドが直感的で設定ミスが起きにくい構成になっています。
インストールと基本設定
Ubuntu/Debianではデフォルトでインストール済みのことが多いですが、入っていない場合はインストールします。
sudo apt install ufw -y
デフォルトポリシーをまず設定します。有効化(enable)の前に行います。
sudo ufw default deny incoming
sudo ufw default allow outgoing
ポートの許可
SSHを許可します(有効化の前に必ず実行してください)。
# SSH(デフォルト22番)を許可
sudo ufw allow 22/tcp
# SSHポートを変更している場合(例: 2222番)
sudo ufw allow 2222/tcp
Webサーバーを運用する場合はHTTP/HTTPSも開けます。
sudo ufw allow 80/tcp
sudo ufw allow 443/tcp
サービス名で指定することもできます。
sudo ufw allow ssh
sudo ufw allow http
sudo ufw allow https
有効化と状態確認
# ufwを有効化(SSHポートを許可した後に実行)
sudo ufw enable
# ルール一覧と状態を確認
sudo ufw status verbose
sudo ufw status verbose の出力例は次のようになります。
Status: active
Logging: on (low)
Default: deny (incoming), allow (outgoing), disabled (routed)
New profiles: skip
To Action From
-- ------ ----
22/tcp ALLOW IN Anywhere
80/tcp ALLOW IN Anywhere
443/tcp ALLOW IN Anywhere
22/tcp (v6) ALLOW IN Anywhere (v6)
80/tcp (v6) ALLOW IN Anywhere (v6)
443/tcp (v6) ALLOW IN Anywhere (v6)
IPアドレスによる制限(管理ポートの絞り込み)
SSH等の管理ポートは、特定のIPアドレスからのみ許可する運用が望ましいです。オフィスや自宅の固定IP、またはVPN出口IPを指定します。
# 特定のIPだけSSHを許可(既存の全開放ルールは削除する)
sudo ufw allow from 203.0.113.0/24 to any port 22 proto tcp
# 全開放ルールを削除する場合
sudo ufw delete allow 22/tcp
ルールの削除
# ルールを番号で確認
sudo ufw status numbered
# 番号で削除(例: 番号3)
sudo ufw delete 3
# ルールを直接指定して削除
sudo ufw delete allow 80/tcp
iptables — 細かい制御が必要な場合
iptables は ufw より低レベルなツールです。接続の状態(ステート)・プロトコル・インターフェース・パケットの方向(INPUT/OUTPUT/FORWARD)を細かく制御できます。
iptablesの基本構造
iptablesはチェーンとテーブルで構成されます。通常のサーバー設定では filter テーブルの INPUT(受信)・OUTPUT(送信)・FORWARD(転送)チェーンを扱います。
# 現在のルールを確認(-v で詳細、-n でDNS解決なし、--line-numbers で行番号)
sudo iptables -L -v -n --line-numbers
基本的なルールセット(デフォルト拒否構成)
# まず全チェーンをフラッシュ(既存ルールをクリア)
sudo iptables -F
sudo iptables -X
# デフォルトポリシーを設定(全拒否)
sudo iptables -P INPUT DROP
sudo iptables -P FORWARD DROP
sudo iptables -P OUTPUT ACCEPT
# ループバックを許可(ローカル通信を遮断しない)
sudo iptables -A INPUT -i lo -j ACCEPT
# 確立済み・関連接続を許可(ステートフル)
sudo iptables -A INPUT -m state --state ESTABLISHED,RELATED -j ACCEPT
# SSH(22番)を許可
sudo iptables -A INPUT -p tcp --dport 22 -j ACCEPT
# HTTP/HTTPS を許可
sudo iptables -A INPUT -p tcp --dport 80 -j ACCEPT
sudo iptables -A INPUT -p tcp --dport 443 -j ACCEPT
# ICMPを許可(ping)
sudo iptables -A INPUT -p icmp -j ACCEPT
特定IPからの接続に限定する
# 特定のIPからSSHだけ許可
sudo iptables -A INPUT -p tcp -s 203.0.113.10 --dport 22 -j ACCEPT
iptablesルールの永続化
iptables のルールは再起動で失われます。iptables-persistent で保存・復元します。
sudo apt install iptables-persistent -y
# 現在のルールを保存
sudo netfilter-persistent save
# 保存されたルールを確認
sudo cat /etc/iptables/rules.v4
ルールの削除
# ルールを番号で削除(INPUTチェーンの3番目)
sudo iptables -D INPUT 3
# ルールを内容で削除(追加コマンドの -A を -D に変える)
sudo iptables -D INPUT -p tcp --dport 80 -j ACCEPT
nftables — iptablesの後継
nftables は iptables の後継で、Debian 10以降・Ubuntu 20.04以降でデフォルトになっています。構文が整理されており、IPv4とIPv6を統一的に扱えます。
nftablesの基本確認
# 現在のルールセットを表示
sudo nft list ruleset
基本的なルールセット例
/etc/nftables.conf に設定を書きます。
sudo nano /etc/nftables.conf
以下は典型的なサーバー構成です。
#!/usr/sbin/nft -f
flush ruleset
table inet filter {
chain input {
type filter hook input priority 0; policy drop;
# ループバックを許可
iif "lo" accept
# 確立済み・関連接続を許可
ct state { established, related } accept
# ICMP を許可
ip protocol icmp accept
ip6 nexthdr icmpv6 accept
# SSH を許可
tcp dport 22 accept
# HTTP/HTTPS を許可
tcp dport { 80, 443 } accept
}
chain forward {
type filter hook forward priority 0; policy drop;
}
chain output {
type filter hook output priority 0; policy accept;
}
}
設定を適用します。
sudo nft -f /etc/nftables.conf
sudo systemctl enable nftables
sudo systemctl restart nftables
OSファイアウォールとクラウドのセキュリティグループの2層構成
ConoHa VPS・Xserver VPS などのクラウドVPSは、コントロールパネル側にもネットワークレベルのファイアウォール機能(セキュリティグループ・ファイアウォール設定)を持っています。これはOSより外側、ネットワーク層で動作します。
2層の役割分担
| レイヤー | ツール | 動作する場所 | 特徴 |
|---|---|---|---|
| クラウド(外側) | セキュリティグループ / コントロールパネルFW | ネットワーク層 | OSが起動する前に遮断できる。SSHポートへのスキャン自体をOSに届かせない |
| OS(内側) | ufw / iptables / nftables | OS内部 | アプリケーション単位の制御・ログ取得・IPベースの細かい制限が可能 |
推奨構成
実務では両方を併用します。
- クラウド側: 大まかなポリシー(SSH/HTTP/HTTPSのみ、管理ポートは自社IPに限定)
- OS側: アプリケーション単位の詳細制御・ログ取得・fail2ban との連携
どちらか一方に頼ると、次のリスクがあります。
- クラウド側だけに頼る: OSに上がってきたパケットのアプリレベル制御ができない。コントロールパネルの誤操作で全開放になった場合の防御がない。
- OS側だけに頼る: スキャン・DoS試行がOSまで届くため、リソースを消費する。クラウドパネルのデフォルト設定が全開放のままになっているリスクがある。
よくある設計パターン
一般的なWebサーバー
# ufw での構成例
sudo ufw default deny incoming
sudo ufw default allow outgoing
sudo ufw allow 22/tcp # SSH(管理者のIPに絞るなら: allow from <IP> to any port 22 proto tcp)
sudo ufw allow 80/tcp # HTTP
sudo ufw allow 443/tcp # HTTPS
sudo ufw enable
SSH管理ポートをIPで絞る構成
# 管理者のIP(固定IP or VPN出口)からのみSSHを許可
sudo ufw allow from 203.0.113.10 to any port 22 proto tcp
# 全開放のSSHルールが残っていれば削除
sudo ufw delete allow 22/tcp
Nginxリバースプロキシ構成
リバースプロキシを使う場合、バックエンドアプリのポート(例: 3000/8080)は外部に開けず、ローカルホストのみ受け付ける構成にします。詳細はNginxリバースプロキシでVPS上のサービスをまとめるを参照してください。
# バックエンドポートは外部に開かない(開けるのはNginxの80/443のみ)
sudo ufw allow 80/tcp
sudo ufw allow 443/tcp
# 3000番など内部ポートは許可しない
ログとブロックの確認
ufwのログ
# ufwのログレベルを設定
sudo ufw logging on
# ブロックログを確認(ufwのログはsyslogまたはkernelログ)
sudo journalctl -k --since "1 hour ago" | grep UFW
iptablesでのログ記録
拒否されたパケットをログに記録するルールを追加できます。
# INPUTチェーンで拒否する前にログに記録(DROPの手前に追加)
sudo iptables -A INPUT -j LOG --log-prefix "iptables-drop: " --log-level 4
sudo iptables -A INPUT -j DROP
ログは journalctl -k または /var/log/syslog で確認できます。
現在の接続状況の確認
# 開いているポートとリッスン中のプロセスを確認
sudo ss -tulpn
# 確立済みの接続を確認
sudo ss -tupn state established
まとめ
| ツール | 向いている用途 | 主なデメリット |
|---|---|---|
| ufw | Ubuntu/Debian の日常管理・シンプルな構成 | 高度なルール(マーキング・NATなど)は不向き |
| iptables | 詳細な制御が必要な場合・スクリプト自動化 | 構文が冗長・IPv4/IPv6を別管理 |
| nftables | iptablesの後継・新規構築 | 情報リソースがiptablesより少ない |
| クラウドFW | ネットワーク層での大まかなポリシー | OS側の細かい制御はできない |
設計の優先順序は次の通りです。
- クラウドのセキュリティグループでSSH/HTTP/HTTPSのみ開放・管理ポートはIP絞り込み
- OS側でufwを有効化、同じポリシーを二重で適用(デフォルト拒否・最小開放)
- SSH管理ポートは固定IPまたはVPN出口からのみ許可
- バックエンドの内部ポートは外部に開かない、ループバックのみ受け付ける
sudo ufw status verboseとsudo ss -tulpnで実際に何が開いているかを定期確認する
VPSの初期セキュリティ設定(rootログイン無効化・SSH鍵認証・fail2ban)と組み合わせると、攻撃面を最小化した構成になります。詳細はVPSを借りたら最初にやるセキュリティ設定10項目を参照してください。
各サービス公式
ファイアウォール設定を試す環境として、国内VPSの定番2サービスです。ConoHa VPS・Xserver VPSともにコントロールパネル側にセキュリティグループ機能があり、本記事で解説した2層構成をすぐに実践できます。
- ConoHa VPS: コントロールパネルのセキュリティグループ設定が直感的で、OS側のufwと併用しやすい構成です。
- Xserver VPS: シンプルなパネル構成で、ファイアウォールルールの管理が分かりやすいです。