はじめに
これまでの実験では、すべてのユーザーに対して「ドア」(ポート)を開いたり閉じたりしました。しかし、ドアを 友人だけ に開けたり、問題を起こしている相手に対してだけ閉じたりしたい場合はどうでしょうか。
ここで rich rule が役立ちます。サービスを大まかに開閉するだけでなく、送信元アドレスの一致、ログ記録、特定の通信の拒否など、より細かなポリシーを指定できます。
実際のファイアウォールポリシーでは、条件に応じて処理を変えることが多いため、rich rule は重要です。セキュリティ上の判断が、単純な「ポートが開いている」または「ポートが閉じている」だけになることはほとんどありません。
実験環境に関する注意: Web ターミナルから誤って締め出されないように、この実験ではデフォルトで trusted ゾーンを使用します。つまり、明示的にブロックしない限り、すべての通信が許可されます。実際の本番環境では、public や drop のような、より制限の厳しいゾーンを使用します。
この実験では、次の操作を学びます。
- 特定の相手をブロックする: 特定の IP アドレスからの接続を拒否します。
- 記録を残す: 接続を試みた相手を確認できるよう、試行をログに記録します。
- アクセスを制限する: リモート操作(SSH)を特定のネットワークからだけ許可するルールを設定します。
- 監査する: 確認用にルールをファイルへ保存します。
特定の IP をブロックする
このステップでは、まず特定の悪意ある相手をブロックする方法を学びます。192.168.1.100 のコンピューターがあなたに対して攻撃を試みているとします。この IP を完全にブロックします。
この操作には「Rich Rule」を使用します。デフォルトゾーンは trusted(すべての通信を許可)ですが、この IP に対する Reject ルールが優先されます。
rich rule が重要なのは、実際のファイアウォールポリシーでは条件に応じて異なる処理が必要になることが多いためです。送信元アドレス、サービス、ログ記録の要否など、単純な開閉コマンドでは十分に表現できない条件に応じて、異なる動作を指定できます。
構文は文章を組み立てるように記述します。rule family="ipv4" source address="192.168.1.100" reject
次のコマンドを実行して、このルールを永続的に追加します。
sudo firewall-cmd --permanent --add-rich-rule='rule family="ipv4" source address="192.168.1.100" reject'
この「文章」の各部分を確認しましょう。
rule family="ipv4": 標準的な IP アドレスを対象にします。source address="...": ブロック対象の相手のアドレスを指定します。reject: 実行するアクションです。
Reject と Drop の違い:
- Reject は丁寧な拒否です。送信元に「許可されていないため接続できない」と通知します。
- Drop は完全に無視します。コンピューターが存在しないかのように、送信元へ何も返しません。
どちらを選ぶかは単なる表現上の違いではありません。reject は正当なクライアントにすばやく結果を返し、トラブルシューティングを容易にします。一方、drop は攻撃者に与える情報を減らせますが、タイムアウトまでの時間が長くなる可能性があります。
--permanent を使用したため、ルールは保存されましたが、まだ有効ではありません。ファイアウォールをリロードして適用します。
sudo firewall-cmd --reload
次に、ルールが存在することを確認します。
sudo firewall-cmd --list-rich-rules
追加した新しいルールが一覧に表示されます。
拒否パケットをログに記録する
このステップでは、相手をブロックするだけでなく、証拠も残したい場合を考えます。ルールに「ログ記録」を追加すると、ルールが実行されるたびに記録する防犯カメラのような動作を設定できます。
フィルタリングとログ記録の組み合わせは、セキュリティ運用でよく使われます。通信のブロックによってシステムを保護し、ログによって後から調査できる証拠を残します。
今回は別の IP、10.0.0.5 をブロックします。ただし、拒否する前にその試行を ログに記録 します。
次のコマンドを実行します。
sudo firewall-cmd --permanent --add-rich-rule='rule family="ipv4" source address="10.0.0.5" log prefix="BLOCKED_IP: " level="info" reject'
ここで追加された内容を確認しましょう。
log: ログ記録を有効にします。prefix="BLOCKED_IP: ": システムログへ書き込む行の先頭に、この文字列を付けます。これにより、後で検索ツールを使って該当するイベントを簡単に見つけられます。
変更を適用します。
sudo firewall-cmd --reload
設定結果を確認します。
sudo firewall-cmd --list-rich-rules
最初のルール(単純な拒否)と、2 番目のルール(ログ記録してから拒否)の 2 つが表示されます。
サービスへのアクセスを制限する
このステップでは、セキュリティを強化した環境を想定し、SSH をすべての送信元に対してブロックして、信頼できるネットワーク(VPN など)からだけ許可する方法を学びます。
学習上の注意: この実験では接続を維持するために trusted ゾーンを使用しているため、このステップは一部が説明目的の操作です。すでにすべての通信が許可されている状態で「Allow」ルールを追加しても、動作は変わりません。ただし、public や drop のような制限の厳しいゾーンを使用するときには、この構文を理解していることが重要です。
ここでは、「送信元が 192.168.0.0/24 の場合に だけ SSH を許可する」というルールを作成します。
これは、ネットワークポリシーにおける最小権限のよい例です。管理アクセスをインターネット全体に公開するのではなく、サーバーを正当に管理するネットワークに限定します。
まず、SSH の一般的なサービス設定を削除します。
sudo firewall-cmd --permanent --remove-service=ssh
注意: Warning: NOT_ENABLED: ssh のような警告が表示される場合があります。これは 正常であり、想定された結果 です。デフォルトゾーンの trusted はすべての通信を許可しますが、個別のサービスは有効化されていません。そのため、明示的に一覧へ登録されていないサービスを削除しようとすると、この無害な警告が表示されます。
次に、サブネットに対する Rich Rule を追加します。
sudo firewall-cmd --permanent --add-rich-rule='rule family="ipv4" source address="192.168.0.0/24" service name="ssh" accept'
リロードして変更を有効にします。
sudo firewall-cmd --reload
設定を確認します。まず、サービス一覧を確認します。
sudo firewall-cmd --list-services
ここには ssh が表示されないはずです(一般的なサービス一覧から削除したためです)。
次に、Rich Rules を確認します。
sudo firewall-cmd --list-rich-rules
指定した送信元からの service name="ssh" を許可するルールが表示されます。
ルールを監査する
本番環境では、セッションを終了する前にファイアウォールルールを最終確認し、バックアップしておくことが推奨されます。これにより、ルールが正しい順序で適用されていることを確認でき、復旧用のファイルも用意できます。
このステップでは、Rich Rules を監査用のテキストファイルへエクスポートします。
まず、すべての Rich Rules を一覧表示し、出力をプロジェクトフォルダーの rules_list.txt というファイルへリダイレクトします。
sudo firewall-cmd --list-rich-rules > ~/project/rules_list.txt
次に、ファイルを読み取り、内容が正しいことを確認します。
cat ~/project/rules_list.txt
この実験で作成したルールの一覧が表示されます。このファイルは、rich rule 設定の簡単なバックアップとして利用できます。
まとめ
この実験では、Rich Rules を使ってファイアウォールのスキルを高めました。次の操作を学びました。
- 特定の IP をブロックする(「Reject」ルール)。
- セキュリティイベントをログに記録する(「カメラ」ルール)。
- SSH などの機密性の高いサービスを、信頼できるネットワークだけに制限する。
- ルールをファイルへエクスポートして設定を監査する。
これらの高度な手法により、複雑な環境を保護するために必要な精密な制御が可能になります。



