我试图在 Ubuntu 上使用 pam_exec.so 来调用脚本,提示用户输入,并允许用户通过 SSH 登录(如果脚本以退出代码 0 退出)。我无法让它工作。所以我写了一个简单的脚本如下来测试pam_exec.so,看看问题是否出在我原来的脚本上。然而,即使使用这个简单的脚本,我也会遇到同样的问题。
/usr/local/bin/test.sh
#!/bin/bash
echo -n "Please enter your name:"
read name
echo "Hello $name"
@include common-auth
我通过在 /etc/pam.d/sshd 中添加以下行来调用它
auth required pam_exec.so stdout /usr/local/bin/test.sh
但是,当我通过 SSH 连接到该系统时(如下所示),我没有收到输入任何输入的提示。输入密码后,我就会登录。但是,脚本的输出是可见的。
然后我将上面的脚本更改如下,如果没有给出输入,则以退出代码 1 退出。
#!/bin/bash
echo -n "Please enter your name:"
read name
if [ -z "$name" ]
then
exit 1
else
echo "Hello $name"
exit 0
fi
然后,即使我输入正确的密码,我也无法通过 SSH 进入系统(下面的屏幕截图),并且看不到脚本的任何输出。
所以我想知道的是如何纠正这个问题并使用 pam_exec.so 运行脚本,获取用户输入,并仅当该脚本以退出代码 0 退出时才允许 ssh 授权?
答案1
我不熟悉pam_exec.so
实现,但我已经完成了一个小型 PAM,并且我认为任何模块处理与第三方脚本的交互会话都是很棘手的,因为 PAM 对话的工作方式(pam_conv_*
函数)以及需要知道何时第三方脚本将被读取stdin
或不被读取(因为该脚本不仅仅是exec
由前台的模块读取)。
根据人们愿意付出的努力量,构建 PAM 并不复杂,并且您可以轻松阅读以下示例Python或者戈兰
另一个(也许更快)选项是使用stdin
中的选项pam_exec.so
。
撇开安全性不谈,根据您的用例,这可能就足够了,因为它将密码发送到脚本标准输入。
如果您可以选择将脚本输入与密码连接起来(例如某些 2FA 实现,您在密码字段中输入密码 + OTP):
- 将选项添加
stdin
到您的pam_exec.so
线路 - 在您的脚本中,将密码与第二个输入分开
- 处理密码身份验证本身(因为
pam_unix
使用额外的输入将无法做到这一点) - 利用您的额外输入