如何列出 Linux 中所有锁定的用户?
usermod -L user_name
此命令锁定特定用户。Linux 是否有任何命令可以列出锁定的用户?
答案1
passwd -S -a | grep LK | cut -d " " -f1
和/或 passwd -S -a |awk '/LK/{print $1}'
应该管用。
(如果你感兴趣的话)
这两个例子都展示了 Unix/Linux 中使用的一种非常常见的技术:我称之为命令管道。
在这些例子中,一个命令(例如 ls)的输出被“传输到”另一个命令,该命令有效地过滤其输入并将其发送到下游。
參閱Linux问题网站了解更多信息。
答案2
sudo awk '/!\*/' /etc/shadow | cut -d : -f1
本地用户的另一种方式。
答案3
现有的答案并不精确:对于使用不同技术锁定的账户,他们会得到假阴性usermod -L
,而对于使用不同技术锁定的账户,他们会得到假阴性。积极因素在可以使用 SSH 密钥但不能使用密码登录的帐户上。
为了在具有本地密码和影子文件以及活动 SSH 守护程序的系统上进行全面工作,您必须检查所有这些情况:
首先查看 的 shell 字段;如果它是、或
/etc/passwd
之一,则该帐户将被无条件锁定。(原则上,您可以使用任何非有效 shell 程序,但没有简单的方法来定义“有效 shell 程序”,并且该字段中带有不寻常程序的专用帐户非常常见,您不想假设这些帐户已被锁定。)/bin/false
/sbin/nologin
/usr/sbin/nologin
对于具有有效 shell 的帐户,接下来检查
~user/.ssh/authorized_keys
或是否~user/.ssh/authorized_keys2
存在、是否为空以及是否具有适当的访问权限。(该文件及其所有父目录必须由用户或 root 拥有,并且其他所有帐户都无法写入。)如果是这样,则可以使用某个 SSH 密钥登录该帐户,即使没有密码。根据 PAM 和 sshd 配置,可能可以使用 中的“帐户到期日期”字段禁用此类帐户/etc/shadow
,但最安全的做法是假设这是不可能的。对于具有有效 shell 但没有 的帐户
authorized_keys
,接下来检查/etc/shadow
。密码字段有三种可能性:如果它为空,则可以使用该帐户而无需指定任何密码。(可以配置 PAM 以阻止对此类帐户的访问,但我永远不会假设这样做了。)如果它是crypt(3)
某个密码的有效哈希值,则可以使用该密码访问该帐户。 任何其他字符串表示无法使用密码访问帐户。通常,您会看到使用*
、!
或之一*LK*
。不幸的是,没有简单的方法来判断一个字符串是否是有效的
crypt(3)
哈希值一些密码。我在此的建议是将任何以*
或开头的字符串!
视为表示该帐户无法使用密码登录,而将任何其他字符串视为表示可以登录。从技术上讲,“密码最长使用期限”、“密码不活动期”和“帐户到期日期”字段
/etc/shadow
也可用于禁用用户帐户,但我会犹豫是否要依赖这些作为锁定帐户的唯一手段,因此在决定帐户是否被锁定时,我也不会查看它们。从技术上讲,记录的密码字段
/etc/passwd
可能包含除魔法令牌x
(意思是“去查看/etc/shadow
”)以外的其他内容,但如今,这表明操作系统配置有灾难性错误。如果我看到这种情况,我会认为该盒子已被攻破并进入灾难恢复模式。
这个 Python 脚本(必须以 root 身份运行,因为它会读取/etc/shadow
并进入每个人的主目录)将打印所有用户的登录名解锁用户。这通常比所有锁定用户的列表更有用,因为其中包含一堆不感兴趣的系统帐户。
#! /usr/bin/python3
import os
import stat
import sys
def get_homes_and_uids_for_users_with_shells():
users = {}
with open("/etc/passwd", "rt") as pf:
for line in pf:
login, x, uid, gid, gecos, home, shell = line.split(':')
if x != 'x':
sys.stderr.write("*** Account '{!r}' not properly shadowed\n"
.format(login))
if shell not in ('/bin/false', '/usr/bin/false',
'/sbin/nologin', '/usr/sbin/nologin'):
users[login] = (int(uid), home)
return users
def check_ssh_auth_perms(path, owner):
owners = (0, owner)
badwritebits = stat.S_IWGRP | stat.S_IWOTH # 0022
# FIXME: I'm not sure whether sshd allows symlinks at any point in this
# path. Conservatively assume it does.
# FIXME: Doesn't check for ACLs.
try:
st = os.stat(path)
except FileNotFoundError:
return False
if (st.st_size == 0 or st.st_uid not in owners
or not stat.S_ISREG(st.st_mode)
or stat.S_IMODE(st.st_mode) & badwritebits):
return False
while True:
path = os.path.dirname(path)
# Not necessary to check for ENOENT; if we got here at all,
# the entire chain of parent dirs must exist
st = os.stat(path)
if (st.st_uid not in owners
or not stat.S_ISDIR(st.st_mode)
or stat.S_IMODE(st.st_mode) & badwritebits):
return False
if path == '/': break
return True
def get_users_with_ssh_keys(all_users):
ssh_users = set()
already_processed_homes = {}
for login, (uid, home) in all_users.items():
if home in already_processed_homes:
if already_processed_homes[home]:
ssh_users.add(login)
continue
if (check_ssh_auth_perms(home + "/.ssh/authorized_keys", uid)
or check_ssh_auth_perms(home + "/.ssh/authorized_keys2", uid)):
already_processed_homes[home] = True
ssh_users.add(login)
else:
already_processed_homes[home] = False
return ssh_users
def get_users_with_possible_passwords():
pw_users = set()
with open("/etc/shadow", "rt") as sf:
for line in sf:
login, phash, chg, mina, maxa, warn, inact, expir, res \
= line.split(':')
if not phash:
sys.stderr.write("*** Account '{!r}' has blank password\n"
.format(login))
if phash[0] != '*' and phash[0] != '!':
pw_users.add(login)
return pw_users
def main():
users = get_homes_and_uids_for_users_with_shells()
ssh_users = get_users_with_ssh_keys(users)
pw_users = get_users_with_possible_passwords()
active_users = set(users.keys()) & (ssh_users | pw_users)
for u in sorted(active_users):
sys.stdout.write(u + "\n")
main()
如果您必须担心网络身份验证服务(例如 NIS、LDAP、Kerberos)提供的帐户,情况会更加复杂。我不知道如何扩展这个答案来涵盖这些内容。