Linuxエンジニア養成講座 第20回|全36回・フェーズ3「ネットワークとインフラ基盤」の5回目(5/12回目)です。
前回まで: 第16回でTCP/IPの基礎、第17回でnmcliによるIP設定と疎通確認、第18回でプロキシ・DNS・NTPのクライアント設定、第19回でdnfによるパッケージ管理とEPEL導入を学びました。
今回学ぶこと: firewalld のゾーン・サービス・ポートの概念を理解し、firewall-cmd で通信ルールを設定する方法を実践します。
前回の予告で「パッケージをインストールできるようになった今、サーバーを『守る』技術へと進みましょう」とお伝えしました。今回はその「守る」技術の中核となる firewalld を学びます。
この記事を読み終えると、以下のことができるようになります。
- ファイアウォールが必要な理由を「ホワイトリスト思考」で説明できる
- firewalld のゾーン・サービス・ポートの関係を説明できる
firewall-cmdでサービスやポートの許可・削除ができる--permanentと--reloadの正しい使い方を理解し、設定を永続化できる- 2台の VM 間で通信制御を体験できる
- NIC ごとにゾーンを使い分けられる
- リッチルールの基本的な構文を読める
なぜファイアウォールが必要か
サーバーにソフトウェアをインストールしてサービスを起動すると、そのサーバーは外部からの通信を受け付けるようになります。Web サーバーなら TCP/80、データベースなら TCP/3306 といったポートが開きます。
しかし、すべての通信を受け入れてよいわけではありません。データベースのポートがインターネットから直接アクセスできる状態は、攻撃者にとって格好の標的です。第16回で学んだように、TCP/IP の仕組み上、IP アドレスとポート番号がわかれば通信を試みることができます。
ファイアウォールの基本的な考え方は「必要な通信だけを許可し、それ以外はすべて拒否する」です。これをホワイトリスト方式と呼びます。第18回で学んだ alma-proxy の Squid が許可ドメインだけを中継していたのと同じ考え方です。
NW機器のFWとホストFWの違い
企業ネットワークでは、ネットワーク機器として設置されるファイアウォール(NW機器FW)と、各サーバーに設定するファイアウォール(ホストFW)の2つが存在します。
NW機器FWはネットワークの境界に設置され、セグメント間の通信を制御します。一方、ホストFWは各サーバー自身が「自分への通信」を制御します。両方を併用するのが一般的です。NW機器FWが突破されても、ホストFWが最後の防壁として機能します。今回学ぶ firewalld は、このホストFWにあたります。

iptables から nftables、そして firewalld へ
Linux のファイアウォールには歴史があります。
かつては iptables コマンドでルールを直接記述していました。しかし iptables はルールの追加・削除のたびに全ルールを再読み込みする必要があり、運用面で課題がありました。その後、カーネル内部のパケットフィルタリング基盤が nftables に置き換わりました。
firewalld は、この nftables をバックエンドとして利用する管理ツールです。管理者は nftables のルールを直接書く必要はなく、firewall-cmd コマンドでゾーンやサービスといった抽象的な概念を通じてルールを管理できます。
AlmaLinux 9 のデフォルト構成は「firewalld(フロントエンド)+ nftables(バックエンド)」です。このシリーズでは firewall-cmd に統一して操作します。iptables コマンドは使いません。
firewalld の基本概念
ゾーン(zone)
firewalld の最も重要な概念がゾーンです。ゾーンとは「NIC ごとに異なるルールセットを適用できる仕組み」です。
たとえば、検証環境の alma-main には eth0(外部ネットワーク向け)と eth1(内部ネットワーク向け)があります。外部向けの eth0 には厳しいルール、内部向けの eth1 にはやや緩いルールを適用する、といった使い分けが可能です。

firewalld にはあらかじめ10個のゾーンが定義されています。よく使うものを紹介します。
| ゾーン名 | 特徴 | 用途 |
|---|---|---|
| public | SSH・DHCPv6・cockpit のみ許可(デフォルト) | 公開ネットワーク向け |
| internal | SSH・mDNS・Samba 等を追加で許可 | 内部ネットワーク向け |
| trusted | すべての通信を許可 | 完全に信頼できるネットワーク |
| drop | すべての通信を破棄(応答なし) | 完全遮断 |
| block | すべての通信を拒否(ICMP で応答あり) | 拒否を通知したい場合 |
drop と block の違いは「応答するかどうか」です。drop は通信を黙って捨てます。block は「拒否した」と ICMP メッセージで通知します。セキュリティの観点では drop のほうが情報を漏らさないため、外部向けでは drop が選ばれることがあります。
サービス(service)
firewalld の「サービス」とは、ポート番号のエイリアス(別名)です。「TCP/22 を許可する」代わりに「ssh サービスを許可する」と書けます。
エイリアスを使う利点は2つあります。
- 可読性: ルール一覧を見たときに「何を許可しているか」が一目でわかる
- 保守性: サービスが複数ポートを使う場合でも、1つのサービス名で管理できる
サービスの定義は XML ファイルで管理されています。ssh.xml の中身を見てみましょう。
alma-mainで実行
実行コマンド:
$ cat /usr/lib/firewalld/services/ssh.xml
実行結果:
<?xml version="1.0" encoding="utf-8"?>
<service>
<short>SSH</short>
<description>Secure Shell (SSH) is a protocol for logging into and executing commands on remote machines. It provides secure encrypted communications. If you plan on accessing your machine remotely via SSH over a firewalled interface, enable this option. You need the openssh-server package installed for this option to be useful.</description>
<port protocol="tcp" port="22"/>
</service>
<port protocol="tcp" port="22"/> の1行が「ssh サービス = TCP/22」という対応を定義しています。
http.xml も確認します。
実行コマンド:
$ cat /usr/lib/firewalld/services/http.xml
実行結果:
<?xml version="1.0" encoding="utf-8"?>
<service>
<short>WWW (HTTP)</short>
<description>HTTP is the protocol used to serve Web pages. If you plan to make your Web server publicly available, enable this option. This option is not required for viewing pages locally or developing Web pages.</description>
<port protocol="tcp" port="80"/>
</service>
サービス定義ファイルは2つの場所にあります。
/usr/lib/firewalld/services/— パッケージが提供するデフォルト定義(223個)。ここは編集しない/etc/firewalld/services/— 管理者がカスタムサービスを追加する場所。デフォルトと同名のファイルを置くと上書きできる
この二層構造は、第13回で学んだ systemd のユニットファイル(/usr/lib/systemd/ と /etc/systemd/)と同じ設計思想です。パッケージ管理側のファイルを直接編集しないことで、アップデート時の上書きを防ぎます。
ランタイムとパーマネント
firewalld の設定には「ランタイム」と「パーマネント」の2つの状態があります。ランタイムは今すぐ有効になる一時的な設定、パーマネントは再起動後も残る永続的な設定です。この2つの使い分けは重要なので、セクション7で詳しく体験します。
現在の状態を確認する
操作を始める前に、まず alma-main の firewalld がどのような状態にあるか確認します。
alma-mainで実行
firewalld が動作しているか確認します。
実行コマンド:
$ sudo firewall-cmd --state
実行結果:
running
running と表示されれば、firewalld は稼働中です。
デフォルトゾーンを確認します。
実行コマンド:
$ sudo firewall-cmd --get-default-zone
実行結果:
public
デフォルトゾーンは public です。明示的にゾーンを指定しない NIC は、すべてこのデフォルトゾーンに属します。
現在どのゾーンがアクティブで、どの NIC が割り当てられているか確認します。
実行コマンド:
$ sudo firewall-cmd --get-active-zones
実行結果:
public
interfaces: eth2 eth1 eth3 eth0
4つの NIC(eth0〜eth3)がすべて public ゾーンに属しています。
ゾーンの詳細な設定を一覧で表示します。
実行コマンド:
$ sudo firewall-cmd --list-all
実行結果:
public (active)
target: default
icmp-block-inversion: no
interfaces: eth0 eth1 eth2 eth3
sources:
services: cockpit dhcpv6-client ssh
ports:
protocols:
forward: yes
masquerade: no
forward-ports:
source-ports:
icmp-blocks:
rich rules:
出力の中で注目すべき項目を整理します。
interfaces: このゾーンに属する NICservices: 許可されているサービス。cockpit、dhcpv6-client、sshの3つが初期状態で許可されているports: サービス定義を使わずにポート番号で直接許可した通信(現在はなし)rich rules: 送信元 IP を限定するなど、より細かい条件を指定するルール(現在はなし)
cockpit は Linux サーバーの Web 管理ツールです。ブラウザから操作できる GUI を提供しますが、このシリーズではコマンドライン操作を学ぶため使いません。初期状態で許可されているだけなので、そのままにしておきます。
ここまでのコマンドをすべて覚える必要はありません。firewall-cmd --help を実行すれば、使えるオプションの一覧を確認できます。「状態を見たいときは --list-all」とだけ覚えておけば十分です。
サービスを許可・削除する
実際にサービスの許可と削除を操作してみましょう。ここでは http サービスを例に使います。http は第29回で Apache を構築するときに本格的に使いますが、今は firewall-cmd の操作例として使います。
alma-mainで実行
まず http サービスの中身を確認します。
実行コマンド:
$ sudo firewall-cmd --info-service=http
実行結果:
http
ports: 80/tcp
protocols:
source-ports:
modules:
destination:
includes:
helpers:
ports: 80/tcp と表示されています。「http サービスを許可する = TCP/80 を許可する」ということです。
http サービスを許可します。
実行コマンド:
$ sudo firewall-cmd --add-service=http
実行結果:
success
許可されたか確認します。
実行コマンド:
$ sudo firewall-cmd --list-services
実行結果:
cockpit dhcpv6-client http ssh
http が追加されました。特定のサービスが許可されているかどうかだけを確認したい場合は --query-service が使えます。
実行コマンド:
$ sudo firewall-cmd --query-service=http
実行結果:
yes
不要になったサービスを削除します。
実行コマンド:
$ sudo firewall-cmd --remove-service=http
実行結果:
success
実行コマンド:
$ sudo firewall-cmd --list-services
実行結果:
cockpit dhcpv6-client ssh
http が消えて、元の3つに戻りました。
なお、ここで行った操作はすべて「ランタイム」への変更です。firewalld を再起動すれば元に戻ります。永続化の方法はこのあとのセクションで学びます。
各オプションの詳細は man firewall-cmd で確認できます。--add-service、--remove-service、--query-service の3つは頻繁に使うので、この機会に man ページで周辺のオプションも眺めておくとよいでしょう。
ポートを許可・削除する
サービス定義に存在しないポートを許可したい場合は、ポート番号を直接指定します。たとえば、アプリケーションが 8080/tcp を使う場合の操作です。
alma-mainで実行
実行コマンド:
$ sudo firewall-cmd --add-port=8080/tcp
実行結果:
success
実行コマンド:
$ sudo firewall-cmd --list-ports
実行結果:
8080/tcp
--list-all で全体を見ると、services と ports の両方が確認できます。
実行コマンド:
$ sudo firewall-cmd --list-all
実行結果:
public (active)
target: default
icmp-block-inversion: no
interfaces: eth0 eth1 eth2 eth3
sources:
services: cockpit dhcpv6-client ssh
ports: 8080/tcp
protocols:
forward: yes
masquerade: no
forward-ports:
source-ports:
icmp-blocks:
rich rules:
ポートを削除します。
実行コマンド:
$ sudo firewall-cmd --remove-port=8080/tcp
実行結果:
success
サービスとポート、どちらを使うべきか
結論としては、サービス定義が存在するものはサービスで許可し、存在しないものだけポート番号で許可します。
理由は運用面にあります。半年後に --list-all を見たとき、services: http ssh と書いてあれば何を許可しているかすぐわかります。ports: 80/tcp 22/tcp では「80 は何だったか」と調べ直す手間がかかります。チームで管理するサーバーでは、可読性の差がミスの差になります。
–permanent と –reload を正しく使う
ここまでの操作はすべて「ランタイム」への変更でした。ランタイムの変更は firewalld の再起動やシステムの再起動で消えます。設定を永続化するには --permanent オプションを使います。
ただし、--permanent の挙動には注意が必要です。実際に試してみましょう。

alma-mainで実行
--permanent を付けて http サービスを追加します。
実行コマンド:
$ sudo firewall-cmd --permanent --add-service=http
実行結果:
success
パーマネント設定を確認します。
実行コマンド:
$ sudo firewall-cmd --permanent --list-all
実行結果:
public
target: default
icmp-block-inversion: no
interfaces:
sources:
services: cockpit dhcpv6-client http ssh
ports:
protocols:
forward: yes
masquerade: no
forward-ports:
source-ports:
icmp-blocks:
rich rules:
パーマネント設定には http が追加されています。しかし、ランタイム(現在動作中の設定)を確認するとどうでしょうか。
実行コマンド:
$ sudo firewall-cmd --list-services
実行結果:
cockpit dhcpv6-client ssh
ランタイムにはまだ反映されていません。--permanent は「次回の起動時(または reload 時)に反映する設定」を書き込むだけで、今すぐには反映されないのです。
--reload でパーマネント設定をランタイムに読み込みます。
実行コマンド:
$ sudo firewall-cmd --reload
実行結果:
success
実行コマンド:
$ sudo firewall-cmd --list-services
実行結果:
cockpit dhcpv6-client http ssh
reload 後にランタイムにも反映されました。
つまり、永続的な設定変更の正しい手順は次のとおりです。
firewall-cmd --permanent --add-service=xxxでパーマネントに追加firewall-cmd --reloadでランタイムに反映
もう一つの方法: –runtime-to-permanent
別のアプローチもあります。まずランタイムで試して問題がなければ永続化する方法です。
実行コマンド:
$ sudo firewall-cmd --add-port=8080/tcp
実行結果:
success
ここで通信テストを行い、問題がなければ永続化します。
実行コマンド:
$ sudo firewall-cmd --runtime-to-permanent
実行結果:
success
--runtime-to-permanent は、現在のランタイム設定をそのままパーマネントにコピーします。「試してから確定」できるため、本番環境では安全な方法です。
なお、--reload と似たオプションに --complete-reload がありますが、こちらは firewalld 自体を完全に再初期化します。通常の運用で使うのは --reload のほうです。
後続の演習に備えて、ここで追加した http サービスと 8080/tcp ポートをクリーンアップしておきます。
実行コマンド:
$ sudo firewall-cmd --permanent --remove-service=http
実行結果:
success
実行コマンド:
$ sudo firewall-cmd --permanent --remove-port=8080/tcp
実行結果:
success
実行コマンド:
$ sudo firewall-cmd --reload
実行結果:
success
ヒヤリハット: 深夜作業で –permanent を忘れた話
あるサーバーで深夜にメンテナンス作業を行い、新しいサービスのポートを開けました。動作確認もOK。翌朝、「サービスに繋がらない」と連絡が入りました。原因は、--permanent を付けずにルールを追加していたことでした。深夜の計画メンテナンスでサーバーが再起動され、ランタイムのみの設定が消えたのです。
対策は「設定変更後に --list-all と --permanent --list-all の両方を確認する」ことです。ランタイムとパーマネントの内容が一致していれば問題ありません。
体感演習: 2台間の通信を制御する
ここまでの知識を使って、実際に2台の VM 間でファイアウォールによる通信制御を体験します。alma-main で簡易的な HTTP サーバーを起動し、alma-sub からアクセスできるかどうかを確認します。
前提確認
alma-sub が起動していることを確認します。alma-main から ping で疎通確認を行います。
alma-mainで実行
実行コマンド:
$ ping -c 2 10.0.1.3
実行結果:
PING 10.0.1.3 (10.0.1.3) 56(84) bytes of data.
64 バイト応答 送信元 10.0.1.3: icmp_seq=1 ttl=64 時間=0.366ミリ秒
64 バイト応答 送信元 10.0.1.3: icmp_seq=2 ttl=64 時間=0.321ミリ秒
--- 10.0.1.3 ping 統計 ---
送信パケット数 2, 受信パケット数 2, 0% packet loss, time 1045ms
rtt min/avg/max/mdev = 0.321/0.343/0.366/0.022 ms
応答があれば疎通は正常です。
HTTP サーバーを起動する
alma-main で Python の簡易 HTTP サーバーを起動します。Python 3 は AlmaLinux 9 の Minimal Install に含まれており、追加インストールは不要です。/tmp ディレクトリで起動します。
alma-mainで実行
実行コマンド:
$ cd /tmp && python3 -m http.server 8080 --bind 0.0.0.0 &
実行結果:
[1] XXXXX
Serving HTTP on 0.0.0.0 port 8080 (http://0.0.0.0:8080/) ...
& を末尾に付けてバックグラウンドで起動しています。第12回で学んだ、バックグラウンドジョブの仕組みです。プロセスID(XXXXX の部分)は環境によって異なります。
ss コマンドでポートがリッスンされているか確認します。
実行コマンド:
$ ss -tlnp | grep 8080
実行結果:
LISTEN 0 5 0.0.0.0:8080 0.0.0.0:* users:(("python3",pid=20673,fd=3))
8080/tcp でリッスンしていることが確認できました。pid の数値は環境によって異なります。
ファイアウォールでブロックされることを確認
alma-sub から alma-main の 8080 番ポートにアクセスしてみます。
alma-subで実行
実行コマンド:
$ curl --connect-timeout 3 http://10.0.1.1:8080/
実行結果:
curl: (7) Failed to connect to 10.0.1.1 port 8080: ホストへの経路がありません
接続が失敗しました。alma-main では 8080/tcp でサーバーが動いているのに、通信が届きません。これが firewalld によるブロックです。alma-main の public ゾーンでは 8080/tcp が許可されていないため、通信が拒否されています。
ポートを許可して通信を通す
alma-main で 8080/tcp を許可します。
alma-mainで実行
実行コマンド:
$ sudo firewall-cmd --add-port=8080/tcp
実行結果:
success
再度 alma-sub からアクセスします。
alma-subで実行
実行コマンド:
$ curl --connect-timeout 3 http://10.0.1.1:8080/
実行結果:
<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01//EN" "http://www.w3.org/TR/html4/strict.dtd">
<html>
<head>
<meta http-equiv="Content-Type" content="text/html; charset=utf-8">
<title>Directory listing for /</title>
HTML の応答が返ってきました。ファイアウォールでポートを許可した結果、通信が通るようになったことがわかります。
ルールを削除して再びブロックされることを確認
許可ルールを削除して、再びブロックされることを確認します。
alma-mainで実行
実行コマンド:
$ sudo firewall-cmd --remove-port=8080/tcp
実行結果:
success
alma-subで実行
実行コマンド:
$ curl --connect-timeout 3 http://10.0.1.1:8080/
実行結果:
curl: (7) Failed to connect to 10.0.1.1 port 8080: ホストへの経路がありません
再びブロックされました。「ルールを追加すれば通る、削除すれば止まる」というファイアウォールの動きを体感できたと思います。
HTTP サーバーを停止する
バックグラウンドで動いている HTTP サーバーを停止します。
alma-mainで実行
実行コマンド:
$ kill %1
%1 はバックグラウンドジョブ番号1を指します。jobs コマンドでジョブが残っていないことを確認してください。
ゾーンを使い分ける
ここまではデフォルトの public ゾーン1つで操作してきました。しかし実際のサーバーでは、外部向けと内部向けの NIC で異なるルールを適用したいことがあります。alma-main の eth1(Internal Switch 側)を internal ゾーンに変更してみましょう。
alma-mainで実行
まずランタイムで変更して、動作を確認します。
実行コマンド:
$ sudo firewall-cmd --zone=internal --change-interface=eth1
実行結果:
success
アクティブゾーンを確認します。
実行コマンド:
$ sudo firewall-cmd --get-active-zones
実行結果:
internal
interfaces: eth1
public
interfaces: eth2 eth3 eth0
eth1 が internal ゾーンに移動し、残りの NIC は public のままです。特定の NIC がどのゾーンに属しているかは --get-zone-of-interface で確認できます。
実行コマンド:
$ sudo firewall-cmd --get-zone-of-interface=eth1
実行結果:
internal
internal ゾーンの許可サービスを確認してみましょう。
実行コマンド:
$ sudo firewall-cmd --zone=internal --list-all
実行結果:
internal (active)
target: default
icmp-block-inversion: no
interfaces: eth1
sources:
services: cockpit dhcpv6-client mdns samba-client ssh
ports:
protocols:
forward: yes
masquerade: no
forward-ports:
source-ports:
icmp-blocks:
rich rules:
public ゾーンは cockpit dhcpv6-client ssh の3つでしたが、internal ゾーンは mdns と samba-client が追加された5つです。内部ネットワーク向けに、より多くのサービスがデフォルトで許可されています。
ゾーン変更を永続化する
ランタイムで問題がなければ永続化します。
実行コマンド:
$ sudo firewall-cmd --permanent --zone=internal --change-interface=eth1
実行結果:
The interface is under control of NetworkManager, setting zone to 'internal'.
success
「The interface is under control of NetworkManager」というメッセージは、NIC が NetworkManager の管理下にあることを示しています。firewalld は NetworkManager と連携して、ゾーン設定を NIC の接続プロファイルに保存します。
実行コマンド:
$ sudo firewall-cmd --reload
実行結果:
success
実行コマンド:
$ sudo firewall-cmd --get-active-zones
実行結果:
internal
interfaces: eth1
public
interfaces: eth2 eth3 eth0
reload 後も eth1 は internal ゾーンに割り当てられています。
元に戻す
演習後は元の状態に戻しておきます。
実行コマンド:
$ sudo firewall-cmd --permanent --zone=public --change-interface=eth1
実行結果:
The interface is under control of NetworkManager, setting zone to 'public'.
success
実行コマンド:
$ sudo firewall-cmd --reload
実行結果:
success
実行コマンド:
$ sudo firewall-cmd --get-active-zones
実行結果:
public
interfaces: eth2 eth1 eth3 eth0
4つの NIC がすべて public ゾーンに戻りました。
リッチルール(rich rule)
これまでの --add-service や --add-port は、「全員に対して」許可するルールでした。しかし実務では「特定の IP アドレスからだけ許可したい」というケースがあります。たとえば「監視サーバー(10.0.1.3)からの HTTP アクセスだけを許可し、それ以外はブロックする」といった制御です。
このような細かい条件を指定するのがリッチルール(rich rule)です。
alma-mainで実行
実行コマンド:
$ sudo firewall-cmd --add-rich-rule='rule family="ipv4" source address="10.0.1.3" service name="http" accept'
実行結果:
success
追加されたリッチルールを確認します。
実行コマンド:
$ sudo firewall-cmd --list-rich-rules
実行結果:
rule family="ipv4" source address="10.0.1.3" service name="http" accept
構文を分解すると、次のようになります。
rule family="ipv4"— IPv4 の通信に適用するsource address="10.0.1.3"— 送信元が 10.0.1.3 の場合service name="http"— HTTP(TCP/80)への通信をaccept— 許可する
リッチルールの詳細な構文は man firewalld.richlanguage で確認できます。今は「送信元 IP で絞り込みができる」ということだけ覚えておいてください。第23回のログ管理で、rsyslog の転送ポート(514/tcp)を特定の IP からのみ許可する場面で活用します。
演習で追加したリッチルールを削除しておきます。
実行コマンド:
$ sudo firewall-cmd --remove-rich-rule='rule family="ipv4" source address="10.0.1.3" service name="http" accept'
実行結果:
success
ヒヤリハット: SSH を閉じてしまった話
ファイアウォールの設定変更で最も恐ろしい失敗は「SSH サービスを削除してしまい、リモートからログインできなくなる」ことです。
あるサーバーで不要なサービスを整理していた際、うっかり ssh を削除してしまいました。その瞬間は何も起きませんが(既存のSSH接続は維持されます)、一度切断すると新しいSSH接続ができなくなります。物理コンソールまたはVMコンソールから直接ログインして復旧するしかありません。
復旧手順は次のとおりです。仮想化ソフトのコンソール機能で alma-main に直接ログインし(Hyper-Vの場合: Hyper-Vマネージャーで「接続」)、以下を実行します。
実行コマンド:
$ sudo firewall-cmd --add-service=ssh
$ sudo firewall-cmd --runtime-to-permanent
現場での鉄則は「ファイアウォールの設定変更時は、別のターミナルで SSH セッションを開いたまま作業する」ことです。設定を変更したら、別のターミナルから新しい SSH 接続を試します。接続できることを確認してから、作業を続行します。
やってみよう
ここまでの内容を使って、以下の2つの課題に取り組んでください。
課題1: HTTP(80番ポート)を永続的に許可する
alma-main で HTTP サービス(TCP/80)を永続的に許可してください。手順は次のとおりです。
firewall-cmd --permanent --add-service=httpでパーマネントに追加するfirewall-cmd --reloadでランタイムに反映するfirewall-cmd --list-allで services に http が含まれていることを確認するfirewall-cmd --permanent --list-allでパーマネントにも http が含まれていることを確認する
ランタイムとパーマネントの両方に http が表示されていれば成功です。
課題2: eth1 を internal ゾーンに永続的に変更する
alma-main の eth1 を internal ゾーンに永続的に変更し、許可サービスの違いを確認してください。
firewall-cmd --permanent --zone=internal --change-interface=eth1でゾーンを変更するfirewall-cmd --reloadでランタイムに反映するfirewall-cmd --get-active-zonesで eth1 が internal に属していることを確認するfirewall-cmd --zone=internal --list-allで許可サービスの一覧を確認する- public ゾーンとの許可サービスの違いを比較する
internal ゾーンには public にはない mdns と samba-client が含まれていることが確認できるはずです。
クリーンアップ
演習が終わったら、以下のコマンドで元の状態に戻してください。
alma-mainで実行
実行コマンド:
$ sudo firewall-cmd --permanent --remove-service=http
実行結果:
success
実行コマンド:
$ sudo firewall-cmd --permanent --zone=public --change-interface=eth1
実行結果:
The interface is under control of NetworkManager, setting zone to 'public'.
success
実行コマンド:
$ sudo firewall-cmd --reload
実行結果:
success
実行コマンド:
$ sudo firewall-cmd --list-all
services が cockpit dhcpv6-client ssh のみ、interfaces に eth0〜eth3 の4つが public に表示されていれば、クリーンアップ完了です。
まとめと次回予告
今回は firewalld を使ったファイアウォールの基本を学びました。
覚えておいてほしいポイントは次の3つです。
- firewalld は「ゾーン」で NIC ごとにルールを分け、「サービス」や「ポート」で許可する通信を制御する
- 永続化は
--permanent+--reload。ランタイムで試してから--runtime-to-permanentで確定する方法もある - SSH を閉じないこと。設定変更時は別セッションで接続確認するのが鉄則
今回学んだ firewall-cmd は、後続の回で繰り返し使います。第23回の rsyslog リモート転送では 514/tcp の許可が必要になりますし、第29回の Web サーバー構築では http/https サービスの許可が前提になります。
なお、クラウド環境(AWS や Azure)にも「Security Group」や「NSG(Network Security Group)」と呼ばれる同様の仕組みがあります。「必要な通信だけを許可する」というホワイトリスト思考は、オンプレミスでもクラウドでも共通の考え方です。
各オプションの詳細は man firewall-cmd で確認できます。ゾーン定義の詳細は man firewalld.zones、リッチルールの構文は man firewalld.richlanguage です。すべてを暗記する必要はなく、必要になったときに調べられることが大切です。
次回の第21回「ボンディング/チーミング」は発展トピックです。複数の NIC を束ねて冗長化する技術を学びます。受講者のアサイン先によってはスキップ可能で、スキップしても第23回以降に支障はありません。
理解度チェック
以下の文が正しければ「○」、誤りなら「×」と答えてください。
Q1. firewalld のデフォルトゾーンは trusted であり、すべての通信が許可されている。
Q2. firewall-cmd --add-service=http を実行すると、ランタイムに即座に反映されるが、再起動後は元に戻る。
Q3. --permanent オプションを付けてルールを追加すると、ランタイムとパーマネントの両方に即座に反映される。
Q4. firewalld のサービス定義はXMLファイルで管理されており、/usr/lib/firewalld/services/ にデフォルト定義がある。
Q5. AlmaLinux 9 の firewalld は、バックエンドとして iptables を使用している。
Q6. リッチルールを使うと、送信元 IP アドレスを指定してサービスの許可・拒否を制御できる。
Q7. firewalld のゾーンは NIC 単位で割り当てることができ、NIC ごとに異なるルールを適用できる。
解答
Q1. × — デフォルトゾーンは public です。public ゾーンでは SSH・DHCPv6・cockpit のみが許可されています。
Q2. ○ — --permanent を付けない操作はランタイムのみに反映されます。firewalld の再起動やシステムの再起動で設定は消えます。
Q3. × — --permanent はパーマネント設定にのみ書き込みます。ランタイムに反映するには --reload が必要です。
Q4. ○ — デフォルトのサービス定義は /usr/lib/firewalld/services/ に XML 形式で格納されています。カスタム定義は /etc/firewalld/services/ に配置します。
Q5. × — AlmaLinux 9 の firewalld は nftables をバックエンドとして使用しています。iptables ではありません。
Q6. ○ — リッチルールでは source address= で送信元 IP を指定し、サービスやポートの許可・拒否を細かく制御できます。
Q7. ○ — --zone=ゾーン名 --change-interface=NIC名 で NIC ごとにゾーンを割り当てられます。外部向けと内部向けで異なるルールを適用する運用ができます。
シリーズ一覧
フェーズ1: エンジニアのいろは(第1回〜第3回)
フェーズ2: Linux基礎(第4回〜第15回)
- 第4回 Linuxとは何か+環境確認
- 第5回 SSH接続とターミナル操作
- 第6回 ファイルシステムとディレクトリ構造
- 第7回 基本コマンド(ファイル操作)
- 第8回 基本コマンド(テキスト処理・パイプとリダイレクト)
- 第9回 viエディタ
- 第10回 ユーザーとグループ管理
- 第11回 パーミッションと所有権
- 第12回 プロセス管理
- 第13回 systemd
- 第14回 シェルスクリプト入門
- 第15回 フェーズ2まとめ演習
フェーズ3: ネットワークとインフラ基盤(第16回〜第27回)
- 第16回 ネットワーク基礎
- 第17回 ネットワーク設定と疎通確認
- 第18回 企業ネットワークの仕組み
- 第19回 パッケージ管理
- 第20回 ファイアウォール(firewalld)(この記事)
- 第21回 ボンディング/チーミング
- 第22回 VLAN
- 第23回 ログ管理
- 第24回 cron / systemd timer
- 第25回 ストレージ管理(LVM)
- 第26回 シェルスクリプト実践
- 第27回 SSH応用
フェーズ4: サーバー構築と運用(第28回〜第36回)
