RHEL系Linuxに備わっているfirewalld。非常に柔軟で(比較的)直感的に使える仕組みだったのでメモを残します。

特に驚きだったのがzoneの概念。

ufwが基本的に「システム全体に対してポートを開けるか閉じるか」をシンプルに管理するのに対し、firewalldは「接続するネットワークの信頼度に応じて、ファイアウォールのルールを瞬時に切り替える」という柔軟性がありました。

そもそもfirewalldにおけるゾーンとは?

一言で言うと、ゾーンとは「接続元のネットワークやインターフェース(LANカードなど)の『信頼度』に応じたグループ分け」のことです。

従来の iptables などでは、「このIPアドレスからのこのポートへの通信を許可する」といった細かいルールを1つずつ書く必要があります。

一方、firewalld では以下のようなステップで考えます。

  1. あらかじめ「拒否」「自宅用」「パブリック(公共)」といった、ルールの異なる箱(ゾーン)を用意しておく。
  2. ネットワークインターフェース(例: eth0)や、特定のIPアドレスをその箱に割り当てます。

これにより、「カフェのWi-Fiに繋いだ時は『パブリック』ゾーンに切り替える」「会社のLANに繋いだ時は『社内』ゾーンに切り替える」といった管理が、一瞬でできるようになります。

代表的なプリセットゾーン

firewalld には、最初からいくつかのゾーンが用意されています。

ゾーン名信頼度主な用途・特徴
drop最低すべての受信パッケージを破棄します(応答すら返さない)。こちらからの送信は可能です。
blockすべての受信を拒否します。drop と違い、相手に「拒否しました」という通知(ICMP)を返します。
public低〜中デフォルトのゾーン。 不特定多数がいる公共のネットワーク用。自分が許可した通信(sshなど)だけを通します。
externalルーターとして使う場合の「外側(インターネット側)」用。マスカレード(NAT)が有効になります。
**home / internal**自宅や社内LANなど、周囲のコンピューターを信頼できる場合用。お互いの通信が少し緩く許可されています。
trusted最高すべてを許可します。完全に安全だと分かっているネットワーク専用です。

ゾーンの3つの重要なルール

インターフェースは必ずどこかのゾーンに属する

ネットワークカード(eth0wlan0 など)は、必ずいずれか1つのゾーンに紐付けられます。何も設定していない場合、自動的に public(デフォルトゾーン)に属します。

IPアドレス単位での割り当ても可能

「インターフェース全体は public だけど、上司のPCのIPアドレス(192.168.1.50)だけは trusted ゾーンとして扱う」といった柔軟な設定が可能です。

ルールはゾーンごとに設定する

Webサーバー(80番ポート)を開放したい」となったら、「public ゾーンに対して80番ポートを許可する」というように、ゾーンに対して設定を紐付けます。

もっと有り体に言うと

『ジョジョの奇妙な冒険』第5部における『マン・イン・ザ・ミラー』です。

ここには『スタンド力』は おれの許可なくしては入る事はできない
『おまえ本体』だけ入る事を許可した
ここにある物は全て命のない『物質』だけだ―――おまえとオレだけ!他に『生きてる物』はいない………

という「許可」と「許可しない」を、鏡の世界ではなく「ゾーン」ごとに決められる能力、と言っていいでしょう。

よく使う基本コマンド

ゾーンの状態を確認・操作するための、代表的な firewall-cmd コマンドです。

現在のデフォルトゾーンを確認する

firewall-cmd --get-default-zone

すべてのゾーンの設定を確認する

firewall-cmd --list-all-zones

特定のインターフェース(例: eth0)のゾーンを変更する

firewall-cmd --zone=home --change-interface=eth0

特定のゾーン(例: public)にサービス(例: http)を許可する

 firewall-cmd --zone=public --add-service=http --permanent

`

  • --permanent をつけた後は、設定を反映させるために以下が必要です
firewall-cmd --reload

Linuxサーバーを構築する際は、まず「このサーバーはどこに置かれていて、どのゾーンを適用すべきか」を考えていきましょう。

そのケーススタディを行っていきます。

ケーススタディ

各部署が持っているサーバを管理するためシステム部が一括でzabbixのエージェントを入れたいという状況。

  • システム部だけにzabbixサーバへのssh接続(ターミナル操作)と管理画面(Web管理画面)の閲覧と操作を許可
  • それ以外の部署が所属するNWには上記2つを拒否。
  • zabbixサーバそのものを司る大本のzabbixサーバはエージェントの通信を許可。
  • ただし、zabbixのエージェントは通るようにします。

Step 1: システム部専用ゾーンの作成と「IP」の紐付け

まずは 192.168.1.0/24 だけが所属する専用のゾーン illuso を作ります。

  • ゾーンの新規作成
sudo firewall-cmd --permanent --new-zone=illuso
  • 一度リロードして、OSに新しいゾーンを認識させる(重要)
sudo firewall-cmd --reload

作成したゾーンに「部内NWのIPセグメント」を紐付ける

sudo firewall-cmd --permanent --zone=illuso --add-source=192.168.1.0/24

Step 2: システム部専用ゾーンに「許可サービス」を追加

Step 1 で作ったゾーンに、ssh, http, https の鍵(許可)を配置します。

  • システム部専用ゾーンに対して SSH を許可
sudo firewall-cmd --permanent --zone=illuso --add-service=ssh
  • システム部専用ゾーンに対して HTTP を許可
sudo firewall-cmd --permanent --zone=illuso --add-service=http
  • システム部専用ゾーンに対して HTTPS を許可
sudo firewall-cmd --permanent --zone=illuso --add-service=https

Step 3: 上位監視サーバー専用のゾーン作成と設定

社内のZabbixサーバー(192.168.12.6)だけが所属する man-in-the-mirror を作り、Zabbix Agent用の 10050 ポートを許可します。

  • 上位サーバー用のゾーンを新規作成
sudo firewall-cmd --permanent --new-zone=man-in-the-mirror
  • 再度リロードして、新しいゾーンを認識させる
sudo firewall-cmd --reload
  • そのゾーンに「上位ZabbixのIP」を紐付ける
sudo firewall-cmd --permanent --zone=man-in-the-mirror --add-source=192.168.12.6
  • そのゾーンに 10050 ポート(tcp)の許可を与える
sudo firewall-cmd --permanent --zone=man-in-the-mirror --add-port=10050/tcp

Step 4: 全員に開くポートの追加 と public の掃除

誰からでも受け付ける Zabbix Server(10051)や SMTP(25)を public に設定し、同時に、先ほど部内限定へお引越しさせた不要なサービス(ssh, http, https)を public から削除します。

  • 自身の Zabbix Server ポート(10051)を全員に開放
sudo firewall-cmd --permanent --zone=public --add-port=10051/tcp
  • SMTP(25)を全員に開放
sudo firewall-cmd --permanent --zone=public --add-service=smtp
  • 【とても重要】どこからでも SSH できる状態を public から削除
sudo firewall-cmd --permanent --zone=public --remove-service=ssh
  • どこからでも HTTP できる状態を public から削除
sudo firewall-cmd --permanent --zone=public --remove-service=http
  • HTTPS も public から削除
sudo firewall-cmd --permanent --zone=public --remove-service=https

Step 5: 設定の最終反映と確認

ここまでの --permanent(次回起動用の設定)を、一気に本番環境へ反映(リロード)させます。

  • すべての設定を反映させます。
sudo firewall-cmd --reload

反映が完了したら、正しく設定できているか各ゾーンを覗いてみましょう。

  • 部内限定ゾーンの確認(sourcesにIP、servicesにssh http httpsがあること)
sudo firewall-cmd --zone=illuso --list-all
  • 上位Zabbix用ゾーンの確認(sourceにIP、portsに10050/tcpがあること)
sudo firewall-cmd --zone=man-in-the-mirror --list-all
  • 共通ゾーンの確認(servicesからssh, http, httpsが消え、zabbix-serverやsmtp、portsに10051/tcpがあること)
sudo firewall-cmd --zone=public --list-all

まとめ

以上、手順は多いものの

  • こいつは許可
  • こいつは拒否

を極めて柔軟に行えるのはRHEL系Linuxの持つ特権だと思いました。とはいえ、

この条件は「これから入ろうとする邪魔者」を拒否するには有効ですが、入ってしまったものを取り除くのは極めて厄介です。とくにウィルス(マルウェア)の除去は

『マン・イン・ザ・ミラー』オレだけが外に出る事を許可しろォォォォーーーーッ
うおおおががががが だが! ウイルスは許可しないィィィィィーーーッ
感染した部分は出る事は 許可しないィィィィィィィーーーッ!!

とはならないので注意が必要です。

(最後のこれが言いたいだけのエントリーを書き終えました)