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 / 規則評価と固定の通信記録
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
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
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
show(db,"SELECT seq,ack FROM packet WHERE flags='A'")seq | ack 101 | 501
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
show(db,"SELECT device FROM state WHERE device='fw-b' AND src=? AND sport=? AND dst=? AND dport=?",reply)device
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
演習完了