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

NATとステートフル検査

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

説明

状態を追跡するファイアウォールは、戻りの通信を先行する接続と対応付けます。NATではアドレスやポートが変わるため、観測位置も一致させる必要があります。

同じTCP接続の内側・外側の固定記録をSQLで開きます。SYNとACK、NATの変換、状態を持たない別装置への戻りを順に確認します。

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

1観測位置を含めてパケットを並べる

insideは変換前、outsideは変換後の側です。

from sp03 import * from sp02 import show観測位置を含めてパケットを並べる db = connect() show(db,"SELECT * FROM packet ORDER BY id")

内側の192.0.2.7:53000が外側では203.0.113.9:61000へ変わります。宛先は198.51.100.20:443のままです。

2同じSYNの変換前後を抽出する

送信シーケンス番号100の2行を取得します。

show同じSYNの変換前後を抽出する(db,"SELECT point,src,sport,dst,dport,seq FROM packet WHERE flags='S' ORDER BY id")

送信元と送信元ポートが変わっています。異なる場所の5タプルをそのまま比較すると同じ接続を見失います。

3SYNに対するACKを確認する

戻りのSYN+ACKを取得します。

showSYNに対するACKを確認する(db,"SELECT point,dst,dport,seq,ack FROM packet WHERE flags='SA' ORDER BY id")

ackは101で、SYNの100から1進んでいます。SYNはシーケンス番号を一つ消費します。戻りの宛先もNATによって元の端末へ戻ります。

4送信側のACKで両方向を照合する

最後のACKを取得します。

show送信側のACKで両方向を照合する(db,"SELECT seq,ack FROM packet WHERE flags='A'")

seq 101、ack 501です。相手のSYNの500に対して1進んでいます。これらはTCPの確認でありHTTPやTLSの成功までは表していません。

5戻り通信に対応する状態を検索する

fw-aが保持する内側タプルを逆向きに照合します。

reply = ('192.0.2.7',53000,'198.51.100.20',443) show戻り通信に対応する状態を検索する(db,"SELECT device,expires FROM state WHERE src=? AND sport=? AND dst=? AND dport=?",reply)

fw-aに対応状態があります。expiresは今回の固定資料での有効期限60秒です。製品共通のタイムアウト値ではありません。

6別装置に戻った場合を調べる

状態を共有していないfw-bを検索します。

show別装置に戻った場合を調べる(db,"SELECT device FROM state WHERE device='fw-b' AND src=? AND sport=? AND dst=? AND dport=?",reply)

該当状態がありません。非対称経路では、往路を見た装置とは別の装置へ戻ることがあります。実際の処理はその装置の規則と状態同期に依存します。

7期限切れとアプリ識別の不足を確認する

時刻61秒で有効な状態を検索し、記録にあるフィールドを確認します。

show期限切れとアプリ識別の不足を確認する(db,"SELECT device FROM state WHERE expires>61") show(db,"SELECT name FROM pragma_table_info('packet')")

有効な状態はありません。また今回の記録にはペイロードやアプリ識別結果がありません。443番と接続状態だけから、アプリ名や内容を確定できません。

まとめ

NAT前後の観測位置をそろえて照合します。

戻りを受ける装置の状態と期限を確認します。

TCPの確立とアプリの成功は別の確認です。

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

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

1
from sp03 import * from sp02 import show db = connect() show(db,"SELECT * FROM packet ORDER BY id")
id | point | src | sport | dst | dport | flags | seq | ack
1 | inside | 192.0.2.7 | 53000 | 198.51.100.20 | 443 | S | 100 | 0
2 | outside | 203.0.113.9 | 61000 | 198.51.100.20 | 443 | S | 100 | 0
3 | outside | 198.51.100.20 | 443 | 203.0.113.9 | 61000 | SA | 500 | 101
4 | inside | 198.51.100.20 | 443 | 192.0.2.7 | 53000 | SA | 500 | 101
5 | inside | 192.0.2.7 | 53000 | 198.51.100.20 | 443 | A | 101 | 501
2
show(db,"SELECT point,src,sport,dst,dport,seq FROM packet WHERE flags='S' ORDER BY id")
point | src | sport | dst | dport | seq
inside | 192.0.2.7 | 53000 | 198.51.100.20 | 443 | 100
outside | 203.0.113.9 | 61000 | 198.51.100.20 | 443 | 100
3
show(db,"SELECT point,dst,dport,seq,ack FROM packet WHERE flags='SA' ORDER BY id")
point | dst | dport | seq | ack
outside | 203.0.113.9 | 61000 | 500 | 101
inside | 192.0.2.7 | 53000 | 500 | 101
4
show(db,"SELECT seq,ack FROM packet WHERE flags='A'")
seq | ack
101 | 501
5
reply = ('192.0.2.7',53000,'198.51.100.20',443) show(db,"SELECT device,expires FROM state WHERE src=? AND sport=? AND dst=? AND dport=?",reply)
device | expires
fw-a | 60
6
show(db,"SELECT device FROM state WHERE device='fw-b' AND src=? AND sport=? AND dst=? AND dport=?",reply)
device
7
show(db,"SELECT device FROM state WHERE expires>61") show(db,"SELECT name FROM pragma_table_info('packet')")
device
name
id
point
src
sport
dst
dport
flags
seq
ack

演習完了