TLS検査と利用者別のアクセス制御
名前解決、プロキシ、復号、配送のどこで処理したかを記録から説明します。
説明
HTTPSの本文はTLSで暗号化されています。Web通信を復号して検査する構成では、端末側と接続先側を別のTLS接続として扱います。トンネルのまま中継する場合と、検査できる情報が異なります。
メモリー上のTLS接続でHTTPを暗号化し、暗号文と終端後の値を比較します。その後、固定の利用者別規則と復号除外を照合します。
名前解決、プロキシ、復号、配送のどこで処理したかを記録から説明します。
1TLSを確立して要求を送る
証明書の信頼とホスト名を検証する固定の試験接続です。
from sp05 import *
from sp02 import show
db = connect()
version,wire,plain = tls_exchangeTLSを確立して要求を送る()
print(version)
print(len(HTTP),len(wire))HTTPの長さよりTLSレコードは長くなります。レコードヘッダーや認証タグなどが加わるためです。
2暗号文の中にパスが見えるか調べる
/manualとHostの文字列を検索します。
print(b'/manual' in wire,b'Host:' in wire)
print(wire[:5]暗号文の中にパスが見えるか調べる.hex())どちらもFalseです。先頭5バイトはTLSレコードのヘッダーで、HTTPヘッダーではありません。
3TLSを終端した側の平文を開く
受信側のTLS処理から返った値です。
print(plain.decodeTLSを終端した側の平文を開く(),end='')
print(plain==HTTP)元のHTTPと一致します。パスやHTTPヘッダーの検査は、このように平文を得られる位置で行います。
4利用者と検査方法を含む規則を表示する
同じホストでもaliceとguestの処理が違います。
show利用者と検査方法を含む規則を表示する(db,"SELECT * FROM policy ORDER BY host,user")docsは復号対象ですが、guestはdenyです。復号できることと、その利用者に通信を許可することは別の条件です。
5利用者を指定して適用規則を取得する
guestのdocsへの接続を検索します。
show利用者を指定して適用規則を取得する(db,"SELECT inspection,action FROM policy WHERE user=? AND host=?",('guest','docs.example.test'))decrypt、denyです。IPだけに依存する規則では、共有端末やプロキシ越しの利用者を誤って結び付ける場合があります。
6復号除外の通信を抽出する
tunnelとして通す行を調べます。
show復号除外の通信を抽出する(db,"SELECT host,action FROM policy WHERE inspection='tunnel'")healthはトンネルでallowです。この経路でHTTP本文を検査したと報告するには、別の終端点など追加の根拠が必要です。
7平文を得る位置を図の形で確認する
検査時と除外時の接続を対応付けます。
print平文を得る位置を図の形で確認する('inspect: endpoint --TLS A--> gateway --TLS B--> origin')
print('bypass : endpoint -----------TLS-------------> origin')検査時はゲートウェイが両接続の間で平文を扱います。証明書の信頼、接続先の検証、平文へのアクセス管理もこの構成の確認対象です。
まとめ
TLSの暗号文と終端後のHTTPを分けて確認します。
利用者、宛先、復号設定をそろえて規則を調べます。
復号除外では検査できる内容も変わります。
操作履歴と解説を振り返れます。
Python 3.15 / TLS MemoryBIO / 固定の経路・配送記録
from sp05 import *
from sp02 import show
db = connect()
version,wire,plain = tls_exchange()
print(version)
print(len(HTTP),len(wire))TLSv1.3 49 71
print(b'/manual' in wire,b'Host:' in wire)
print(wire[:5].hex())False False 1703030042
print(plain.decode(),end='')
print(plain==HTTP)GET /manual HTTP/1.1 Host: docs.example.test True
show(db,"SELECT * FROM policy ORDER BY host,user")user | host | inspection | action alice | docs.example.test | decrypt | allow guest | docs.example.test | decrypt | deny alice | health.example.test | tunnel | allow
show(db,"SELECT inspection,action FROM policy WHERE user=? AND host=?",('guest','docs.example.test'))inspection | action decrypt | deny
show(db,"SELECT host,action FROM policy WHERE inspection='tunnel'")host | action health.example.test | allow
print('inspect: endpoint --TLS A--> gateway --TLS B--> origin')
print('bypass : endpoint -----------TLS-------------> origin')inspect: endpoint --TLS A--> gateway --TLS B--> origin bypass : endpoint -----------TLS-------------> origin
演習完了