cron 的 PAM 支持

• 本文约 974 字,阅读大致需要 2 分钟 | Development | #FreeBSD | #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(默认行为)的兼容性。