脚本必须由 pam_exec 运行的 SELinux 上下文是什么?

sha*_*ote 5 pam selinux

我刚刚在我的 VPS 上安装了 Fedora 22 并试图做一些小事——在每次 ssh 登录时通过 pam_exec 运行我的告密者脚本。但是我遇到了意想不到的困难:pam_exec 失败,退出代码为 13。

我在 /etc/pam.d/sshd 的末尾添加了习惯行:

session optional pam_exec.so seteuid /usr/local/bin/loginformer.py
Run Code Online (Sandbox Code Playgroud)

当然 loginformer.py 有执行标志:

$ ls -l /usr/local/bin/loginformer.py
-rwxr-xr-x. 1 root root 4254 Jun  8 09:35 /usr/local/bin/loginformer.py
Run Code Online (Sandbox Code Playgroud)

但这里是痛苦的摘录journalctl -lb SYSLOG_FACILITY=10

Jun 08 11:58:49 fedora22 sshd[671]: pam_exec(sshd:session): execve(/usr/local/bin/loginformer.py,...) failed: Permission denied
Jun 08 11:58:49 fedora22 sshd[663]: pam_exec(sshd:session): /usr/local/bin/loginformer.py failed: exit code 13
Run Code Online (Sandbox Code Playgroud)

我不确定发生了什么,因为它始终适用于我的 ArchLinux。我认为这可能是一些 SELinux 限制,但我不确定。

我做错了什么?

更新

好吧,我尝试深入了解 SELinux 并明白我应该更改脚本的 SELinux 上下文。

现在它的 SELinux 上下文看起来是这样的:

$ ls -Z /usr/local/bin/loginformer.py
unconfined_u:object_r:user_home_t:s0 /usr/local/bin/loginformer.py
Run Code Online (Sandbox Code Playgroud)

但是我应该为脚本设置哪个上下文?

更新 2

另外,我认为 SELinux AVC 日志对于检测问题可能非常有用。很抱歉我没有早点给。 cat /var/log/audit/audit.log | grep loginformer.py返回很多相同的字符串:

type=AVC msg=audit(1433784991.570:265): avc:  denied  { execute } for  pid=7866 comm="sshd" name="loginfomer.py" dev="vda1" ino=11924 scontext=system_u:system_r:sshd_t:s0-s0:c0.c1023 tcontext=unconfined_u:object_r:user_home_t:s0 tclass=file permissive=0
Run Code Online (Sandbox Code Playgroud)

seb*_*sth 2

pam_execpam_selinux的调用顺序很重要。注释的手册页pam_selinux

将 pam_selinux 添加到 PAM 堆栈中可能会破坏执行应用程序的其他 PAM 模块的行为。为了避免这种情况,pam_selinux.so open应放置在 PAM 堆栈中此类模块之后,而 pam_selinux.so close应放置在它们之前。当这样的放置不可行时,可以使用pam_selinux.so 恢复来临时恢复原始安全上下文。

同样,丹·沃尔什 (Dan Walsh)就该主题写道:

如果您要添加一个 pam_module 来执行不允许用户执行的命令,例如 pam_mount,则应将其添加在pam_selinux.so open 命令之前。如果您要添加一个 pam_module 来执行用户可以执行的命令,那么您可能需要在pam_selinux.so 打开行之后添加这些模块。

另请注意,您的脚本当前的安全上下文为user_home_t,这可能与默认策略不兼容(移动文件时会保留文件上下文;如果您在主目录中创建文件,则移动文件将保留原始上下文)。您可能应该使用默认bin_t上下文。要恢复默认上下文:

restorecon  /usr/local/bin/loginformer.py
Run Code Online (Sandbox Code Playgroud)

如果您的脚本没有做任何太特殊的事情,则放置在上下文pam_exec之前pam_selinux并重新字符串应该足以解决您的问题。