ファイアウォール設定入門 - ufwとfirewalldの基礎
ファイアウォールとは何か?
ファイアウォールはネットワーク通信を許可・遮断するフィルタリング機構だ。Linux カーネルの iptables/nftables がその実体で、ufw と firewalld はそれを管理する高レベルツールに相当する。
ディストリビューション別の標準ツール
- Ubuntu / Debian 系:
ufw(Uncomplicated Firewall) - RHEL / CentOS / Fedora 系:
firewalld
ufw と firewalld はどう違うのか?
ufw はシンプルなコマンドラインインターフェースを重視した静的ルールセット型の設計だ。firewalld はゾーン(zone)という概念でルールを管理し、サービスを再起動せずに D-Bus 経由でルールを動的に変更できる。
| 項目 | ufw | firewalld |
|---|---|---|
| 主な用途 | Ubuntu / Debian | RHEL / CentOS |
| ルール管理 | 静的 | 動的(zone ベース) |
| 設定の複雑さ | シンプル | 柔軟だが複雑 |
| バックエンド | iptables / nftables | nftables / iptables |
ufw の基本的な使い方
インストールと有効化
Ubuntu ではデフォルトでインストール済みだ。有効化する前に SSH を許可しないとロックアウトされるため、順番に注意する。
$ sudo ufw status Status: inactive $ sudo ufw allow 22/tcp Rules updated Rules updated (v6) $ sudo ufw enable Command may disrupt existing ssh connections. Proceed with operation (y|n)? y Firewall is active and enabled on system startup
ufw enable の前に必ず SSH(22番ポート)を許可すること。順番を誤るとリモート接続が切断される。
ポートの許可・拒否
# ポート番号で許可 $ sudo ufw allow 80/tcp $ sudo ufw allow 443/tcp # サービス名で許可(/etc/services の定義を参照) $ sudo ufw allow ssh $ sudo ufw allow http $ sudo ufw allow https # ポートを拒否 $ sudo ufw deny 23/tcp # IP アドレスからの接続を許可 $ sudo ufw allow from 192.168.1.0/24 # 特定 IP からの特定ポートへのアクセスを許可 $ sudo ufw allow from 192.168.1.100 to any port 3306
デフォルトポリシーの設定
# インバウンドをデフォルト拒否(推奨) $ sudo ufw default deny incoming # アウトバウンドをデフォルト許可 $ sudo ufw default allow outgoing
ルールの確認・削除
# 現在のルールを番号付きで表示 $ sudo ufw status numbered
Status: active
To Action From
-- ------ ----
[ 1] 22/tcp ALLOW IN Anywhere
[ 2] 80/tcp ALLOW IN Anywhere
[ 3] 443/tcp ALLOW IN Anywhere
# ルール番号を指定して削除 $ sudo ufw delete 3 # ルール内容を指定して削除 $ sudo ufw delete allow 443/tcp
ufw の無効化とリセット
# 一時的に無効化(ルールは保持) $ sudo ufw disable # ルールを完全にリセット $ sudo ufw reset
ufw reset はすべてのルールを削除する。実行前に現在のルールをメモしておくこと。
firewalld の基本的な使い方
インストールと起動
RHEL 系では標準でインストール済みの場合が多い。
# RHEL / CentOS $ sudo yum install firewalld # Fedora $ sudo dnf install firewalld $ sudo systemctl start firewalld $ sudo systemctl enable firewalld
ゾーン(zone)の概念
firewalld のルールはゾーンに紐付く。各ネットワークインターフェースはいずれか 1 つのゾーンに属し、そのゾーンのルールが適用される。
# 使用可能なゾーン一覧 $ firewall-cmd --get-zones block dmz drop external home internal public trusted work # デフォルトゾーンの確認 $ firewall-cmd --get-default-zone public # アクティブなゾーンとインターフェースの確認 $ firewall-cmd --get-active-zones
ポートの許可・削除
# 現在のルールを確認 $ firewall-cmd --list-all # ポートを一時的に許可(再起動で消える) $ sudo firewall-cmd --add-port=80/tcp # ポートを永続的に許可 $ sudo firewall-cmd --add-port=80/tcp --permanent $ sudo firewall-cmd --reload # サービス名で許可 $ sudo firewall-cmd --add-service=http --permanent $ sudo firewall-cmd --add-service=https --permanent $ sudo firewall-cmd --reload # ポートを削除 $ sudo firewall-cmd --remove-port=80/tcp --permanent $ sudo firewall-cmd --reload
--permanent を付けると設定ファイルに書き込まれ再起動後も有効になる。--permanent なしの変更は現在のセッションのみ有効。--reload で設定ファイルの内容を即時適用できる。
使用可能なサービス一覧
$ firewall-cmd --get-services
ゾーンへのソース IP 追加
# 特定のサブネットを trusted ゾーンに追加 $ sudo firewall-cmd --zone=trusted --add-source=192.168.1.0/24 --permanent $ sudo firewall-cmd --reload
よくある設定パターンはどれか?
Web サーバー(HTTP / HTTPS + SSH)
ufw の場合:
$ sudo ufw default deny incoming $ sudo ufw default allow outgoing $ sudo ufw allow ssh $ sudo ufw allow http $ sudo ufw allow https $ sudo ufw enable
firewalld の場合:
$ sudo firewall-cmd --set-default-zone=public $ sudo firewall-cmd --add-service=ssh --permanent $ sudo firewall-cmd --add-service=http --permanent $ sudo firewall-cmd --add-service=https --permanent $ sudo firewall-cmd --reload
データベースサーバー(MySQL を特定 IP のみ許可)
ufw の場合:
$ sudo ufw allow from 192.168.1.10 to any port 3306 proto tcp
firewalld の場合:
$ sudo firewall-cmd --add-rich-rule='rule family="ipv4" source address="192.168.1.10" port port="3306" protocol="tcp" accept' --permanent $ sudo firewall-cmd --reload
設定が反映されないときはどうするか?
設定後にポートへの接続が通らない場合、以下の順で確認する。
# ufw: ファイアウォール自体が有効か確認 $ sudo ufw status Status: active # firewalld: サービスが起動しているか確認 $ sudo systemctl status firewalld # 実際にポートがリッスンしているか確認 $ ss -tlnp | grep :80
クラウド環境(AWS / GCP / Azure)の注意点
クラウドの場合、VPC のセキュリティグループやネットワーク ACL が OS レベルのファイアウォールより前段で動作する。OS 側でポートを開けてもクラウド側で塞がれていれば通信できない。両方の設定を確認すること。
# ログを有効化して確認(ufw) $ sudo ufw logging on $ sudo tail -f /var/log/ufw.log # ログを確認(firewalld) $ sudo journalctl -u firewalld -f