一个数据包消灭一台服务器的 DNS 漏洞

2015 年 7 月 28 日,世界上应用最广泛的 DNS 服务器 bind9 爆出了一个严重的拒绝服务漏洞(CVE-2015-5477)。

一点背景知识:DNS 是把域名映射到 IP 地址的服务。当你访问 google.com 时,计算机就会问你所在小区的 DNS 服务器,google.com 的 IP 地址是什么?如果你的邻居刚好也在访问 google.com,DNS 服务器就会直接返回其 IP;不然,这个 DNS 服务器就会去问 Google 官方的 DNS 服务器,得到 google.com 的 IP 地址,并返回给你。这个小区的 DNS 服务器叫做递归 DNS;递归 DNS 挂了,会导致它服务的区域无法上网。Google 官方的 DNS 服务器叫做权威 DNS;权威 DNS 挂了,会导致它所服务的网站从地球上消失。

图片来源:
DNS 递归查询(图片来源

这个漏洞严重到什么程度呢?只要发一个 UDP 数据包,就能搞挂一台 DNS 服务器。不管是递归 DNS 还是权威 DNS,不管是 bind9 做了什么样的配置,只要这个数据包被 bind9 进程接收了,它就会立刻抛出异常,终止服务。

继续阅读“一个数据包消灭一台服务器的 DNS 漏洞”

从受损的 git 仓库里恢复代码

背景:Windows 上的 Virtualbox 虚拟机。Ubuntu 14.04.1 LTS,3.13 内核。ext4 文件系统。

作死:前几天一直在该虚拟机上开发网站,做了 N 多 commit,以为 git push 了,但事实上 push 失败了。

悬疑:今天妹子 git pull 了一下,发现没有任何更新,然后说我这几天都没干活。

悲剧:登录到虚拟机里一看,项目目录里有几个刚写的文件变成了 0 字节的空文件。(ext4 这么稳定,一定是母机里万恶的 NTFS 和 Virtualbox 惹的祸)
.git 目录里好多文件也变成了 0 字节的空文件。git 提示仓库已损坏。

$ git status
error: object file .git/objects/71/cbcbbc9d06a74f2fd8ea9109b81b88086f1430 is empty
error: object file .git/objects/71/cbcbbc9d06a74f2fd8ea9109b81b88086f1430 is empty
fatal: loose object 71cbcbbc9d06a74f2fd8ea9109b81b88086f1430 (stored in .git/objects/71/cbcbbc9d06a74f2fd8ea9109b81b88086f1430) is corrupt
$ git fsck
error: object file .git/objects/00/837a7e1f8afb8da8609369f7acf95fe9b7fc5b is empty
error: object file .git/objects/00/837a7e1f8afb8da8609369f7acf95fe9b7fc5b is empty
fatal: loose object 00837a7e1f8afb8da8609369f7acf95fe9b7fc5b (stored in .git/objects/00/837a7e1f8afb8da8609369f7acf95fe9b7fc5b) is corrupt

几天来写的代码是不是这样就灰飞烟灭了呢?我们知道,当你删除一个东西的时候,你只是删除了这个东西在当前三维空间中的引用,而这个东西的本体仍然存在于四维时空之中。穿越大法,走起!

继续阅读“从受损的 git 仓库里恢复代码”

博客启用新域名 ring0.me

2013 年 5 月 16 日,我的博客有了顶级域名 bojieli.com。2015 年 1 月 6 日,注册并启用了新域名 ring0.me(是数字 0 哦,字体看着像字母 O)。

Ring0 是 CPU 体系结构里特权级最高的保护级别,运行在 Ring0 级别的代码直接与物理硬件交互。特权级的概念可以追溯到 20 世纪 60 年代的 MULTICS。在 x86 体系结构中,ring0 代表操作系统内核和内核驱动,相对于通常运行在 ring 3 的用户态应用程序。我第一次听说 ring0 是在一篇关于 rootkits 的文章里,那时我初中,对 “黑客” 技术很好奇。惭愧的是,我至今都不会写 rootkit。

我的博客使用 ring0.me 这个域名,是为了展示我的兴趣主要在搭建起计算机系统和网络的基础研究和技术。

注册 ring0.me 是感觉姓名全拼的域名 bojieli.com 看起来不够 geek。我想过 rdma, ssh22, http80, tcp80, printk, reisub 等多个未被注册的域名,最后还是觉得 ring0 更好。

原来的 bojieli.com 已经 HTTP 301 跳转到 ring0.me 的相应页面。由于 StartSSL 的政策限制,SSL 证书需要在域名注册后三天才能申请。1 月 17 日部署了 SSL 证书。bojieli.com 将继续服务到 2016 年 5 月,之后不再续费。

博客标题由 “null != undefined” 改成了 “Ring0”,副标题由 “Seeking possibility for next-generation network” 改成了 “Fundamental research in networked systems”。希望读者喜欢 ^_^

《程序员的自我修养》读书笔记

贴一篇旧文:2012 年 6 月写的读书笔记(原文链接)。这个笔记是写给自己看的,里面掺进了太多自己的设想,有可能会对读者造成误导。不过文章太长了,没有时间修订。欢迎吐槽。

近来(2012 年上半年)在郭家华的推荐下,读了LUG书库的《程序员的自我修养——链接、装载与库》一书,有种相见恨晚的感觉。然而快到期末考试了,没有时间把全书读完,因此只写了一部分。

有两种方式构建软件:一种是把它设计得如此简单以至于明显没有缺陷,另一种是把它设计得如此复杂以至于没有明显的缺陷;前一种的难度大得多。

——Hoare 于图灵奖演讲《皇帝的旧衣》

继续阅读“《程序员的自我修养》读书笔记”

虚拟化技术大观

按:2014 年 11 月 21 日,笔者在阿里巴巴技术俱乐部的虚拟化技术交流会暨 “科大云 3.0” 发布会上分享了一些对虚拟化技术的浅见,整理、补充后与诸位探讨。(长文慎入)

虚拟化技术大家都不陌生,我们大都使用过诸如 VMWare、VirtualBox 的虚拟机软件。一些人认为,虚拟化技术是近几年跟着云计算的潮流才火起来的,十年前只是桌面用户测试其他操作系统的玩具。非也。只要计算机上同时运行着多个任务,就会有任务隔离的需求,虚拟化就是让每个任务看起来独占整个计算机、隔离任务之间影响的技术。早在计算机还是庞然大物的 20 世纪 60 年代,虚拟化技术就开始发展了。

IBM 7044

继续阅读“虚拟化技术大观”

网络权威 Jennifer Rexford 教授给研究生的忠告

译者按:Jennifer Rexford 是普林斯顿大学教授、网络研究圈子里呼风唤雨的大牛。她在 2010 年给新入学的工程领域研究生做了个报告:Advice for New Graduates

了解我的人都知道我有收集名言的爱好。一句话解释这背后的故事:名言短小便携,对小时候经常搬家的我来说是一个合适的爱好。20 世纪 30 年代普林斯顿的两个著名科学家,爱因斯坦和托马斯·路易斯,分别对 “个体” 所处的角色发表了有趣而有些对立的评论。

物理领域的爱因斯坦说:“人类社会所有有价值的东西依赖于个体发展的机会。”

药学、生物学领域的托马斯·路易斯则说,“事实上不存在单个个体这样的生物;他自己的生命并不比从皮肤表面上扯下来的一个细胞多什么。”

这两句名言很好地概括了研究生是干什么的。

继续阅读“网络权威 Jennifer Rexford 教授给研究生的忠告”

大话同步/异步、阻塞/非阻塞

好多人搞不清这两组概念之间的区别。我们拿小明下载文件打个比方。

  1. 同步阻塞:小明一直盯着下载进度条,到 100% 的时候就完成。
  2. 同步非阻塞:小明提交下载任务后就去干别的,每过一段时间就去瞄一眼进度条,看到 100% 就完成。
  3. 异步阻塞:小明换了个有下载完成通知功能的软件,下载完成就“叮”一声。不过小明仍然一直等待“叮”的声音(看起来很傻,不是吗)
  4. 异步非阻塞:仍然是那个会“叮”一声的下载软件,小明提交下载任务后就去干别的,听到“叮”的一声就知道完成了。

也就是说,同步/异步是下载软件的通知方式,或者说 API 被调用者的通知方式。阻塞/非阻塞则是小明的等待方式,或者说 API 调用者的等待方式。

继续阅读“大话同步/异步、阻塞/非阻塞”

编译:一个 C 程序的艺术之旅

正在学习 CS50(一门 MOOC)的 @张静宁 写了一篇《【读图学 C 语言】编译时发生了什么》。她的文章更多讲的是 “what”,本文将尝试解释一些 “why”。

C 程序为什么要编译才能执行?一个 C 程序在变成可执行文件的过程中,为什么要经过预处理、编译、汇编、链接这四道工序?让我们从这段简单的 C 程序开始。

为什么要编译

这并不是一个简单的问题。我们知道 Python 代码不需要 “编译”,输入一行代码就可以运行出结果了,对用户很友好有木有!这种交互式的运行环境被称为 REPL(Read-Evaluate-Print-Loop),也就是读取用户输入的语句,执行语句,输出语句的值,再返回到等待输入状态。 继续阅读“编译:一个 C 程序的艺术之旅”

给开源编译器插入后门

说起 Ken Thompson,我们首先想到的是他发明的 UNIX 操作系统。他因此获得 1984 年的图灵奖。在图灵奖演讲上,Ken Thompson 提出了一个深刻的问题:看到了软件的源码,就意味着没有后门吗?编译器是否可能存在能自我复制的后门?

KenThompson

这篇发表在《ACM 通讯》上的论文只有短短三页,省略了很多细节。原理上有点像输出自身代码的 C 程序,但又比它难很多。我追随先哲的脚步,给一个开源 C 编译器——tcc 插入了能自我复制的后门,这个插入了后门的编译器在编译 Linux 登录程序 sulogin 的源码时,会自动插入一个后门。

继续阅读“给开源编译器插入后门”

3G 为什么比 Wi-Fi 费电

前天张擎宇同学告诉我,在有 Wi-Fi 的时候最好使用 Wi-Fi 并关掉 3G 网络,可以省很多电。3G 真的比 Wi-Fi 费电吗?我查阅了文献,发现果真如此。当要传输的数据较少时,电源消耗的差距可以大到 10 倍之多。

蓝线:3G 功耗;绿线:wifi 功耗(来源:TailEnder)
蓝线:3G 功耗;绿线:wifi 功耗;紫线:考虑了 wifi 扫描和建立连接之后的功耗(来源:TailEnder)

原因主要有两方面:

  1. 3G 网络完成数据传输后要保持一段时间的高功率状态;
  2. 3G 网络的发射功率远大于 Wi-Fi 网络。

继续阅读“3G 为什么比 Wi-Fi 费电”