这篇博文是为了将来北师大在校的校友继续维护我编写的内网上网认证客户端 pysrun 而做准备。
一上来我应该介绍 pysrun 到底是什么。在北师大,使用校园网络需要通过帐号认证,因为上网涉及到费用问题。北师大的网络计费系统采用了深圳深澜公司提供的管理软件,每个用户都需要通过某种方式,用自己的帐号名和密码向学校统一的认证服务器获取许可。通常有两种认证方式:客户端认证或者 Web 页面认证,深澜提供有 MS Windows 和 Linux 操作系统的客户端下载。对于普通的学生帐号来说,在校内多数区域需要客户端,因为 Web 认证被禁用。教师帐号通常可以在任何地方使用 Web 认证。
pysrun 就是我自己编写的一个客户端。为什么要重新编写,而不是用深澜提供的“官方”客户端?我在 pysrun 的说明文档里加入了一段背景介绍来解释这个问题,这里就不逐一重复了。简而言之,原因有三:
- 深澜没有为诸 BSD 系统提供客户端,因此我们最好需要一个跨平台客户端为各种类Unix(Unix-like)系统提供服务。
- 原有客户端软件或许很 user-friendly, 但同时却十分 programmer-hostile, 难以成为自动化流程的组件。我们需要一个新客户端提供符合类Unix环境下习惯的新客户端。
- 原有客户端存在不少 bugs. 由于“官方”客户端不公布源码,我们无法修正它们,只能另起炉灶。
pysrun 的主要目的就是克服这三点我认为比较重要的缺陷。
目前,我认为现在的 pysrun 几乎达成了所有目标。但是,接下来仍然有继续维护和编写的必要。除了不断地清理各种难以避免的小错误外,我觉得还有这些事情可以做。
首先,目前的客户端只在 Linux 系统上经过较详细的测试和试用,在诸 BSD 系统上使用还很有限,很有进一步测试的需要。仅仅在 Linux 系统上能够保证如我们所愿地工作,这不符合我们初衷。想要做到这一点,我们可以通过各种网络配置(桥接,NAT 等)下的虚拟机进行测试,虚拟机可以比较快地在多个系统上同时测试。
第二,现在 pysrun 默认的工作模式,是在用户的主目录下存放配置文件,在 /tmp 下放置工作过程中需要的 Unix domain socket 文件对象。我们可以将其修改成全局安装, 在 /etc 下存放配置文件,在 /var/lib 或其它合适的路径下存放临时性文件,在 /var/log 下存放日志。这样 pysrun 就可以成为一个系统服务,由主机上有权限的用户开启或关闭。
为了做到这一点,除了修改 pysrun 自身以外,还需要进行一些系统配置,比如添加一个低权限用户和群组专门用来执行 pysrun 进程。以 root 用户启动进程以后,让 pysrun 自动 drop privilege 到这个低权用户。运行过程中用来监听用户指令的 socket 文件,应该置于 ownership 和 permissions 合适的子目录下,保证两点:有权限的用户可以随时操作,无权限的用户任何时候都不能操作。
除此之外,还需要为 SysV init, systemd 和 Upstart 等提供启动服务脚本,这样 pysrun 就可以真正成为一个按需启动的服务。
第三,和上面相关的,是通过 distutils 设置安装过程,而不再是要求用户把唯一的可执行文件拷入 PATH 下。之前之所以这样,是考虑到“伸手党”们懒得阅读安装说明,所以把什么都搞到一个文件下,直接把它扔到可执行文件的搜索路径里就行。但后果是,这单一的文件现在越来越大,已经有 1000 多行了。将它拆分成库(package)和可执行文件两部分,再优化库的内部依存结构,有助于我们进一步维护。当然我们不是要抛弃伸手党,因为安装过程也完全可以自动化,我们只需要做好打包工作就行了。
这样做还有一个好处。目前为了照顾各种不同系统的用户,我们不得不加入了很多因系统而异的定义等等,然后在运行时检测自己是什么系统,从而执行相关代码。其实,检测系统完全可以放在安装时进行,然后只安装相应模块。这就避免了代码的浪费。
第四,在登录时,认证服务器会返回一组关于帐号状态的信息。这组信息的数据格式我已经破译了,但还没有派上用场。我们可以增加一个功能,让用户可以查看这组数据告诉我们的帐号状态。
最后,值得说明的是,由于认证过程中需要通过当前时间来编码认证信息,而认证服务器解码的时候当然是用它自己的系统时间,这就存在客户端和服务器端时间不同步的可能性。为了解决这个问题,服务器返回错误代码的时候,在末尾加有它的时间戳,可以帮助我们近似计算可能存在的时间差。目前我们利用之恶个时间戳的方式,是先假设时间差为 0, 然后通过一个循环逐步修正可能的时间差,直到认证成功或最大循环次数超出。是否有必要缓存这个时间差供下次登录使用,目前是一个可以考虑的问题。
这就是我能想到的,接下来可以做的事情。做这些事的时候,我们最好是能够不忘 pysrun 的三大目标,并且最大程度保证兼容性。
同时,以下几点细节,我认为也是值得保持下去的:
pysrun不依赖于任何别的库,只使用 Python 标准库。我相信pysrun需要的功能都很简单,完全可以通过标准库很方便地实现,不需要引入外部依赖。- 我们的设计是一切植根于命令行界面(CLI),满足 CLI 下使用的需要。为此我们刻意不去做 GUI. 如果对 GUI 有兴趣,可以让有兴趣的人去写一个前端。但无论什么样的前端,都应该独立于
pysrun本身,不需要整合进来。 - 现在的代码有比较详细的注释说明,将来也要有。
- 我们现在和用户交互的方式是按照 Unix 的“安静地成功,极度喧嚣地失败”原则进行。也就是,当一切操作正常的时候应该避免任何消息输出,返回值 0 就够了;而失败的时候应该输出尽可能多的错误信息。有必要的信息可以按照用户的要求输出到日志文件。
- 源码是 BSD License 授权的,因此任何人都可以获取源码来做她想做的任何事情。但这个项目一直都独立于北师大“官方”,接下来没必要主动和“官方”扯上什么关系。此前有人建议我联系北师大网络部门,将
pysrun添加到他们的客户端下载里。我拒绝了此建议。如果他们觉得这个东西好,大可自己 fork 之,反正是开源自由的。我们没必要主动和他们联系。
我希望现在写下来的这份“备忘录”,能够成为将来做出一些决定时的参考。