ScapyでDNSフィルタリング
Scapyでネットワークブリッジを構築し、ブリッジ内でDNSフィルタリングを実施してみた。
ネットワーク
ubuntu上にScapyによるネットワークブリッジを設け、そこでDNSフィルタリングを行う。ClientからはRouterをとおしてインターネットへアクセスする。(なお、ClientはRouter上で動作しているDHCPサーバーからIPアドレスを取得する。)
DNSフィルタリング
フィルタリングとして、特定ドメインをブロックするもの。いわゆるブラックリストを作成し、Webアクセスなどが行えないよう制御する。
ソースコード
ブラックリスト
”blacklist.txt”というファイルにアクセスを許可しないドメインを記載する。なお、”.”(ピリオド)ではじまる場合、ワイルドカード的に扱うこととした。
blacklist.txt
yahoo.com
.zm
www.bbc.co.uk
上記の2行目では、”www.abc.zm”や”xdu.zm”もマッチ(適用)するものとする。”.”(ピリオド)ではじまらない場合は、完全一致した場合のみ適用する。
コード本体
dns_filter.py
from scapy.all import *
import datetime
blk_list = []
def cb_filter(p):
found = 0
if p.haslayer(DNS):
dns = p.getlayer(DNS)
qname = dns.qd.qname
#print(qname.decode('utf-8'))
chk_domain = qname.decode('utf-8').rstrip('.')
for blk_domain in blk_list:
if blk_domain.startswith('.'):
if chk_domain.endswith(blk_domain):
found = 1
break
else:
if chk_domain == blk_domain:
found = 1
break
if found == 1:
now = datetime.datetime.now()
d = now.strftime('%Y/%m/%d-%H:%M:%S')
msg = d + ' ' + chk_domain + ' is dropped.'
print(msg)
msg += '\n'
flog.write(msg)
return False
else:
return True
with open('blacklist.txt') as f:
for line in f:
blk_list.append(line.rstrip())
flog = open('dns.log', 'a')
bridge_and_sniff('enp3s0', 'enp1s0f0', xfrm12=cb_filter, xfrm21=cb_filter)
#do not call flog.close()
- blk_list: ブロックするドメインのリスト
- cb_filter: ブリッジ時にCallされる関数
- DNSパケットのみを対象
- ブリッジを通過するDNSのドメイン名を取得(最後のピリオド”.”削除)
- ブロックするドメイン名がピリオド”.”で始まっている場合、取得したドメイン名が後方一致するかチェック
- ピリオド”.”で始まっていない場合、取得したドメイン名が完全一致するかチェック
- 一致した場合、コンソール表示およびログへの書き込み
- 一致した場合、Trueを返す(転送する)
- 一致しない場合、Falseを返す(転送しない)
- ブラックリストファイル(blacklist.txt)に格納されているドメイン名をblk_listに格納
- ログファイル(dns.log)をオープン
- bridge_and_sniff(): 2つのネットワークI/F("enp3s0","enp1s0f0")のブリッジ化およびブリッジ時にCallされる関数(cb_filter)の定義
検証
ほぼ自明なので、クライアントの状況は省略。上記コードで記載したログファイル(一部)は下記のとおりとなる。
access.log
2023/12/31-14:37:05 www.bbc.co.uk is dropped.
2023/12/31-14:37:05 www.bbc.co.uk is dropped.
2023/12/31-14:37:14 www.cabinet.gov.zm is dropped.
2023/12/31-14:37:14 www.cabinet.gov.zm is dropped.
終わりに
パフォーマンス的には今ひとつかもしれない。とにかく、Scapyは便利である。関連して、「ろうとるがPythonを扱う、、(その20:Scapyで改ざん)」でも一部実施したが、本格的なSpoofingもできそう(気が向いたらトライしてみる)。