ping 命令的故事

ping 命令主要用于测试网络的连通性与延迟,称得上是最著名的网络诊断工具。IT 专业人员在排查网络故障时,第一步就是执行 ping 命令。就连普通用户在遇到网页打不开或 Wi-Fi 问题时,可能也会打开一片漆黑的命令行界面来 ping 一下。
今天我们来聊一聊 ping 命令的故事,看看这个几乎所有网民或多或少都在使用的命令是如何诞生的;是如何在机缘巧合下让一本儿童绘本在 IT 圈激起浪花的;又是如何影响一名意大利建筑系学生的职业规划的,这名学生日后创造了热门的键值数据库 Redis。
一夜之间 ping 就诞生了
故事开始自 1983 年年底的一个夜晚。就职于美国弹道研究实验室的 Mike Muuss 当年才 25 岁,还是能熬个通宵的年纪。Muuss 为了解决工作中的某个网络问题,连夜编写出了千行左右的代码。一夜之间 ping 诞生了。

Michael John Muuss 1958 年 10 月 16 日~2000 年 11 月 20 日
那一晚,Muuss 不仅编写了大概 500 行左右的 C 语言代码,还顺带修改了所使用的操作系统 BSD Unix 4.2a 的内核。按他自己的说法是“气呼呼地修改了内核”,因为他发现自己的代码能顺利通过编译,但程序的行为不符合预期,查来查去是内核不支持 ICMP 原始套接字(raw socket)导致的,而这正是 ping 所依赖的基础功能。
第二天,Muuss 兴冲冲地来到办公室,打算用 ping 来分析烦人的网络问题。但没想到的是,就在他埋头编写代码的时候,一位同事竟先把问题解决了。虽然 ping 失去了首秀的机会,但 BSD Unix 的维护者,加州大学伯克利分校的人察觉到了 ping 的价值,迫不及待地要走了 Muuss 修改后的内核代码和 ping 的源代码。
随后,ping 就成了 BSD Unix 的标准组件。不久后,ping 又被移植到了其他的操作系统中。而现在,无论是 Windows、Linux 还是 macOS,我们甚至可以在几乎任何主流操作系统上使用 ping 命令测试网络通不通,网速快不快。
随着 ping 的流行,其用法和原理出现在不少 IT 图书上,然而一本以小黄鸭为封面的儿童绘本却在 IT 圈激起了浪花,甚至有人“认为”这是 ping 命令的专著。

在 IT 圈激起浪花的儿童绘本
1933 年出版过一本叫作《The Story of Ping》的英文儿童绘本,比 ping 命令的诞生早了整整 50 年。1933 年就连家用电话都还没有普及,标题中的 Ping 显然不可能是诊断计算机网络问题的 ping。
绘本中的 Ping 其实是一只生活在长江上的小鸭子。它和一大群家人生活在一艘船上,每天早晨,一群鸭子在长江中游玩觅食,傍晚时分再回到船上。有一次 Ping 没能及时回到船上,于是开启了寻找家人的冒险……
随着 ping 命令的流行,这样一本情节简单的绘本却在 IT 圈激起了浪花。有一部分 IT 人只是为了恶作剧,忽悠同事这是一本专门介绍 ping 命令的书,然后期待着看到对方拿到书后一脸迷茫的表情。但有位来自乌兹别克斯坦的工程师非常幽默,认为该绘本中充满了隐喻,作者以小孩都能理解的术语描述了 ping 命令。他的这条书评还偶尔被其他人复制,发布到 Amazon 中。

这位工程师在书评中指出,童话的作者其实是将 ping 数据包(ICMP 报文)比作鸭子,将渔船比作联网的主机,长江则是网络。这样一来,故事的开头——鸭子们离开渔船在长江中游玩,就变成了源主机发出的 ping 数据包进入到网络中;而故事的高潮——小鸭子 Ping 在冒险过程中被另一艘渔船上的人抓住,险些被吃掉,但最终还是脱险并回到了自家的船上,则是在暗指 ping 数据包到达目标主机后又会返回源主机。
书评中最绝的一个解读是:虽然故事发生在长江上,但作者避免了 Ping 遇到了洪水这一类庸俗的情节。小鸭子 Ping 遇到了洪水或被大水淹没英文表达是 flood Ping,而 flood ping 是一个巧妙的双关语,flood 既有“被淹没”的意思,又是 ping 命令的一种工作模式。
在 flood 模式下,ping 命令会疯狂地发送大量数据包,像洪水一样涌来的 ping 数据包甚至会耗尽网络带宽和目标主机的资源。flood 与其说是一种正常的工作模式,倒更像是一种攻击手段,所以要慎重使用。在 Linux 中,只有 root 账号权限才能使用 flood 模式的 ping,而意大利西西里岛上的一位建筑系的大学生却巧妙地绕过了这个限制。
他发现了 ping 的一个漏洞
Redis 的作者 Salvatore Sanfilippo(网名 antirez)在意大利西西里岛长大,虽然从小就接触计算机,也有一些编程经验,但在大学期间却选择了建筑学院,可能当时并没有打算走职业程序员的道路吧。
然而 antirez 应该就属于老天爷赏饭的那类人,据说仅仅因为错把显卡买成了网卡,商家又不肯退货,他就放下游戏,拿起了 C 语言的教材。不久之后,antirez 发现了一个 ping 的漏洞,非 root 用户也可以执行 flood ping。这是怎么回事呢?
ping 命令普通的工作方式是间隔 1 秒就发送 1 个 ping 数据包,而这种周期性是借助系统的定时器所产生的 SIGALRM
信号实现的。超时时间为 1 秒的定时器一到期,就会产生 SIGALRM
信号,进而触发 ping 数据包的发送。
既然只要收到 SIGALRM
信号就会发送 ping 数据包,那如果绕过定时器,大量伪造这种信号呢?antirez 发现 ping 根本不校验这个信号是否真的是因定时器到期(超时)而发出的。于是,antirez 利用一些编程技巧,不需要 root 权限就可以疯狂产生 SIGALRM
信号,间接达到了 flood ping 的效果。
1998 年 5 月,21 岁的 antirez 将这一发现发布到一个专注于计算机安全漏洞披露的公共邮件列表上,并很快得到了网络安全公司 SECLAB 的垂青,一通来自米兰的长途电话邀请他前往 SECLAB 工作。

https://seclists.org/bugtraq/1998/May/139
在 SECLAB 的工作期间,antirez 发明了一种称为 Idle Scan 的网络攻击手法,开发了类似 ping 的工具 hping,并参与了大量 C 语言开发的项目。这无疑是 antirez 职业发展路径上的转折点,离开 SECLAB 后,antirez 为企业提供过基于 Linux 和开源技术的支持和服务,自己创过业,而最重要的里程碑之一莫过于开发出了键值数据库 Redis。
相信还有许多关于 ping 的趣闻逸事,但遗憾的是,ping 之父 Muuss 已不幸离世,我们再也无法聆听他分享那些有趣的故事了。
2000 年 11 月 20 日,Muuss 在发生于美国 95 号州际公路上的一场车祸中丧生。
《巴尔的摩太阳报》于 5 天后刊登的讣告写道:ping 是在 1983 年的一个晚上编写完成的,是全球使用最广泛的计算机网络诊断工具之一。Muuss 的好友 Pistritto 说,“这是 Muuss 一生中做过的又一件微不足道的事,但却有如此广泛的应用”。
Muuss 曾开玩笑说道,早知道 ping 将是我一生中最著名的成就,我可能要花个一两天时间再去完善完善。
版权声明: 本文为 InfoQ 作者【胡译胡说】的原创文章。
原文链接:【http://xie.infoq.cn/article/dc7ee70dbdbf11098a96c9ea7】。文章转载请联系作者。
评论