如何告诉 SSH 在 PAM 之后而不是在重新映射用户之前设置 uid

Nic*_*Goy 6 linux ssh pam

我正在研究由 PAM 模块和 NSS 模块组成的半径身份验证解决方案。

流程是这样的:

  • 用户ben登录(通过login命令)
  • 用户输入用户名: ben
  • 使用该用户名查询我的 NSS 模块并返回一个默认的非特权用户radius,行为与libnss-ato相同
  • 用户输入密码
  • 我的 PAM 模块被调用并将查询 Radius 服务器,如果 auth 被接受,PAM 模块将使用 Radius 供应商属性来选择一个本地用户名来映射 Radius 用户,这个映射被写入数据库,例如ben->admin
  • 现在,我的 NSS 模块将读取该数据库并返回 Radius 用户的正确本地用户名
  • 使用该login命令,用户以正确的映射用户登录admin

现在,我的问题如下。OpenSSH 服务器会在 PAM 之前读取 NSS。

这意味着流程是这样的:

  • 用户benssh 进入
  • SSH查询NSS并映射ben到默认账号radius
  • 用户将看到密码提示并输入密码
  • 我的 PAM 模块被调用并且映射ben->admin缓存
  • SSH 将产生一个会话,radius而不是admin因为它使用在调用 PAM 之前从 NSS 获得的值

现在这个错误只发生在第一次登录时,因为在第二次登录时 NSS 将缓存数据并在第一次调用时返回正确的用户。

但这仍然是一个问题,首先是因为我不想每次第一次登录都落到错误的用户,其次如果ben管理员权限下降,由于我的 NSS 缓存,他的下一次登录仍然会通过 SSH 映射到管理员NSS 模块。

我无法在第一次 NSS 调用中查询映射,因为从 radius 查询映射需要成功登录。

我有一些线索,但我真的很想对这个问题有一些见解。

我的线索是:

  • radius用户使用一个特殊的 root setuid shell,这个 shell 会读取我的 NSS 数据库并更改用户,然后执行真正的 shell,问题是我需要知道登录的是哪个半径用户。我可以在我的PAM 模块,但由于 shell 将是 setuid,我需要一个安全机制来确保 var 是可信的。我唯一看到的是在 var 中有一个加密签名,并让 setuid shell 使用 root 0600 中的私钥验证它。
  • 调用setuidPAM 模块,但这听起来很可疑

Nic*_*Goy 2

我最终将用户的 shell 更改为 setuid 包装器,该包装器会删除目标用户的权限。

代码在这里: https: //github.com/kuon/radius-auth-virtual