Linux ファイアウォール設定:VPS で UFW と firewalld を使う方法(IPv6 対応)
インストール直後の Linux サーバーは、サービスが開いたポートすべてで外部に応答します。そのためホストファイアウォールは最初に設定すべき項目の一つです。このガイドでは、Debian / Ubuntu では UFW による Linux ファイアウォール設定、CentOS・Rocky Linux・AlmaLinux では firewalld の使い方を説明します。まず SSH を許可し、Web ポートを開け、重要なサービスを送信元 IP で制限し、IPv6 も保護し、締め出された場合の復旧方法までを扱います。ヨハネスブルグ・モスクワ・東京・ソウルの JUSTG クラウドサーバーには無料で IPv6 が付くため、IPv6 のルールも IPv4 と同じくらい重要です。
ステップ1:開いているポートと SSH ポートを確認
ルールを書く前に、実際に待ち受けているサービスと SSH のポート番号を確認します。SSH をカスタムポートに変更している場合は、以下の SSH ルールをすべて 22 ではなくそのポートに置き換えてください。
# Which ports are services actually listening on?
ss -tulpn
# Which port does SSH use?
sshd -T | grep -i '^port'
ステップ2:有効化の前にセーフティネットを用意
ルールを 1 つ間違えるだけで SSH セッションが切れることがあります。一定時間後にファイアウォールを自動で無効化するタイマーをバックグラウンドで動かしておけば、自動的に戻れます。新しいターミナルでログインできることを確認したらタイマーを取り消します。
# Safety net: turn the firewall off again in 10 minutes unless you cancel it
nohup sh -c 'sleep 600; ufw disable' >/dev/null 2>&1 & # UFW
nohup sh -c 'sleep 600; systemctl stop firewalld' >/dev/null 2>&1 & # firewalld
# Everything works? Cancel the timer:
pkill -f 'sleep 600'
ステップ3:Debian / Ubuntu で UFW を設定
UFW(Uncomplicated Firewall)はカーネルファイアウォールのシンプルなフロントエンドです。受信のデフォルトを拒否にし、まず SSH を許可してから有効化します。ufw limit は SSH を許可しつつ、短時間に接続が多すぎるアドレスを一時的にブロックします。
apt update && apt install -y ufw
# Make sure IPv6 rules are managed too
grep '^IPV6' /etc/default/ufw # should print IPV6=yes
ufw default deny incoming
ufw default allow outgoing
# SSH FIRST (use your real SSH port if you changed it)
ufw limit 22/tcp # allow + basic brute-force rate limit
# Web server
ufw allow 80,443/tcp
ufw enable # answer "y"
ufw status verbose
ステップ4:UFW で送信元 IP を制限(IPv4 と IPv6)
データベースや管理画面、監視エージェントをインターネット全体に公開してはいけません。既知のアドレスからのみ許可します。UFW はルールを上から順に評価するため、拒否ルールは範囲の広い許可ルールより上に挿入する必要があります。
# Allow MySQL only from one office IPv4 and one IPv6 network
ufw allow from 198.51.100.25 to any port 3306 proto tcp
ufw allow from 2001:db8:10::/64 to any port 3306 proto tcp
# Block an abusive network (insert at the top so it is matched first)
ufw insert 1 deny from 203.0.113.0/24
# List rules with numbers and delete one
ufw status numbered
ufw delete 4
ステップ5:CentOS / Rocky Linux / AlmaLinux で firewalld を設定
firewalld はゾーン単位で動作し、通常ネットワークインターフェースは public ゾーンに属していて SSH は最初から許可されています。--permanent を付けたルールは再起動後も残りますが、--reload するまで反映されません。
dnf install -y firewalld # CentOS 7: yum install -y firewalld
systemctl enable --now firewalld
firewall-cmd --get-default-zone # usually "public"
# SSH FIRST (or: --add-port=2222/tcp for a custom port)
firewall-cmd --permanent --add-service=ssh
# Web server
firewall-cmd --permanent --add-service=http --add-service=https
# Close what you do not use
firewall-cmd --permanent --remove-service=cockpit
firewall-cmd --reload
firewall-cmd --list-all
ssh サービスを削除する前に --add-port でそのポートを追加してください。Rocky / AlmaLinux では SELinux でもポートの許可が必要です。ステップ6:firewalld のリッチルールで送信元 IP を制限
リッチルールでは送信元アドレス・ポート・動作を 1 行で指定できます。1 つのルールは 1 つのアドレスファミリーにしか適用されないため、IPv4 用と IPv6 用をそれぞれ書きます。
# Allow MySQL from one IPv4 address and one IPv6 network only
firewall-cmd --permanent --add-rich-rule='rule family="ipv4" source address="198.51.100.25" port port="3306" protocol="tcp" accept'
firewall-cmd --permanent --add-rich-rule='rule family="ipv6" source address="2001:db8:10::/64" port port="3306" protocol="tcp" accept'
# Drop all traffic from an abusive network
firewall-cmd --permanent --add-rich-rule='rule family="ipv4" source address="203.0.113.0/24" drop'
firewall-cmd --reload
firewall-cmd --list-rich-rules
ステップ7:IPv6 もフィルタされているか確認
IPv4 のルールは完璧なのに、同じサービスが IPv6 では丸見え、というのはよくあるミスです。UFW は IPV6=yes のときだけ IPv6 を管理します(ufw status に「(v6)」の行が出ます)。firewalld のゾーンとサービスは両方に自動で適用されます。別のマシンからテストしましょう。
# Your server's IPv6 address
ip -6 addr show scope global
# From ANOTHER machine: test a port over IPv4 and IPv6
nc -vz 203.0.113.50 443
nc -vz 2001:db8:50::10 443
nc -vz 2001:db8:50::10 3306 # should fail from a non-allowed address
ステップ8:Docker の公開ポートに注意
Docker は独自に iptables ルールを書き込むため、-p 8080:80 で公開したポートは UFW や firewalld でブロックしたつもりでも外部から届くことがあります。コンテナは 127.0.0.1 に公開してリバースプロキシを前段に置くか、DOCKER-USER チェーンで管理してください。
# Publish a container port on localhost only, then proxy it with Nginx
docker run -d -p 127.0.0.1:8080:80 nginx
ステップ9:ファイアウォールで締め出されたときの復旧
変更後に SSH が応答しなくなったら、まずステップ2 のタイマーを待ちます。それ以外の場合は VNC コンソールを使います。JUSTG クライアントエリア → 製品とサービス → 対象サーバー → 管理パネルを開いてください(コンソールが見つからない場合はチケットでお問い合わせください)。root でログインし、SSH を再度許可します。
# Debian / Ubuntu (UFW)
ufw allow 22/tcp # or: ufw disable
# CentOS / Rocky / AlmaLinux (firewalld)
firewall-cmd --panic-off 2>/dev/null
firewall-cmd --add-service=ssh # runtime only; add --permanent once fixed
# last resort
systemctl stop firewalld
よくある質問
UFW と firewalld を同時に使えますか?
使わないでください。どちらも同じカーネルのテーブルを管理するため競合します。Debian/Ubuntu では UFW、CentOS/Rocky/AlmaLinux では firewalld を使い、もう一方は無効にします。
再起動したら firewalld のルールが消えました。
--permanent を付けずに追加したため、実行中の設定だけが変わっていました。firewall-cmd --runtime-to-permanent で現在のルールを保存できます。
攻撃してくる IP をブロックできますか?
できます。UFW では ufw insert 1 deny from 203.0.113.66、firewalld では drop を指定したリッチルールを使います。大規模な帯域攻撃はホストファイアウォールだけでは防げないため、サポートにご相談ください。
Linux ファイアウォールの設定で解決しない問題があれば、https://www.justg.com/submitticket.php からチケットを送信してください。JUSTG テクニカルサポートが対応いたします。