「iptablesとfirewalldの違いがよく分からず、どちらを使えばいいのか迷っている」
Linuxサーバーを運用する以上、ファイアウォールの設定は避けて通れません。ネットで断片的な情報をコピペしただけでは、なぜその設定が必要なのかが分からず、トラブル時に手も足も出なくなります。
この記事では、RHEL/CentOS/AlmaLinux/Rocky Linuxで標準採用されている
firewalld の実践的な使い方を解説します。基本的なポート開放やサービスの許可から、ゾーンの仕組み、リッチルールを使った細かいアクセス制御、そしてよくあるトラブルの対処法まで、現場で必要な知識を網羅しました。
※firewalldの操作には
root 権限(または sudo)が必要です。以降のコマンド例は全て root 権限で実行するものとします。実行環境:RHEL 9.4 / Rocky Linux 9.4 / AlmaLinux 9.4 で動作確認済み
・firewall-cmd --list-all で現在の設定を確認できる
・--permanent を付けないと再起動で設定が消えることとその対処法
・ポート開放は --add-port、サービス追加は --add-service の使い方
・ゾーンでNIC単位のアクセス制御を柔軟に設計する方法
・よくあるエラー(ポートが開かない・設定が消える)の原因と対処法
でも安心してください。プロのエンジニアはコマンドを暗記していません。
「現場で使える型」を効率よく使いこなしているだけです。
なぜファイアウォール設定が必要なのか
サーバーをインターネットに公開すると、SSHへの不正ログイン試行、ポートスキャンなど、外部からの攻撃は日常的に発生します。ファイアウォールは「必要な通信だけを許可し、それ以外は全て遮断する」ための仕組みです。
たとえばWebサーバーであれば、HTTP(80番ポート)とHTTPS(443番ポート)だけを開放し、それ以外のポートへのアクセスは拒否するのが基本です。この「必要最小限だけ開ける」という考え方を最小権限の原則と呼び、サーバーセキュリティの基本中の基本です。
firewalldの基本(ゾーンとサービス)
iptablesとの違い
RHEL 6以前は
iptables でファイアウォールを直接管理していました。RHEL 7以降では firewalld が標準となっています。両者の違いを整理します。| 比較項目 | iptables | firewalld |
|---|---|---|
| 設定単位 | チェイン+ルール番号 | ゾーン+サービス/ポート |
| 永続化 | iptables-save |
firewall-cmd --permanent |
| 設定反映 | 即時(save別途) | --permanentはfirewall-cmd --reloadが必要 |
| 管理ツール | iptables / ip6tables | firewall-cmd / firewall-config |
| reload時の挙動 | ルール全体を再読み込み(一瞬遮断のリスク) | アクティブな接続を切断しない |
firewalldは内部的にnftables(RHEL 8以降)またはiptablesをバックエンドとして使っています。つまり、firewalldは「iptables/nftablesを人間にとって扱いやすくするフロントエンド」という位置づけです。
現在のRHEL系ディストリビューションを使っているなら、firewalldを使ってください。iptablesを直接操作する必要はほとんどありません。
ゾーン(zone)とは
ゾーンは「ネットワークインターフェースに適用するセキュリティレベルのテンプレート」です。firewalldにはあらかじめ複数のゾーンが用意されています。
| ゾーン名 | 用途 | デフォルトの許可 |
|---|---|---|
| drop | すべて破棄(応答なし) | なし |
| block | すべて拒否(ICMP応答あり) | なし |
| public | 公開ネットワーク(デフォルト) | ssh, dhcpv6-client |
| external | 外部ネットワーク(NAT用) | ssh |
| dmz | DMZ(非武装地帯)向け | ssh |
| work | 職場ネットワーク | ssh, cockpit, dhcpv6-client |
| home | 自宅ネットワーク | ssh, cockpit, dhcpv6-client, mdns, samba-client |
| internal | 内部ネットワーク | homeと同じ |
| trusted | すべて許可 | 全通信 |
実務で最もよく使うのは
public ゾーンです。特に指定しなければ、このゾーンが適用されます。サービス(service)とは
サービスは「ポート番号とプロトコルの組み合わせに名前を付けたもの」です。たとえば
http というサービスは「TCP 80番ポート」、https は「TCP 443番ポート」を意味します。ポート番号を直接指定するよりも、サービス名で管理した方が設定の見通しがよくなります。firewalldに定義済みのサービスは以下のコマンドで一覧表示できます。
# 利用可能なサービス一覧を表示 # firewall-cmd --get-services RH-Satellite-6 RH-Satellite-6-capsule amanda-client amanda-k5-client amqp amqps apcupsd ... http https imap imaps ipp ipp-client ipsec ... mysql nfs nfs3 nmea-0183 nrpe ntp ... postgresql proxy-dhcp radius rdp redis rpc-bind ... samba samba-client samba-dc smtp smtp-submission smtps snmp ... ssh syncthing syslog telnet tftp ...
基本的な使い方
1. 現在の状態を確認する
まずはfirewalldが動作しているか、現在どのような設定になっているかを確認しましょう。
# firewalldの動作状態を確認する # firewall-cmd --state running
running と表示されれば正常に動作しています。現在のゾーンに適用されている設定の全体像を確認するには、
--list-all を使います。# デフォルトゾーンの設定を一覧表示する # firewall-cmd --list-all public (active) target: default icmp-block-inversion: no interfaces: ens192 sources: services: cockpit dhcpv6-client ssh ports: protocols: forward: yes masquerade: no forward-ports: source-ports: rich rules:
public ゾーンが ens192 インターフェースに適用されていて、ssh と dhcpv6-client、cockpit のサービスが許可されていることが分かります。サーバーを引き継いだときは、まずこのコマンドで現在の状態を確認するのが鉄則です。
2. ポートを開放する
特定のポート番号を直接指定して開放する方法です。たとえば、TCP 8080番ポートを開放するには以下のように実行します。
# TCP 8080番ポートを開放する(即時反映・一時的) # firewall-cmd --add-port=8080/tcp success
--list-ports を使います。# 開放中のポートを確認する # firewall-cmd --list-ports 8080/tcp
--remove-port を使います。# TCP 8080番ポートを閉じる # firewall-cmd --remove-port=8080/tcp success
3. サービスを許可する
ポート番号を直接指定する代わりに、サービス名で許可する方法です。Webサーバーを公開する場合は以下のように設定します。
# HTTPサービス(TCP 80番ポート)を許可する # firewall-cmd --add-service=http success # HTTPSサービス(TCP 443番ポート)を許可する # firewall-cmd --add-service=https success
--list-services を使います。# 許可済みサービスの一覧を表示する # firewall-cmd --list-services cockpit dhcpv6-client http https ssh
--remove-service を使います。不要なサービスは閉じておくのがセキュリティの基本です。特にcockpitは、使っていない場合は削除しましょう。
# cockpitサービスの許可を取り消す # firewall-cmd --remove-service=cockpit success
4. サービスの詳細情報を確認する
サービスがどのポートを使うか確認するには、
--info-service を使います。# httpサービスの定義内容を確認 # firewall-cmd --info-service=http http ports: 80/tcp protocols: source-ports: modules: destination: includes: helpers:
5. 設定を永続化する(--permanent)
firewalldの設定には「ランタイム(実行中のみ有効)」と「永続(再起動後も有効)」の2種類があります。
永続的な設定を行うには、コマンドに
--permanent オプションを付けます。# HTTPサービスを永続的に許可する # firewall-cmd --permanent --add-service=http success
--permanent を付けた設定は、永続設定ファイルに書き込まれるだけで、実行中のfirewalldにはすぐに反映されません。反映するには --reload が必要です。# 永続設定をランタイムに反映する # firewall-cmd --reload success
・手順1:まず
--permanent なしで設定を追加し、即座に動作確認する・手順2:動作に問題がなければ
--permanent 付きで同じコマンドを実行する・手順3:
--reload で永続設定を反映するこの手順なら、設定ミスがあっても firewalld を reload すれば永続設定(=変更前の状態)に戻せます。
6. ゾーンを確認・変更する
デフォルトゾーンを確認するには
--get-default-zone を使います。# デフォルトゾーンを確認する # firewall-cmd --get-default-zone public
--set-default-zone を使います。# デフォルトゾーンを internal に変更する # firewall-cmd --set-default-zone=internal success
--zone オプションを使います。# ens224をtrustedゾーンに割り当てる # firewall-cmd --zone=trusted --change-interface=ens224 --permanent success # 設定を反映する # firewall-cmd --reload success
--get-active-zones が便利です。# アクティブなゾーンとインターフェースの割り当てを確認する # firewall-cmd --get-active-zones public interfaces: ens192 trusted interfaces: ens224
--zone オプションを付けて --list-all を実行します。# trustedゾーンの設定を表示 # firewall-cmd --zone=trusted --list-all trusted (active) target: ACCEPT icmp-block-inversion: no interfaces: ens224 sources: services: ports: protocols: forward: yes masquerade: no forward-ports: source-ports: rich rules:
# 全ゾーンの設定を表示する # firewall-cmd --list-all-zones
応用・実務Tips
リッチルールで細かいアクセス制御
リッチルール(rich rule)は、単純なサービス許可やポート開放では対応できない、より詳細な条件を指定するための仕組みです。
たとえば「特定のIPアドレスからのSSH接続だけを許可する」といった設定が可能です。
# 192.168.1.100 からのSSH接続のみ許可する # firewall-cmd --permanent --add-rich-rule='rule family="ipv4" source address="192.168.1.100" service name="ssh" accept' success
# 10.0.0.50 からの全通信を拒否する # firewall-cmd --permanent --add-rich-rule='rule family="ipv4" source address="10.0.0.50" drop' success
--list-rich-rules を使います。# リッチルールの一覧を表示する # firewall-cmd --list-rich-rules rule family="ipv4" source address="192.168.1.100" service name="ssh" accept
--remove-rich-rule で、追加時と同じルール文字列を指定します。# リッチルールを削除する # firewall-cmd --permanent --remove-rich-rule='rule family="ipv4" source address="192.168.1.100" service name="ssh" accept' success # 設定を反映する # firewall-cmd --reload success
特定のIPアドレスだけ許可する
「社内ネットワークからのみ管理画面にアクセスさせたい」という要件は実務で頻繁に出てきます。リッチルールを使って、特定のネットワークからだけポートを開放する方法を紹介します。
# 192.168.1.0/24 のネットワークからのみ TCP 3306(MySQL)を許可する # firewall-cmd --permanent --add-rich-rule='rule family="ipv4" source address="192.168.1.0/24" port port="3306" protocol="tcp" accept' success # 設定を反映する # firewall-cmd --reload success
設定変更前にバックアップを取る
ファイアウォール設定のミスはサーバーへの接続が切れる原因になります。
変更前に現在の設定をファイルに保存しておきましょう。
# 現在の設定をバックアップ # firewall-cmd --list-all > ~/firewall-backup-$(date +%Y%m%d).txt # 全ゾーンの設定をバックアップ # firewall-cmd --list-all-zones > ~/firewall-zones-backup-$(date +%Y%m%d).txt
トラブルシュート・エラー対処
「FirewallD is not running」が出た場合
firewall-cmd を実行した際に以下のエラーが出ることがあります。# firewall-cmd --state not running
# firewalldを起動する # systemctl start firewalld # 動作確認 # firewall-cmd --state running # サーバー再起動時にも自動起動するようにする # systemctl enable firewalld Created symlink /etc/systemd/system/dbus-org.fedoraproject.FirewallD1.service -> /usr/lib/systemd/system/firewalld.service. Created symlink /etc/systemd/system/multi-user.target.wants/firewalld.service -> /usr/lib/systemd/system/firewalld.service.
systemctl start firewalld でエラーが出る場合は、iptablesサービスと競合している可能性があります。「ALREADY_ENABLED」が表示された場合
すでに同じ設定が存在しています。エラーではなく警告です。
firewall-cmd --list-all で現在の設定を確認してください。--permanentを付けたのに設定が反映されない
--permanent は永続設定ファイルに書き込むだけで、ランタイム(現在動作中のルール)には反映しません。以下のどちらかで対応してください。
・
firewall-cmd --reload で永続設定をランタイムに読み込む・
--permanent なしで同じコマンドを実行してランタイムにも即時反映するiptablesとfirewalldが競合する場合
RHEL 9系でiptablesサービスとfirewalldを同時に動かすと予期しない動作になります。
どちらか一方だけを有効にしてください。
# iptablesサービスが動いていないか確認する # systemctl status iptables # 動いている場合は停止して無効化する # systemctl stop iptables # systemctl disable iptables # systemctl mask iptables # firewalldが動作していることを確認 # firewall-cmd --state running
systemctl mask を実行すると、iptablesサービスが手動でも起動できなくなります。firewalldに完全に移行する場合に使ってください。ポートを開放したのにアクセスできない時の確認手順
「firewall-cmdでポートを開けたのに、外部からアクセスできない」というトラブルは非常に多いです。以下の手順で原因を切り分けてください。
1. firewalldの設定を再確認する
まずは本当にポートが開放されているか確認します。
# 現在の設定を確認する # firewall-cmd --list-all
--permanent で追加した後に --reload を忘れていないか、ゾーンが正しいかを確認してください。2. サービスがポートをリッスンしているか確認する
ファイアウォールでポートを開放しても、そのポートで待ち受けるサービスが起動していなければアクセスできません。
# 指定ポートでサービスが待ち受けているか確認する # ss -tlnp | grep 8080
3. SELinuxが通信をブロックしていないか確認する
RHEL系ではSELinux(Security-Enhanced Linux)が有効になっていることが多く、firewalldとは別にアクセスをブロックする場合があります。
# SELinuxの状態を確認する # getenforce Enforcing # SELinux の拒否ログを確認する # ausearch -m AVC --start recent
semanage port コマンドでポートにラベルを付与する必要があります。# SELinuxで HTTP用ポートとして 8080 を許可する # semanage port -a -t http_port_t -p tcp 8080
semanage がインストールされていない場合は dnf install policycoreutils-python-utils でインストールしてください。4. クラウド環境のセキュリティグループを確認する
AWS・Azure・GCPなどのクラウド環境では、OS上のfirewalldとは別にクラウド側のセキュリティグループ(またはネットワークセキュリティグループ)でも通信を制御しています。firewalldで開放してもクラウド側で許可していなければアクセスできません。
本記事のまとめ
firewall-cmdの操作を一覧にまとめます。
| やりたいこと | コマンド |
|---|---|
| firewalldの状態を確認する | firewall-cmd --state |
| 現在の設定を一覧表示する | firewall-cmd --list-all |
| ポートを開放する(一時的) | firewall-cmd --add-port=ポート番号/tcp |
| ポートを開放する(永続的) | firewall-cmd --permanent --add-port=ポート番号/tcp |
| ポートを閉じる(永続的) | firewall-cmd --permanent --remove-port=ポート番号/tcp |
| サービスを許可する | firewall-cmd --add-service=サービス名 |
| サービスを許可する(永続的) | firewall-cmd --permanent --add-service=サービス名 |
| サービスを削除する(永続的) | firewall-cmd --permanent --remove-service=サービス名 |
| サービスの詳細を確認する | firewall-cmd --info-service=サービス名 |
| 永続設定を反映する | firewall-cmd --reload |
| デフォルトゾーンを確認する | firewall-cmd --get-default-zone |
| デフォルトゾーンを変更する | firewall-cmd --set-default-zone=ゾーン名 |
| NICのゾーン割り当て | firewall-cmd --zone=ゾーン名 --change-interface=NIC名 --permanent |
| アクティブゾーンを確認する | firewall-cmd --get-active-zones |
| リッチルールでIP制限する | firewall-cmd --permanent --add-rich-rule='rule family="ipv4" source address="IPアドレス" service name="サービス名" accept' |
| 定義済みサービス一覧 | firewall-cmd --get-services |
| firewalldを起動する | systemctl start firewalld |
| firewalldを自動起動に設定する | systemctl enable firewalld |
firewalldは「--permanentを付けて--reloadする」が基本のワークフローです。
慣れないうちは、変更前に
firewall-cmd --list-all で現状を確認し、設定のバックアップを取る習慣をつけてください。ゾーンを使いこなせるようになると、NIC単位の柔軟なアクセス制御が実現できます。
まずはpublicゾーンの設定をしっかり把握するところから始めましょう。
ファイアウォールの設定ミスで、冷や汗をかいたことはありませんか?
firewalldのポート開放やゾーン設定は、一つ間違えるとサーバーへの接続が完全に切れます。ネットの断片的な情報をつなぎ合わせるのではなく、現場で通用する安全なLinuxサーバー構築の「型」を体系的に身につけたい方へ、『Linuxサーバー構築入門マニュアル(図解60P)』を完全無料でプレゼントしています。
「独学の時間がもったいない」「プロから直接、現場の技術を最短で学びたい」という本気の方には、2日で実務レベルのスキルが身につく【初心者向けハンズオンセミナー】も開催しています。
3,100名以上が実践した「型」を無料で公開中
プロのエンジニアはコマンドを暗記していません。
「現場で使える型」を効率よく使いこなしているだけです。
その「型」を図解60Pにまとめた入門マニュアルを、完全無料でプレゼントしています。
登録10秒/合わなければ解除3秒 / 詳細はこちら

無料メルマガで学習を続ける
Linuxの実践スキルをメールで毎週お届け。
登録は1分、解除もいつでも可。
登録無料・いつでも解除できます