cron 的 PAM 支持
在上一家公司的时候曾经有很多关于 cron(8) 的想法,但一直没有付诸实施,很多东西放在本地慢慢生锈了。
去年年底的时候我开始着手去修了一些 cron(8) 的 bug,其中包括为 cron 之前不够完整的 PAM 支持进行了改进。
背景:PAM
Pluggable Authentication Module (PAM) 为一系列身份验证相关的操作提供了一组通用的接口。 在没有 PAM 之前,应用程序需要实现大量重复的代码来完成类似的操作,例如要求用户输入密码并进行验证等。 这么做的问题在于缺乏灵活性,例如,管理员可能希望将用户数据保存到 LDAP 目录中, 或是使用指纹等新式验证方式。PAM 使这些相关操作可以通过插件来完成, 应用程序不再需要关心「如何验证用户身份」(用户名、密码等等是不是正确),而只需要向 PAM 询问 「该用户的身份是否合法?」即可。这层抽象简化了应用程序开发者的工作, 并且赋予了系统管理员更大的灵活性。
PAM 将系统的认证工作分成了四组基本操作:
auth:验证用户身份(比如检查密码)。account:检查账户是否有效(比如是否过期、是否允许在此时间登录)。password:用于修改密码。session:会话管理,即用户「进门前」和「出门后」需要进行的环境搭建或清理工作。这是本次更新的核心。
cron 与 PAM 的集成
cron 使用文本文件来配置定时任务,这种配置文件称作 crontab(5)。在 FreeBSD 所使用的 Vixie Cron 派生版本中, crontab 分为两种:系统 crontab 和用户 crontab。前者(系统 crontab)通常只能由 root 用户修改,用于规划以 root 或其他指定用户身份运行的任务;而后者(用户 crontab)则由拥有相应权限的用户通过 crontab(1) 命令进行编辑, 用于规划以该用户自身身份运行的任务。
从逻辑上来看,cron(8) 并不需要与用户进行交互:作为一个后台守护进程,它主要关注「用户账户是否依然有效」
(即 account 检查),而不需要像 login 等交互式应用那样去验证用户密码。
不过,在本次修改之前,FreeBSD 的 cron(8) 并不支持会话管理。而在某些场景下,用户可能希望在任务执行前进行一些初始化操作, 例如设置环境变量、应用资源限制(Resource Limits)、初始化 Kerberos 等跨服务器身份票据,甚至挂载特定的文件系统。
经过此次改进,FreeBSD 的 cron(8) 也可以通过 PAM 来定制 session 级别的设置了。
在开发过程中,我验证了 pam_deny.so(用于禁用特定用户的 crontab)、pam_xdg.so(自动设置 XDG 环境变量)
以及 pam_permit.so(默认行为)的兼容性。