|通用信息安全| 2022年6月16日

在Python3中使用MTBL有效地访问中等大小的排序和唯一键的CSV文件

简介

想象一下,对于Internet上的每个可注册域名,您都有4或5个数据点,并以域名为键。这样的文件长度将超过3.8亿行,大小可能为10GB,结构为一个简单的排序逗号分隔变量(CSV)文件。

您希望能够在Python3中的Mac笔记本电脑上通过键(例如,域名)访问该文件中的条目,返回相关的数据点,就像您可能使用Python3字典访问更小的数据结构一样。

事实证明,MTBL文件在这方面非常有用。本文将解释如何做到这一点。

安装pymtbl

MTBL文件是不可变排序字符串表(SST)文件的实现远见安全公司(现在是DomainTools的一部分)

如果您尚未安装MTBL软件包,请参阅“被动DNS和SIE文件格式“请你帮忙。

虽然MTBL文件可以使用“C”语言界面直接读写,但许多数据分析师更喜欢Python3。幸运的是,有一个到MTBL文件的Python3接口

安装pymtbl需要cython。如果您还没有安装cython,可以使用酿造

安装libmtbl和cython后,我们应该(终于!)能够成功安装pymtbl:

Git克隆https://github.com/farsightsec/pymtbl.gitcd pymtblSudo /usr/local/bin/python3 setup.py install

读取排序的CSV并将其转换为MTBL文件

假设我们的CSV文件存在,已排序,并且有唯一的键。例如,它的一部分看起来是这样的:

0——0.de,1,,,,0 0——0.dev,1,3,4,2,10 0——0。欧盟、1…0 0 - 0。其中,1,,,,18 0—0.jp,1,,,,32 0—0.link,1,,,,15

我们将用以下代码将该文件转换为MTBL:

猫sample_write_mtbl.py# !/usr/local/bin/python3 """ "写入mtbl样本文件""" " ###执行:### ./sample_write_mtbl.py < small-sample.csv import os import sys import mtbl mtbl_output_file='sample. txt 'Mtbl ' try: os.remove(mtbl_output_file) except: pass w = Mtbl .remove(mtbl_output_file)sys. writer(mtbl_output_file, compression=mtbl.COMPRESSION_ZLIB)Stdin: #分割输入为字段x = line.rstrip().split(',') #我们的第一个字段将是键key=x[0] #我们将使用其余五个字段作为逗号分隔变量val= str(x[1:5])。\取代(“]”、“”).replace(“”、“”)。\取代(“”、“”)。replace(" ","") #这是所有我们需要写MTBL w[key]=val

关于该代码需要注意的一些事情:

  • 我们正在从sys.stdin读取数据 ,但总是写到sample.mtbl。作为这样做的一部分,我们将删除所有现有的样本。mtbl文件
  • 我们假设键是域名,在第一列中,文件是按字母顺序排序的
  • 我们将值作为单个字符串写入MTBL文件。因为我们预计要写入数以亿计的记录,所以我们尽量减少格式的数量,去掉括号和其他格式,只保留用逗号分隔的变量
  • 如果您喜欢编写单独的整数值,请参见https://github.com/farsightsec/pymtbl如果你想在mtbl中存储整数,请使用varint_encode()和varint_decode()或struct。包装和结构。打开行李,这样做”
  • 我们使用zlib进行MTBL压缩。还有其他选项可用,但我们发现zlib提供了一些效率合理/开销可接受的最佳压缩

运行该命令后,我们现在有了一个MTBL文件。但是怎么读呢?

阅读我们的样本MTBL文件

阅读我们的样本MTBL文件非常简单:

猫sample_read_mtbl.py# !/usr/local/bin/python3 """读取mtbl样本文件""" import mtbl ###运行:### ./sample_read_mtbl.py def clean_up(list1):返回str(list1)。\取代('(',”).replace(‘)’,”)。\取代(“的”、“).replace(‘”’,”)。Replace (" ","") r = mtbl.reader('sample. reader ')mtbl', verify_checksum =True) key="0- 0.de" print("Sample read for key="+key) # key可能不存在;如果是这样,返回空数据try: results = clean_up(r[key]) except: results = ",,,,," result_list = results.split(",") print(results)

示例运行:

。/ sample_read_mtbl.py示例读取键=0- 0.de 1,,,,0

上面的代码需要注意:

  • 我们验证校验和;你可以选择放弃这样做。
  • 我们只是从示例文件中提取一个硬编码的值作为示例。您可能会循环遍历一个输入文件,根据这些文件检索一组结果。
  • 我们正在做最小限度的错误处理/清理,仅仅处理请求一个不存在的键的情况。我们没有采取任何步骤来确保键都规范化为小写,只是举一个我们可能需要采取的额外步骤的例子。

这在规模上有效吗?

请记住,我们一开始的前提是要为数亿条记录构建一个样本MTBL文件,而不仅仅是一个小小的玩具样例文件。

我们要尝试加载的文件大约是10GB:

Ls -lh all.data.csv[…10459732114[…]] all.data.csv $Wc -l all.data.csv393111057 all.data.csv

在一台笔记本电脑上加载这个文件并不需要很长时间:

Time ./mtbl_writer.py < all.data.csvReal 16m19.975s user 15m59.968s sys 0m15.097s

生成的文件比原来的文件要小很多(~):

Ls -l all_data.mtbl[…3477694979[…]all_data。mtbl美元mtbl_info all_data.mtbl文件名称:all_data。mtbl文件size: 3,477,694,979 index block offset: 3,464,697,985 index bytes: 12,996,482 (0.37%) data block bytes 3,464,697,985 (99.63%) data block size: 8,192 data block count 908,845 entry count: 393,111,057 key bytes: 6,245,970,880 value bytes: 3,427,539,120 compression algorithm: zlib compactness: 35.95%

吞吐量怎么样?我们测试了2539,048个样本查询——这些查询在88.57秒内运行,转换成每秒2539,048 /88.57=28,667个查询,没有进行任何优化。

更新MTBL文件?

关于MTBL文件有一点要记住:它们是不可变的。一旦创建了一个文件,就不能“更新”它,除非编写一个新文件(可能作为MTBL合并过程的一部分)。

在许多情况下,如果您有新数据(可能来自每日更新周期),最简单的解决方案将是简单地创建一个全新的MTBL文件来替换旧的文件。

启用查询访问,降低详尽数据转储的风险

虽然MTBL文件是二进制格式,用户通常通过查询特定的密钥来访问MTBL文件,但您应该知道MTBL文件可以使用mtbl_dump命令转储为文本格式:

mtbl_dump all_data.mtbl

为了减少详尽数据转储带来的隐私风险,您可以采用的一种方法是在写入MTBL文件之前对键进行哈希,并根据该哈希键对MTBL文件进行查询。

然而,哈希键会有一定的代价,因为:

  • 在创建MTBL文件之前和对经过散列处理的MTBL文件进行任何后续查询时,都需要计算所有的散列。
  • 散列键值可能比原始键值更长,从而增加MTBL的总体大小。
  • 散列后的原始数据将需要重新排序(因此散列后的键将按适当的升序排列)。
  • 散列数据的压缩效果可能不如原始数据。

  • 坚定的一方仍然可以使用探测来提取至少一部分数据。

有关Python3中一些哈希选项的讨论,请参见https://docs.python.org/3/library/hashlib.html

结论

现在您已经了解了如何使用MTBL文件有效地为中等大小的CSV文件提供(只读)类似Python3字典的接口,甚至在典型的笔记本电脑硬件上也是如此。类中使用pymtbl的其他示例,供感兴趣的读者参考Github库

确认

我们要谢谢你肖恩McNee这个博客的创意斯蒂芬·瓦特而且开尔文Dealca感谢他们非常有帮助的意见。任何剩余的问题,完全是作者的责任。

加入超过30,000名安全专业人员

订阅DomainTools每月通讯,接收创新,实用的建议,以改善他们的安全态势。我们的目标是帮助组织在其组织的日常防御中变得更高效、更有知识和更积极主动。

视图DomainTools”隐私政策