记一次报案的经历

2014-12-24 • 个人情感

上个月,大约就是去大众点评网参加最后一次技术面试的那一天,我遇到了电话诈骗。对方冒充熟人要我给他汇几千块钱,我以本人账户暂时没有足够余额需要家人跨行汇款给我为由拖住对方,然后去派出所报案了。

到了派出所,我跟窗口的警察说,我拖住了对方,希望能尽快调查好抓住诈骗分子。窗口的警察一脸不屑,反问道,你能把他引到我们派出所来呀。听到这里,我觉得这次报案已经没有什么意义了,警方应该不会立即着手调查,于是对此类案件至关重要的时效性怕是要白白浪费了。虽然,事后有警官找我确认信息,确认立案,但是我已经没什么感觉了,也不觉得会得到侦破。

为什么说这类案件的时效性非常重要呢?首先,犯罪嫌疑人一般不会傻到用自己的身份证去银行开立账户,否则要想查到他太容易了,犯罪嫌疑人一旦得手后会转移资金以防账户被冻结。第二,犯罪嫌疑人使用的手机卡可能是无法确认其真实身份的,否则也太危险了。那么,案件发生后,非常重要的一点就是快速查到犯罪嫌疑人转移资金的途径,转账不太可能,因为太危险,直接取出可能性更大,如果是直接取出那么如果可以看到监控录像是最好了,但犯罪分子通常会专门遮掩自己的面相。另外就是,通信可以使用技术侦查手段,既然拖住了对方,那么未来通信过程中能够对其做跟踪定位对于抓获嫌疑人是极为有利的。

在这次报案经历中,眼看着有利于破案的因素毁在了警方手里。我不清楚是因为繁冗的报案流程需要还是相关人员怠慢了,总之侦破几无望。若为前者,希望以后特事特办,要求时效性的案件要及时进行侦查;若为后者,那么更加令人失望,这也是在本文中没能不吝使用“民警”一词的原因,希望社会主义中国的警察不仅仅是那么一份职业。

Smurf攻击和DNS反射放大攻击

2014-12-10 • 技术文章

最近几天在新闻中频繁提到DNS反射攻击,之前在微博上也经常说起,本文来简单记叙其原理并顺便介绍比较老的Smurf攻击。

Smurf攻击

Smurf攻击是一种比较老的放大攻击方式了。其原理是向网络广播地址发送ICMP请求(如ping),路由将请求转发给该网段下的所有机器。这个ICMP请求的源地址伪造为攻击目标,如果收到请求的机器都响应这个请求,大量的数据就会流向伪造的目标地址,此之谓“放大”。

一台机器发出这样的请求作为DDoS攻击显然压力不足,所以假如有大量的“肉鸡”或者说是僵尸网络服务器可以一起上,每个机器打满网卡速率放出请求,然后再进行一次放大,效果就完全不一样了。不过,现在一般都把路由配置为不转发这种ICMP给网段内的机器,所以这种攻击目前比较少了。

DNS反射放大攻击

DNS反射放大攻击的原理也是类似的。网络上有大量的开放DNS解析服务器,它们会响应来自任何地址的解析请求。我们发出的解析请求长度是很小的,但是收到的结果却是非常大的,尤其是查询某一域名所有类型的DNS记录时,返回的数据量就更大,于是可以利用这些解析服务器来攻击某个目标地址的服务器,而且是利用被控制的机器发起伪造的解析请求,然后解析结果返回给被攻击目标。由于DNS解析一般是UDP请求,不需要握手,源地址属性易于伪造,而且部分“肉鸡”在平时本来就是合法的IP地址,我们很难验证请求的真实性和合法性。DNSSEC是一种可以防止缓存投毒的机制,另外,如果DNS本身抗压能力不行,而且对方请求量过大的话,也会影响到DNS本身的服务。目前此类攻击的规模在数百Gbps级别。

其它形式的放大攻击

NTP:使用MONLIST命令可以获取与目标NTP Server进行过同步的最后600个客户机IP。这意味着,一个很小的请求包,就能获取到大量的活动IP地址组成的连续UDP包。

SNMP:发送GetBulk请求来枚举MIB。

CHARGEN:用于调试和测量的工具协议。无视输入,返回任意字符。UDP协议下收到一个封包就会回一个封包回去;TCP下不断发包给客户端。

总之,放大攻击一般都有以下特点:可以轻易地伪造源地址,响应的数据量大于请求数据量好多倍。

参考资料与扩展阅读

http://blog.cloudflare.com/deep-inside-a-dns-amplification-ddos-attack/

http://blog.cloudflare.com/technical-details-behind-a-400gbps-ntp-amplification-ddos-attack/

https://www.us-cert.gov/ncas/alerts/TA13-088A

http://blog.sina.com.cn/s/blog_459861630101b4wf.html

http://drops.wooyun.org/tips/2106

PDF: An Analysis of DrDoS SNMP/NTP/CHARGEN Reflection Attacks

分组计算的SQL设计探讨

2014-11-16 • 技术文章

之前,我在《大学课程基础知识整理:数据库原理》文末留了一个SQL设计的问题。这个题是由某项目的具体业务设计时遇到的问题抽象出来的,对于表中类别列分类别取另一数据列的最值,前些日子开源社区的几位同学也在线上简单讨论了一下。

方案选择

看到这个问题,某同学首先想到了用group by,但这样做显然要先子查询排个序,否则得到的并不一定是最值。使用explain查看执行计划,对于该方案,首先是排序来一遍全表扫描,然后在临时表上处理又是一遍全表扫描,type都是all,没有利用到索引。

另外根据讨论情况综合一种方案,select userid,dat from tbl t where t.logintime = (select max(logintime) from tbl where userid = t.userid),查看执行计划,注意到使用到了索引,子查询只扫描了一条记录,select_type是DEPENDENT SUBQUERY,rows=m,外层查询type是index,rows=n。换句话说子查询执行了n次,子查询执行的次数依赖于外层查询。另外为logintime建立索引,也是一种选择。

从执行计划来看,后一种方案效率更高,实际在业务数据中查询也确实效率高很多。但是在使用依赖于外层查询的子查询时,需要小心一些,不妨看看下面的扩展阅读。

扩展阅读

慎用MySQL子查询,尤其是看到DEPENDENT SUBQUERY标记时

RAID及软RAID

2014-11-06 • 技术文章

RAID是“Redundant Array of Independent Disk”的缩写,诞生于1987年,由美国加州大学伯克利分校提出。简单地解释,就是将N台硬盘通过RAID Controller结合成虚拟单台大容量的硬盘使用。RAID最大的优点是提高传输速率和提供容错功能。其中RAID 2、3、4较少实际应用,RAID 5已经涵盖了所需的功能,因此RAID 2、3、4大多只在研究领域有实作,而实际应用上则以RAID 5为主,RAID 6也常见。

RAID 0:连续数据块以轮询的方式写到全部的磁盘上,并行交叉存取,缩短了IO请求的排队时间,最少要2块盘来做,无容错性。

RAID 1:就是做镜像,最少两块盘来做,冗余容错,支持并发读。

RAID 10:即RAID 0和RAID 1的方案一起上,即分布又镜像。优点是同时拥有RAID 0的超凡速度和RAID 1的数据高可靠性,但是CPU占用率同样也更高,而且磁盘的利用率比较低。

RAID 2:在位粒度级别分布,用海明码做校验,适用于大量顺序访问,成本高,实现复杂,基本上不用。

RAID 3:在字节粒度级别分布,使用简单的奇偶校验,单块盘存放校验信息,最少3块盘来实现,容许坏掉一块。对于大量的连续数据可提供很好的传输率,但对于随机数据来说,奇偶校验盘会成为写操作的瓶颈。

RAID 4:在块粒度级别分布,用一块盘来做校验,也是很少使用。

RAID 5:块粒度级别分布,不单独指定奇偶盘,校验信息循环分布在每个盘上,容错性更好。读/写指针可同时对阵列设备进行操作,提供了更高的数据流量。更适合于小数据块和随机读写的数据。容许坏掉1块。有“写损失”,即每一次写操作将产生四个实际的读/写操作,其中两次读旧的数据及奇偶信息,两次写新的数据及奇偶信息。

RAID 6:块粒度级别分布,两份校验信息,容许坏2块盘。

软RAID:一种通过操作系统实现的RAID方式。

参考资料与扩展阅读

http://zh.wikipedia.org/wiki/RAID

短连接、长连接与keep-alive

2014-10-30 • 技术文章

短连接与长连接

通俗来讲,浏览器和服务器每进行一次通信,就建立一次连接,任务结束就中断连接,即短连接。相反地,假如通信结束(如完成了某个HTML文件的信息获取)后保持连接则为长连接。在HTTP/1.0中,默认使用短连接。从HTTP/1.1起,默认使用长连接,这样做的优点是显而易见的,一个网页的加载可能需要HTML文件和多个CSS或者JS,假如每获取一个静态文件都建立一次连接,那么就太浪费时间了,而在保持连接的情况下,继续GET即可。

对于频繁请求资源的客户来说,较适用长连接。但连接数最好进行限制,防止建立太多连接拖累服务端。一般浏览器对一个网站的连接是有限制的几个,所以网站会将资源部署在多个域名上以实现浏览器同时请求。

短/长连接应当在TCP连接的范畴中来讨论。有人常说HTTP的短连接和长连接如何如何,但是HTTP只是一个应用层协议,又是无状态的,最终实质性的保持连接还是得靠传输层,即TCP。

举个例子,NginX作为代理的一种常见配置方式是在NginX与客户端之间的连接使用长连接,NginX与后端服务器之间的连接使用短连接。

keep-alive

我们使用浏览器的开发者工具查看网络请求和响应信息时经常在HTTP请求头部看到Connection: keep-alive,一般的浏览器都会带着个头去请求数据,假如有特殊需求可以用Connection: close断开。HTTP头部的Connection也不一定就被客户端或服务端老老实实地遵循,毕竟各有各的考虑,尤其是在HTTP/1.0这还只是个实验性的功能,而在HTTP/1.1默认长连接于是没有对长连接做特殊的规定。

长连接也不能无限期地长,服务端有可能在头部放Keep-Alive,其中timeout等于一个值来规定保持连接的秒数,还可以用max来规定多少次请求后断开。如果没有说明怎么断开,主动发起四次握手也可以实现连接的断开。

现在有一个问题就是HTTP的keep-alive与TCP的keep-alive到底是什么关系。其实这是两种不同的机制,可以认为没有什么关系。HTTP在头部的Connection中声明keep-alive可以告诉对方要长连接不立即断开,但是TCP的keep-alive则是一种检查对方是否仍旧和自己保持着连接的机制以避免自作多情半开放的连接。假如发出一个探测段,成功收到响应,这证明连接正常保持;假如发出一个探测段一段时间后,一个响应都没收到,对方可能已挂断、机器异常或网络异常;假如对方收到探测段但重置,说明原来的连接已经因为某些原因挂断,目前是因为未进行三次握手新建立连接而被挂断。

参考资料

http://stackoverflow.com/.../relation-between-http-keep-alive-duration-and-tcp-timeout-duration

http://www.cnblogs.com/cswuyg/p/3653263.html

http://www.cnblogs.com/sunada2005/p/3304593.html