返回 登录
0

当一位现代应用开发者与旧式系统开发者走进一家酒吧...

摘要: 一位现代应用开发者与其前辈系统开发者走进一家酒吧,聊起了当前的互联网安全问题,由此探讨出设计一幅互联网地图,标出那些容易受病毒侵害的IP端口。从语言选择到存储主机和端口状态等,他们给出了不同的解决方案。

图片描述

题图来自pastemagazine

故事是这样发生的:

一位现代应用开发者以及他的前辈——一位传统的系统开发者走进一家酒吧,几杯酒下肚,他们聊起了当下的互联网安全问题。灵光一闪,两人觉得:如果能设计出一幅互联网地图,标出那些容易受病毒侵害的IP端口,意义将是非凡的。讨论了一番之后,他们决定:

  • 每月对所有IPv4地址(2^32=4,294,967,296)进行端口扫描。端口总共20个,包括一些像FTP(20,21)、telnet(23)、ssh(22)、SMTP(25)等不常见的端口。
  • 他们打算用nmap来扫描IP和端口。
  • 需要将端口状态设置为开启、关闭、过滤、未过滤、开启过滤和关闭过滤
  • 不论主机状态为“up”还是“down”,都要进行存储。主机状态为“up”须满足以下任意一个条件:

    1. 若主机上有开启的端口,主机状态则可能为“up”;
    2. 若主机以ping来回应,主机状态则可能为“up”。
  • 存储结果的目的是为了将过程写在报告中。

    1. 获得状态为“up”的主机数量;
    2. 判断某个主机处于“up”或“down”的状态;
    3. 判断在特定的/24子网络中,那些主机处于“up”状态;
    4. 获得所有端口开启的主机数量;
    5. 获得过去3个月状态为“up”的主机数量;
    6. 获得本月状态发生改变(由“up”转为“down”,或由“down”转为“up”)的主机数量;
    7. 获得上月状态为“down”,而现在状态为“up”的主机数量;
    8. 获得上月状态为“up”,而现在状态为“down”的主机数量。

现代应用开发者 vs. 旧式系统开发者

假设3亿IP处于开启状态,平均每个有3个开启的端口:

  • 你该如何构建?
  • 如何能更快完成这些任务?
  • 哪些途径更易扩展,例如添加更多端口?
  • 哪些途径耗费更多资源(CPU、内存、硬盘等)?

免责声明:我不太了解ElasticSearch(基于Lucene的搜索服务器),如有错误,还请指正。

语言选择

现代应用开发者:

选择Python,好上手,好维护,简单易懂。

系统开发者:

选择Go,快速高效,简单易懂,易于维护!

存储主机和端口状态

现代应用开发者:

JSON是不二选择!直接解读,无需解析(基于代码库构建),广受欢迎!

{
    "ip": "10.1.1.1",
    "state": "up",
    "ports": {
        "20": "closed",
        "21": "closed",
        "22": "open",
        "23": "closed",
        .
        .
        .
    }
}

400字节表示一个主机、up/down状态以及20个端口状态。

若是3亿IP,则需112GB的空间来存储所有主机和端口状态。

系统开发者:

使用一个位数组(内存映射文件)来存储主机状态,每个主机为1 bit。若bit为1,则为“up”状态;为0,“down”状态。

因为地址为2^32 IPv4,所以位数组为2^32 / 8=536,870,912或512MBs。无需分开存储IP地址,因为IPv4地址会转换成一个数字,可以充当位数组中的index。

然后使用第二个位数组(内存映射文件)来存储主机状态。6个端口状态,每个为3 bit;20个端口状态,总共60 bit。每个主机用一个uint64来表示端口状态。

所有4B IP大概需要32GB的空间来存储端口状态。存储所有主机和端口状态需要33GB的空间。

假设我们暂时不压缩,用EWAH bitmap compression也能节省一些空间。若采用EWAH 位图压缩,可能就无法获得符合条件的主机的数量了。

获得状态为“up”的主机数量

现代应用开发者:

如果是大数据的问题,推荐使用Hadoop进行映射/化简来处理共3亿主机的JSON结果(文件),然后就知道多少IP为开启状态。

如果是搜索的问题,推荐使用ElasticSearch。

我会在“状态”上用ElasticSearch将共3亿JSON文件编入索引,然后在其中搜索“状态(state)”为“up”的结果。

我意识到还有额外的存储需要用ES来编入索引。假设所需空间是普通文件1/8的大小,那么可能有另外14GB的索引数据,使得总大小变成126GB。

系统开发者:

这是bit counting或popcount()的问题,就是简单的加减法而已。循环访问uint64(~8.4M uint64)数组,清点每个主机有多少bit,然后加起来即可。

也可以创建多个goroutine(假设语言为Go),分步来做,跟映射/化简相似,计算起来更快。

判断某个主机处于“up”或“down”的状态

现代应用开发者:

用ElasticSearch搜索即可。

除了上文提到的“状态(state)”,这次我用ElasticSearch将“ip”编入索引。对于任何IP而言,都可以搜索满足条件的IP,从这个文件中,找到“状态(state)”的值。

系统开发者:

这很容易,只需将IPv4的整数值作为位数组的index,然后判断bit值是1还是0即可。

判断在特定的/24子网络中,哪些主机处于“up”状态

现代应用开发者:

这跟搜索单个IP有点儿像。搜索IP在子网络中(在ES中使用CIDR标记搜索)状态为“up”的文件。然后循环一系列搜索结果,找到主机IP。

Or

或者仅仅用映射/简化来处理3亿JSON文件,然后寻找/24子网络中状态为“up”的主机IP。

系统开发者:

这只是另外一个bit迭代的问题了。我打算用子网络的第一个IP地址来判断先选哪个位数组,然后清点子网络中的IP数量。然后循环访问位数组,若bit值为1,则将其index转换为IPv4地址,就知道多少主机状态为“up”了。

获得所有端口开启的主机数量

举个例子,报告可能仅仅如下所示:

20: 3,023
21: 3,023
22: 1,203,840
.
.
.

现代应用开发者:

这是大数据的问题了,我选择使用Hadoop进行映射/简化,返回的结果显示每个端口的主机数量。

用ElasticSearch也可以解决这个问题,ElasticSearch要求端口状态为index,这会增加index所占空间。然后清点搜索的端口22=“open”的结果,每个端口重复一遍即可。

系统开发者:

这就是数数而已。先过一遍主机状态位数组,针对状态为“up”的主机,用bit作为端口状态uint64数组的index,然后得到一个表示那个主机所有端口状态的uint 64。接下来在所有端口3 bit大小的bundle中寻找“up”状态的端口,就能知道符合条件的主机有多少个。

同样也可以用创建多个goroutine的方式来解决这个问题。

获得过去3个月状态为“up”的主机数量

现代应用开发者:

每个月都检索一遍状态为“up”的主机清单,然后把3个清单都过一遍,再缩减到一个清单,这需要一点处理和迭代的操作。

系统开发者:

我可以每3个月在位数组上进行一个简单的OR操作,然后查看有多值为1的bit。

获得本月状态发生改变(由“up”转为“down”,或由“down”转为“up”)的主机数量

现代应用开发者:

这个……还真没什么简单的方法。我直接循环访问上个月的主机,看看状态是否更改了。然后循环访问这个月没有查看过的主机,根据上个月的结果再过一遍清单。

系统开发者

可以在过去两个月的位数组上进行一个简单的XOR操作,然后清点显示在结果中的位数组值为1的bit。

获得上月状态为“down”,而现在状态为“up”的主机数量

现代应用开发者:

可以从上个月ES中检索状态为“up”的主机,然后再在其中寻找本月状态为“down”的主机,清点数量即可。

系统开发者:

操作如下:(this_month XOR last_month) AND last_month。如果主机状态符合条件,返回的位数组会有一个位组(bit set),然后清点显示在结果中的位数组值为1的bit。

获得上月状态为“up”,而现在状态为“down”的主机数量

现代应用开发者:

我可以从ES中检索状态上个月为“down”的主机,再在其中搜索当月状态为“up”的主机,然后清点数量。

系统开发者:

操作如下: (this_month XOR last_month) XOR this_month。如果主机符合条件的话,会返回一个有位组(bit set)的位数组,然后清点结果显示的位数组值为1的bit。

英文来源:A Modern App Developer and An Old-Timer System Developer Walk Into a Bar
作者:zhen
翻译:张新慧
审校/责任编辑:唐小引,欢迎技术投稿、约稿,给文章纠错,请致件tangxy@csdn.net

第一时间掌握最新移动开发相关信息和技术,请关注mobilehub公众微信号(ID: mobilehub)。

图片描述

2016年3月18日-19日,由CSDN重磅打造的数据库核心技术与实战应用峰会、互联网应用架构实战峰会将在上海举行。这两场峰会将邀请业内顶尖的架构师和技术专家,共同探讨高可用/高并发系统架构设计、新技术应用、移动应用架构、微服务、智能硬件架构、云数据库实战、新一代数据库平台、产品选型、性能调优、大数据应用实战等领域的热点话题与技术。

2月29日24点前仍处于最低六折优惠票价阶段,单场峰会(含餐)门票只需799元,5人以上团购或者购买两场峰会通票更有特惠,限量供应,预购从速。(票务详情链接)。

评论