为什么不能用`su`切换到密码为空的用户?

UTF*_*F-8 5 users password login su accounts

创建一个名为 的新帐户test

$ sudo useradd test
Run Code Online (Sandbox Code Playgroud)

test现在没有密码。所以

$ su test
Run Code Online (Sandbox Code Playgroud)

不起作用。如果您尝试,系统会要求您输入test的密码。它没有。这与它的密码为空不同,因此如果您按 Enter 输入空密码,您会收到消息“su: Authentication failure”。

如果您切换到 tty 并尝试以以下身份登录,情况也是如此test:不接受空密码。

现在分配test一个空密码:

$ sudo passwd -d test
Run Code Online (Sandbox Code Playgroud)

您现在可以test通过提供空字符串作为密码以 tty 身份登录。但是,如果您尝试

$ su test
Run Code Online (Sandbox Code Playgroud)

再次,您仍然收到消息“su:身份验证失败”,会话未切换到用户test

为什么是这样?

hee*_*ayl 5

从 的输出来看ldd /bin/susu二进制文件是用pam库 ( libpam*)编译的,因此身份验证、帐户管理、会话启动等内容将由pam.

以下是一个典型的 Ubuntu 系统是如何su管理的pam,如果您使用另一个发行版,您应该会找到类似的方法。

pam 规则su在文件中定义/etc/pam.d/su。此文件还包括与通用模板相同目录中的common-auth, common-passwd,common-session文件,用于涵盖其名称建议的任务(并在其他pam启用的服务中使用)。

在我的系统上,在我的底部/etc/pam.d/su有:

@include common-auth
@include common-account
@include common-session
Run Code Online (Sandbox Code Playgroud)

前面几行不涉及空密码检查,主要是pam_unix模块的工作。

现在/etc/pam.d/common-auth有:

auth    [success=1 default=ignore]      pam_unix.so nullok_secure
Run Code Online (Sandbox Code Playgroud)

来自man pam_unix

零点

如果用户的官方密码为空,则此模块的默认操作是不允许用户访问服务。nullok 参数会覆盖此默认值,并允许任何密码为空的用户访问该服务。

nullok_secure

如果用户的官方密码为空,则此模块的默认操作是不允许用户访问服务。nullok_secure 参数会覆盖此默认值,并允许任何密码为空的用户访问该服务,只要 PAM_TTY 的值设置为 /etc/securetty 中的值之一。

如您所见,如果nullok_secure设置了该选项,除非以PAM_TTY上述方式设置环境变量,否则将不允许具有空密码的用户使用su.

因此,要允许任何密码为空的用户执行操作su,您需要将nullok参数传递给pam_unix模块:

auth    [success=1 default=ignore]      pam_unix.so nullok
Run Code Online (Sandbox Code Playgroud)

这是不安全的,因为该common-auth文件被许多其他服务使用,即使只有su这样也不应该这样做。(为了测试,你可以设置一次,然后恢复原样。虽然如果你想做测试,最好将所有的逻辑合并到/etc/pam.d/su文件中,然后修改任何更改,而不是弄乱任何common-*文件)