如何列出 Linux 中所有锁定的用户?

如何列出 Linux 中所有锁定的用户?

如何列出 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)提供的帐户,情况会更加复杂。我不知道如何扩展这个答案来涵盖这些内容。

相关内容