一覧SP-03-1 · ファイアウォール:通信許可の判定

ファイアウォールのルール評価

規則の判定位置と往復の通信を照合し、許可・破棄の条件を説明します。

説明

ファイアウォールの規則では、送信元・宛先アドレス、ポート、プロトコルなどを照合します。複数規則に一致する通信では、評価順と処理を終える条件が結果を左右します。

先に一致したacceptまたはdropで終了する規則表をPythonで評価します。これは一つの規則列の評価であり、複数チェーンや後段装置の最終判断まで含むものではありません。

規則の判定位置と往復の通信を照合し、許可・破棄の条件を説明します。

1検査する5タプルを表示する

送信元ポート53000からHTTPSの443番へ向かうTCPです。

from sp03 import * print(PACKET検査する5タプルを表示する) print(RULES)

規則10は端末7から特定サーバーへの許可、規則20は同じ送信元ネットワークから443番への破棄です。

2各規則への一致を個別に調べる

この通信がどの規則に一致するかを確認します。

print([(r[0],matches各規則への一致を個別に調べる(PACKET,r)) for r in RULES])

両方Trueです。規則に一致したことだけでは、最終処理を一つに決められません。

3先に一致した規則で評価を終える

番号が小さい順に評価します。

print(trace先に一致した規則で評価を終える(PACKET,RULES))

規則10のacceptで終了し、20には進みません。この評価モデルでは許可です。

4広い破棄規則を前へ移す

規則20の優先番号を5へ変えます。

reordered広い破棄規則を前へ移す = [RULES[0],(5,*RULES[1][1:])] print(trace(PACKET,reordered))

規則5でdropになります。狭い例外許可が後ろにあっても到達できません。

5送信元を同じサブネットの別端末へ変える

192.0.2.8は規則10の/32には含まれません。

other = ('192.0.2.8',*PACKET[1:]) print(trace送信元を同じサブネットの別端末へ変える(other,RULES))

10は不一致、20は一致してdropです。/32は一つのIPv4アドレス、/24は256個のアドレス範囲を表します。

6TCPとUDPの条件を確認する

宛先443のままプロトコルだけをUDPへ変えます。

udp = (*PACKET[:4],'udp') print(traceTCPとUDPの条件を確認する(udp,RULES)) print(trace(udp,RULES,default='accept'))

どちらの規則にも一致しません。最後のdropまたはacceptは既定処理の違いです。443番だけではTCP、UDP、アプリの内容まで同一とは言えません。

7ログ取得だけでは評価を終えない理由を確認する

評価途中を全件記録した結果と、終端処理の実行経路を比較します。

all_matches = [(r[0],matches(PACKET,r)) for r in RULES] visited,verdict = traceログ取得だけでは評価を終えない理由を確認する(PACKET,RULES) print('matches',all_matches) print('visited',visited,'verdict',verdict)

全件照合では20もTrueですが、実行経路に20はありません。ログの一致件数と実際に通った規則を分けて調べます。

まとめ

5タプルとアドレス範囲を確認します。

最初の終端処理まで規則順を追います。

不一致の通信には既定処理が適用されます。

操作履歴と解説を振り返れます。

Python 3.15 / 規則評価と固定の通信記録

1
from sp03 import * print(PACKET) print(RULES)
('192.0.2.7', 53000, '198.51.100.20', 443, 'tcp')
[(10, '192.0.2.7/32', '198.51.100.20/32', 443, 'tcp', 'accept'), (20, '192.0.2.0/24', '0.0.0.0/0', 443, 'tcp', 'drop')]
2
print([(r[0],matches(PACKET,r)) for r in RULES])
[(10, True), (20, True)]
3
print(trace(PACKET,RULES))
([(10, True, 'accept')], 'accept')
4
reordered = [RULES[0],(5,*RULES[1][1:])] print(trace(PACKET,reordered))
([(5, True, 'drop')], 'drop')
5
other = ('192.0.2.8',*PACKET[1:]) print(trace(other,RULES))
([(10, False, '-'), (20, True, 'drop')], 'drop')
6
udp = (*PACKET[:4],'udp') print(trace(udp,RULES)) print(trace(udp,RULES,default='accept'))
([(10, False, '-'), (20, False, '-')], 'drop')
([(10, False, '-'), (20, False, '-')], 'accept')
7
all_matches = [(r[0],matches(PACKET,r)) for r in RULES] visited,verdict = trace(PACKET,RULES) print('matches',all_matches) print('visited',visited,'verdict',verdict)
matches [(10, True), (20, True)]
visited [(10, True, 'accept')] verdict accept

演習完了