はじめに
RHEL 環境で特定のホストとだけ通信を許可し、それ以外の同一サブネット上のホストとの通信を遮断したい場面があります。
本記事では firewalld のリッチルール(Inbound制御)とダイレクトルール(Outbound制御)を組み合わせて、ホスト単位でのフィルタリングを設定・検証した結果をまとめました。
動画
当記事の動画です。理解の一助にお役立てください。
検証環境
設定対象のサーバー(RHEL1)を中心に、通信を許可するサーバー(RHEL2)と、通信を拒否するサーバー(AIX1)を用意して検証します。
| ホスト名 | 役割 | IPアドレス |
|---|---|---|
| RHEL1 | 設定対象サーバー | 172.16.110.59 |
| RHEL2 | 通信許可ホスト | 172.16.110.241 |
| AIX1 | 通信拒否ホスト(確認用) | 172.16.110.142 |
方針:
- RHEL1 は RHEL2(172.16.110.241)とのみ通信を許可する
- 同じ 172.16.0.0/16 サブネット上のその他のホスト(AIX1 など)とは通信を遮断する
設定手順
設定対象サーバー(RHEL1 : 172.16.110.59)にて設定を行います。
① Inbound:特定ホストからの受信を許可(優先度 10)
リッチルールを使用し、特定のIP(RHEL2:172.16.110.241)からの受信を優先的に許可します。
# firewall-cmd --permanent --zone=public --add-rich-rule='rule priority="10" family="ipv4" source address="172.16.110.241" accept'
=> success と表示されればOK
② Inbound:サブネット全体からの受信を拒否(優先度 20)
172.16.0.0/16 全体からの受信を DROP します。
① のルール(優先度 10)が先に評価されるため、RHEL2 からの通信は許可されます。
# firewall-cmd --permanent --zone=public --add-rich-rule='rule priority="20" family="ipv4" source address="172.16.0.0/16" drop'
=> success と表示されればOK
③ Outbound:特定ホストへの送信を許可(優先度 0)
⚠️ 注意(RHEL 9 以降)
Outbound 制御で使用しているダイレクトルール(--direct)は、
RHEL 9 に同梱される firewalld 1.x 系において 非推奨(Deprecated) です。
現時点の RHEL 9 では引き続き動作しますが、将来のバージョンで削除される可能性があるため、新規構築の際はポリシーオブジェクト(Policy Objects) や nftables を利用した構成への移行を推奨します。
当記事ではダイレクトルールで設定しています。
RHEL2(172.16.110.241)への送信パケットを許可します。ダイレクトルールは数字が小さいほど優先されます。
# firewall-cmd --permanent --direct --add-rule ipv4 filter OUTPUT 0 -d 172.16.110.241 -j ACCEPT
=> success と表示されればOK
④ Outbound:サブネット全体への送信を拒否(優先度 1)
172.16.0.0/16 全体への送信を DROP します。③ のルール(優先度 0)が先に評価されるため、RHEL2 への送信は許可されます。
# firewall-cmd --permanent --direct --add-rule ipv4 filter OUTPUT 1 -d 172.16.0.0/16 -j DROP
=> success と表示されればOK
⑤ 設定を反映
# firewall-cmd --reload
=> success と表示されればOK
設定確認
Inbound ルール(リッチルール)の確認
# firewall-cmd --list-rich-rules
rule priority="10" family="ipv4" source address="172.16.110.241" accept
rule priority="20" family="ipv4" source address="172.16.0.0/16" drop
Outbound ルール(ダイレクトルール)の確認
# firewall-cmd --direct --get-all-rules
ipv4 filter OUTPUT 0 -d 172.16.110.241 -j ACCEPT
ipv4 filter OUTPUT 1 -d 172.16.0.0/16 -j DROP
動作検証
意図した通りにフィルタリングが機能しているか、双方向から ping を実行して確認します。
RHEL1 → RHEL2(許可ホスト)への ping ➔ 【成功】✅
# ping 172.16.110.241
PING 172.16.110.241 (172.16.110.241) 56(84) bytes of data.
64 バイト応答 送信元 172.16.110.241: icmp_seq=1 ttl=64 時間=0.187ミリ秒
--- 172.16.110.241 ping 統計 ---
送信パケット数 1, 受信パケット数 1, 0% packet loss, time 0ms
rtt min/avg/max/mdev = 0.187/0.187/0.187/0.000 ms
→ パケットロスなし。正常に通信できています。
RHEL1 → AIX1(非許可ホスト)への ping ➔ 【失敗】❌ (意図した挙動)
# ping 172.16.110.142
PING 172.16.110.142 (172.16.110.142) 56(84) bytes of data.
--- 172.16.110.142 ping 統計 ---
送信パケット数 3, 受信パケット数 0, 100% packet loss, time 2062ms
→ 100% パケットロス。Outbound DROP が機能しています。
RHEL2 → RHEL1(許可ホストからの受信)➔ 【成功】 ✅
# ip a
# ... (中略) ...
inet 172.16.110.241/16 brd 172.16.255.255 scope global noprefixroute env32
# ... (中略) ...
# ping 172.16.110.59
PING 172.16.110.59 (172.16.110.59) 56(84) bytes of data.
64 bytes from 172.16.110.59: icmp_seq=1 ttl=64 time=0.166 ms
64 bytes from 172.16.110.59: icmp_seq=2 ttl=64 time=0.163 ms
64 bytes from 172.16.110.59: icmp_seq=3 ttl=64 time=0.158 ms
^C
--- 172.16.110.59 ping statistics ---
3 packets transmitted, 3 received, 0% packet loss, time 2062ms
→ RHEL2 からの受信も正常。Inbound ACCEPT が機能しています。
AIX1 → RHEL1(非許可ホストからの受信) ➔ 【失敗】❌(意図した挙動)
# ifconfig -a
en0: flags=1e084863,814c0<UP,BROADCAST,NOTRAILERS,RUNNING,SIMPLEX,MULTICAST,GROUPRT,64BIT,CHECKSUM_OFFLOAD(ACTIVE),LARGESEND,CHAIN>
inet 172.16.110.142 netmask 0xffff0000 broadcast 172.16.255.255
# ... (中略) ...
# ping 172.16.110.59
PING 172.16.110.59 (172.16.110.59): 56 data bytes
^C
--- 172.16.110.59 ping statistics ---
2 packets transmitted, 0 packets received, 100% packet loss
→ 100% パケットロス。Inbound DROP が機能しています。
ルール優先度のまとめ
Inbound(リッチルール)
| 優先度 | 条件 | アクション |
|---|---|---|
| 10(先に評価) | 送信元 172.16.110.241 | ACCEPT |
| 20(後に評価) | 送信元 172.16.0.0/16 | DROP |
Outbound(ダイレクトルール)
| 優先度 | 条件 | アクション |
|---|---|---|
| 0(先に評価) | 宛先 172.16.110.241 | ACCEPT |
| 1(後に評価) | 宛先 172.16.0.0/16 | DROP |
まとめ
firewalld の リッチルール(Inbound制御) と ダイレクトルール(Outbound制御) を組み合わせることで、特定のIPアドレスとの送受信のみを許可し、同一サブネット内の他の端末からのアクセスを安全に遮断できることが確認できました。
優先度(Priority)の数値を適切に設定することで、より柔軟なアクセス制御が可能になります。
参考
ネットワーク・インターフェースへの制御は下記をご参考ください。
以上です。