开源路由器固件上 Bug 的故事(一)

前段时间在 atppp 的博客上读到了“纪念一个 Bug”,这让我想起了 OpenWRT 开源固件上面关于 Broadcom 交换芯片的一个 bug,所以也来写个文章纪念一下。

1. Linksys 开源路由器固件的起源和发展

OpenWRT 这个项目最早起源于 Linksys 的 WRT54G 家用无线路由器固件。WRT54G 这款无线路由器(台灣同胞稱作“無線基地台”或者“無線IP分享器”)是 2003 年 802.11g 无线网络兴起时在家用领域的领军人物,引来叫好一片。于是有人研究了它的软件系统,赫然发现它是一个基于 Linux 的嵌入式系统。所以根据 GPL 这一个病毒一样的协议要求 Linksys 开放源代码。Linksys 架不住压力,于是根据 GPL 开放了源代码(现在还可以在 Linksys 的网站上下载)。这一开放,就使得第三方固件雨后春笋一般蓬勃发展起来。OpenWRT 是最特别的一个。因为别家都是在 Linksys 的源代码基础上添砖加瓦,唯有 OpenWRT 是重新构造一个完整功能的路由器固件。

然而做 OpenWRT 的都是一群高人,他们注重扩展性、可定制性却忽视了普通大众的需求。做出来的东西只能用命令行玩玩,这让习惯从浏览器里配置无线路由器的劳苦大众无所适从。所以后来有了 Seavsoft 做了收费但带有 Web UI 的固件,再后来又有了 DD-WRT,DD-WRT 从 v23 的成熟发展到今天 v24 sp2 的功能多样而不失易用性,的确为开源无线路由器的发展立下了汗马功劳。

Tomato 是 DD-WRT 之外异军突起的一个优秀固件。它注重于简单、实用、高效,并且以优雅的 AJAX Web UI 和高效的 QoS 功能赢得了广泛支持。作者原来是 HyperWRT 开发小组的一员,后来跑出来自立门户开发 HyperWRT + Tofu 固件,就演变成了今天的 Tomato Firmware 。

(汗 :mrgreen: 说了个背景就说了这么多!)

2. 关于 802.1X 认证的 bug

因为面向家用和小企业市场,家用路由器的连接方式主要是 PPPoE 和 LAN 接入。但是现在众多学校等接入单位觉得对于 LAN 接入不方便对用户的控制和管理,于是把原本为无线网络设计的 802.1X 认证体系引入到了 LAN 网络中。802.1X 是一个二层的访问控制协议,用户只有认证之后,交换机才开放相应的端口,允许用户接入。这就是传说中的“基于端口”的管理。

众多学校引入了 IEEE 802.1X 之后,导致市面上的家用无线路由统统作废,因为这些设备压根就没有支持 802.1X 这回事(当然现在国内的 TP-LINK 已经顺应国情推出了支持 802.1X 认证的产品)。更可恶的是,国内的锐捷、H3C 推出了802.1x 的自有扩展协议,只能使用自己研制的客户端上网。而这些客户端无一例外地“附赠”了禁止NAT、多网卡的功能。妄图以多角度、多手段来扼杀同学们突破限制的种种企图。

俗话说“道高一尺,魔高一丈”,又说“上有政策,下有对策”,Linux 版本的 802.1x 客户端也自然而然的产生了。而开源固件又正好是基于 Linux 制作的。这些小路由器们个个都有支持 MIPS 指令集的 CPU,外加 4-32 MB 不等的 Flash ROM 和 RAM,本身就是一个五脏俱全的嵌入式 Linux 系统。这样就可以想办法将认证程序移植到开源固件中。

我去买了个 Buffalo  WHR-G125 ,在 Ubuntu Linux 下半生不熟地用交叉编译工具编译出学校校园网的认证程序 mytunet,满怀希望地放上去跑,没想到程序一直停滞在“Send logon request …” 这一步,压根没有收到服务器的响应。但把网线换到 PC 上又可以正常登录。看来是某个地方有问题了。

后来在 Google 上使劲搜,终于找到了问题的原因,OpenWRT 的 Trac 上有两个编号为 16871862 的 Ticket 说明了这个问题。

1687 放出来以后,人家没仔细看就把这个 ticket 关掉了,后面又有人 reopen ,然后再度被关闭。如此往复了几次,就晾在那没人理了。

1862 就更无奈了,Bug 放出来一年没有人理,四楼的哥们一怒之下来了一段抱怨的话:

Judging the fact that this bug is now lingering on for more than a year (since I first pointed it out) and the zero respons from the openwrt team, I came to the understanding that the openwrt team is more interested in fancy apps than a good working tcp stack. Shame shame shame.

俺七个月以前看到这个状态的时候,也觉得很无奈。人家开发者压根不鸟你,只好自己也参与讨论,然后以 Scott Liu 的身份在上面用蹩脚的英语提了提自己的意见完事。

后来把这个路由器在水木二手版上折价买掉了,360买回来的东西拿回来没过十天转出去的时候就是 260 了,价格掉得真快。期间有幸得到康神的指导,倍感荣幸。神说俺体察了一下网络上的民情,发现这是 Broadcom 交换芯片的硬伤,只是俺精力不如从前没工夫去 patch 了,你把它出掉是明智的。神又给我指了一条明路,说神自己的 Dell TrueMobile 2300 可以发送和接收 EAP 认证包,不存在上面的问题,指示我去买一个使用了 6996L 交换芯片的机器就没问题。

幸得神助,又在淘宝上淘了一个 Linksys WRT54GS v1.1 v1.0 (感谢 hyspace 指正) ,序列号以 CGN1 开头,特意跟店家确认了是 6996L 交换芯片。拿回来刷好固件,试了试,果然毫无问题地通过了校园 802.1X 认证!回来跟康神报告,神 cong 了一下又很谦虚地说“其实原因你自己之前也说了……”云云。向 atppp 学习随时随地拜康神!

买到了没有 bug 的硬件,这个问题基本上靠以段落了。下一段的 bugfix 又是后话。

“开源路由器固件上 Bug 的故事(一)”的18个回复

    1. @章鱼

      哈哈~! 原来你也跟随 atppp 成了康神的教众~
      资料收到,解决问题指日可待矣!很是感谢~! 🙂

      现在也终于理解了为什么那bug晾在那儿一年半载的没有人理。可恶的 Broadcom 封锁资料,没有文档要解决问题也只好望BUG兴叹了。。

    1. 康神伟大!
      bugfix 由 Jouke Witteveen 给出了,不过只能用于 标准的 802.1X 认证,非标准的还没有办法。。 故事(二)里讲的就是这个。。

  1. 这位高人,我现在正准备搞一个开源WAN路由器,目的是针对学校的华为H3C 802.1X认证。由于华为客户端只支持WIN并且禁止了NAT和多网卡,导致我在宿舍无法使用WIFI设备上网,MAC OS下上网也成问题,于是想到了开源路由器,之前在LINUX下用到过一个我感觉很稳定的客户端,我想试试移植到开源路由器上。
    有几个问题想请教,如果你时间充裕的话感激不尽。
    第一是程序的移植难度高不高,我现在是一个非计算机专业的学生,编程只是爱好,也刚刚才接触ARM-LINUX的交叉编译,有希望能成功么?第二是买什么型号的路由器比较好,我看到DD-WRT支持的路由器型号很多,甚至有802.11n的,是否也可以用?第三是路由器固件的问题。只能用OpenWRT的固件么?DD-WRT或者TOMATO等支持GUI的固件是否也可以植入自己交叉编译的程序?如果可以的话我甚至想做一个GUI的配置界面。四是你移植成功后可靠性高不高,是否经常掉线。之前我用过很多别的方法实现共享上网,但是可靠性都不是很好,没有实际使用价值。

  2. @hyspace
    你好,很高兴能帮到你。高人谈不上,姑且回答一下你的疑问吧。
    1. 难度有,但不如你想象的那么高。现在 Linux 已经是相当普及了,如果实在有什么问题,到相关的论坛上问一问,会有大把人给你回复。所以也可以看成是“没有难度”。
    2. 买路由器这个,涉及到我在文章里提及的这个bug,现在的新机器都多少需要patch。你可以看看 Belkin 7231-4P ,Linksys WRT54G/GS 早期使用 6996 交换芯片的机型,这都是老机器,没有全新的了。 ASUS WL-520gU , Buffalo WHR-HP-G54 这两款机器都有新的,但是针对交换芯片需要特别的patch,有一点麻烦,因此放在后面推荐。
    3. 固件理论上来说没有限制。因为都是基于 Linux 平台的,植入自己编译的程序这一点上没有太大的差别。可能只是需要针对特定的 Linux 版本重新编译一下。这种小程序就不必 GUI 了,命令行参数就能很好地工作。
    4. 可靠性来说,和你在 LInux 机器下的是一致的。因为使用的源码一样。
    另外,你可以多关注一下国内相关的讨论组,比如QQ群86079951,Google Groups 讨论组 http://groups.google.com/group/njit8021xclient?hl=zh-CN
    希望能帮到你 🙂

  3. @xiaoding
    多谢你的回答。
    现在我基本上有个大概的了解了。我查了一下Linksys WRT54GS的资料,发现v1.1的序列号开头是CGN2,而且交换芯片也不是6996,但是v1.0的则和你文章中描述的一致。
    http://en.wikipedia.org/wiki/Linksys_WRT54G_series#WRT54GS
    莫非你买到的是V1.0的?
    我提到的很好用的802.1x客户端指得就是NJIT的这个,我经常上这个GROUP关注更新情况。这客户端个的功能最好,源码注释也很清晰。
    再次多谢高人指点,我现在已经准备入手一个开始研究。

  4. @hyspace
    不必客气
    我仔细看了一下,我的路由器的确是 CGN1 开头的。那就是我记错了,把文章中的版本写成了 v1.1 ,多谢你的指正。当初我买这个版本的机器就是为了避开文章中提到的bug
    祝你成功 😀

  5. 博主您好 我是H3C802.1X用户受害者.. 百度到了这里 看了您的帖子 就在淘宝入了个6996芯片的WRT54GS V1 卖家帮刷了番茄 然后在网上下载了个别人编译好的H3C客户端 作者说明番茄和DD都可以使用 但是我下载解压后发现是一个没有扩展名的文件 不知道如何使用 更不知道怎么修改 望您在有空的时候能指点一二 万分感谢~!

  6. @大毛虫
    看来你没有 Linux 的基本使用经验,建议你学习一下。 Linux 下的可执行文件是由文件系统的权限来标记的,如果用 ls -l 看到权限位有 x 标记说明可以执行。

  7. 抱歉又来叨扰。。我研究了数天 实在是技穷了 求您帮忙
    我下载了别人编译好的文件(TT和DD可以执行) 作者的使用说明是这样的:
    用法:
    1.把h3cclient传到/jffs,是外挂U盘的目录,
    2.路由上WAN设置自动DHCP,我的校园网是自动分配的,固定IP的自己研究吧
    3.电脑上telnet连接路由
    4. $ifconfig // 可以看到WAN口是vlan1,绑定MAC的要在DD上克隆MAC ,拨号就用这端口,你的特别的话,就自己选吧
    5. $ifconfig vlan1 10.10.10.10 //设置固定IP,这个IP是随便的,连接成功的就会自动获取最新IP的了,原代码的就是这样设置的,谁能修改一下,去了这个也行的,没设IP会显示“can’t find the specified interface”
    6. $./h3cclient -d -r -u 你的用户名/你的密码 vlan1 //-d是后台运行,关了telnet 还在运行

    我前三步做好了(这三步对我来说都很艰难。。研究了很久) 第四步看不明白 怎么能确认wan口是vlan1? 第五步 提示符下打入ifconfig vlan1 10.10.10.10 回车没有任何提示 不知是否成功 第六步 回车后提示-sh: ./h3cclient: not found 不知道为什么 需要路径么?

  8. 学校用的是ZTE认证、我现在用的是 TL-WR741N刷成了 DD-WRT/
    要怎么把802.1X+动态IP认证方式加到路由去呢?

发表回复

您的电子邮箱地址不会被公开。 必填项已用 * 标注