16 用户管理 #
16.1 各种帐户检查 #
16.1.1 未锁定的帐户 #
请务必锁定未用于登录的所有系统帐户和供应商帐户。要获取您系统中未锁定帐户的列表,您可以查找不含以 !
或 *
开头(在 /etc/shadow
文件中)的加密口令字符串的帐户。如果使用 passwd
-l
锁定帐户,将会在加密口令之前添加 !!
,以有效禁用该口令。如果使用 usermod
-L
锁定帐户,将会在加密口令之前添加 !
。默认情况下,许多系统和共享帐户通常都由口令字段中的 *
或 !!
进行锁定,这会让加密口令变为无效字符串。因此,要获取所有未锁定(可加密)帐户的列表,请运行以下命令:
root #
egrep -v ':\*|:\!' /etc/shadow | awk -F: '{print $1}'
同时确保所有帐户在 /etc/passwd
中的口令字段中都有一个 x
。以下命令列出口令字段中没有 x
的所有帐户:
root #
grep -v ':x:' /etc/passwd
口令字段中的 x
表示该口令已阴影化,例如,需要在 /etc/shadow
文件中查找加密口令。如果 /etc/passwd
中的口令字段为空,则系统将不会查找阴影文件,并且不会在出现登录提示时提示用户提供口令。
16.1.2 未使用的帐户 #
应从系统中去除未被用户、应用程序、系统或守护程序使用的所有系统帐户或供应商帐户。您可以使用以下命令,查找特定帐户是否拥有任何文件:
root #
find / -path /proc -prune -o -user ACCOUNT -ls
在此示例中,-prune
选项用于跳过 /proc 文件系统。如果您确定可以删除某个帐户,可以使用以下命令去除该帐户:
root #
userdel -r ACCOUNT
如果没有 -r
选项,userdel
将不会删除用户的主目录和邮件假脱机目录 (/var/spool/mail/USER
)。请注意,许多系统帐户都没有主目录。
16.2 启用口令时效 #
口令失效是一种普遍采用的最佳实践,但对于一些系统帐户和共享帐户(例如 Oracle)而言,可能需要将其排除。如果应用程序帐户失效,这些帐户的失效口令可能会导致系统服务中断。
通常情况下,应针对系统帐户和共享帐户的口令更改规则/程序制定相应的公司政策。但常规用户帐户口令应该会自动失效。以下示例显示如何针对各个用户帐户设置口令失效。
使用 useradd
命令创建新帐户时,可以使用下表中的文件和参数。将在 /etc/shadow
文件中为每个用户帐户储存此类设置。如果使用 YaST 工具( )添加用户,则会为每个用户提供该设置。下面是各种不同的设置,其中一些也可能是系统范围的设置(例如,/etc/login.defs
和 /etc/default/useradd
的修改):
|
|
口令保持有效的最大天数。 |
|
|
自上次更改到用户下次可更改口令之前的最小天数。 |
|
|
从上次更改口令到下次提醒更改口令间隔的天数。 |
|
|
口令失效后帐户处于禁用状态的天数。 |
|
|
帐户失效日期(采用 YYYY-MM-DD 格式)。 |
在这些修改之前创建的用户不受影响。
请确保在 /etc/login.defs
和 /etc/default/useradd
文件中更改上述参数。审阅 /etc/shadow
文件将显示在添加用户之后如何储存这些设置。
要创建新用户帐户,请执行以下命令:
root #
useradd -c "TEST_USER" -g USERS TEST
-g
选项指定此帐户的主组:
root #
id TEST
uid=509(test) gid=100(users) groups=100(users)
为 /etc/shadow
文件中的测试用户在 /etc/login.defs
和 /etc/default/useradd
中记录的设置如下所示:
root #
grep TEST /etc/shadow
test:!!:12742:7:60:7:14::
可使用 chage
命令随时修改口令时效。要禁用系统帐户和共享帐户的口令时效,您可以运行以下 chage
命令:
root #
chage -M -1 SYSTEM_ACCOUNT_NAME
要获取口令失效信息,请运行:
root #
chage -l SYSTEM_ACCOUNT_NAME
例如:
root #
chage -l TEST
Minimum: 7
Maximum: 60
Warning: 7
Inactive: 14
Last Change: Jan 11, 2015
Password Expires: Mar 12, 2015
Password Inactive: Mar 26, 2015
Account Expires: Never
16.3 实施更强的口令 #
在经审计的系统上,请务必限制用户使用可被轻松破解的简单口令。可以将复杂的口令记下来,只要妥善保管即可。有些人主张通过强口令来保护您免受字典攻击,并可通过数次失败尝试之后锁定帐户来防御此类攻击。但此方法并非始终有效。如果进行此类设置,锁定系统帐户可能会使应用程序和系统服务中断,这会产生另一个同样棘手的问题 — 拒绝服务攻击。
但无论怎样,实施有效的口令管理安全措施都很重要。大多数公司会要求口令至少包含一个数字、一个小写字母和一个大写字母。虽然政策各不相同,但要在口令强度/复杂性和管理难易度之间保持平衡可能并不容易。
16.4 使用 PAM 进行口令和登录管理 #
Linux-PAM(适用于 Linux 的可插入身份验证模块)是一组共享库,可让本地系统管理员选择应用程序该如何对用户进行身份验证。
强烈建议您熟悉 PAM 的功能以及如何利用此体系结构为某个环境提供最佳身份验证设置。您可以完成此配置一次并在所有系统中实施此配置(标准),也可以针对各个主机进行增强(增强安全性 — 按主机/服务/应用程序进行增强)。重点了解该体系结构的灵活性。
要了解有关 PAM 体系结构的详细信息,请参见 /usr/share/doc/packages/pam
目录中的 PAM 文档(提供多种格式)。
下面讨论的是如何修改默认 PAM 堆栈的示例(特别是围绕口令政策展开),例如口令强度、口令重复使用和帐户锁定。虽然只涉及了少数几种可能性,但它们是一个良好的开端,向您展示了 PAM 的灵活性。
pam-config
限制
pam-config
工具可用于配置包含全局选项的 common-{account,auth,password,session} PAM 配置文件。这些文件包含以下注释:
# This file is autogenerated by pam-config. All changes # will be overwritten.
个别服务文件(例如 login、password、sshd
和 su
)必须直接编辑。您可以选择直接编辑所有文件,而不使用 pam-config
,虽然 pam-config
包含转换较旧配置、更新当前配置和健全性检查等有用功能。有关详细信息,请参见 man 8 pam-config
。
16.4.1 口令强度 #
SUSE Linux Enterprise Server 可利用 pam_cracklib
库测试弱口令,并在确定口令明显较弱时建议使用较强的口令。以下参数示例可能属于公司口令策略的一部分,或者由于审计约束而需要的某些设置。
PAM 库遵循定义的流程。通常,设计完美堆栈的最佳方式是考虑所有要求和策略并绘制流程图。
|
|
口令的最小长度为 8 |
|
|
小写字母的最少数量为 1 |
|
|
大写字母的最少数量为 1 |
|
|
数字的最少数量为 1 |
|
|
其他字符的最少数量为 1 |
要设置这些口令限制,请使用 pam-config
工具指定您要配置的参数。例如,可使用如下命令修改最小长度参数:
tux >
sudo
pam-config -a --cracklib-minlen=8 --cracklib-retry=3 \ --cracklib-lcredit=-1 --cracklib-ucredit=-1 --cracklib-dcredit=-1 \ --cracklib-ocredit=-1 --cracklib
现在校验新口令限制是否适用于新口令。登录非 root 帐户并使用 passwd
命令更改口令。请注意,如果您在 root 下运行 passwd
命令,则不会强制执行上述要求。
16.4.2 限制使用先前的口令 #
pam_pwhistory 模块可用于配置无法重复使用的先前口令数量。以下命令可在系统上实施口令限制,如此至少六个月内无法重复使用某个口令。
tux >
sudo
pam-config -a --pwhistory --pwhistory-remember=26
回想一下,在第 16.2 节 “启用口令时效”中我们将 PASS_MIN_DAYS
设置为 7
,该选项指定了两次口令更改之间的最少天数。因此,如果 pam_unix
配置为记住 26
个口令,则至少六个月(26*7 天)内无法重复使用先前曾使用过的口令。
pam-config
命令生成的 PAM 配置 (/etc/pam.d/common-auth
) 如下所示:
auth required pam_env.so auth required pam_unix.so try_first_pass account required pam_unix.so try_first_pass password requisit pam_cracklib.so password required pam_pwhistory.so remember=26 password optional pam_gnome_keyring.so use_authtok password required pam_unix.so use_authtok nullok shadow try_first_pass session required pam_limits.so session required pam_unix.so try_first_pass session optional pam_umask.so
16.4.3 登录失败次数太多后锁定用户帐户 #
在到达所定义的 ssh、login、su 或 sudo 失败尝试次数后锁定帐户是一种常见的安全做法。但如果应用程序、管理员或 root 用户被锁定,则可能会导致服务中断。实际上,如果故意大量制造登录失败,就很容易会导致拒绝服务攻击。幸好可以直接通过 PAM 来控制此情况。
默认情况下,PAM 允许所有 root 登录。使用 pam_tally2
可控制所有其他用户(包括人类用户和系统用户)的失败登录行为。将下面一行添加到 /etc/pam.d/login
上方可在六次登录失败之后锁定所有用户(root 用户除外),并在十分钟后自动解锁帐户:
auth required pam_tally2.so deny=6 unlock_time=600
下面是一个完整的 /etc/pam.d/login
文件示例:
#%PAM-1.0 auth requisite pam_nologin.so auth include common-auth auth required pam_tally2.so deny=6 unlock_time=600 account include common-account account required pam_tally2.so password include common-password session required pam_loginuid.so session include common-session #session optional pam_lastlog.so nowtmp showfailed session optional pam_mail.so standard
您也可以锁定 root 用户,不过显然您必须非常确定要执行此操作:
auth required pam_tally2.so deny=6 even_deny_root unlock_time=600
您可以为 root 用户定义不同的锁定时间:
auth required pam_tally2.so deny=6 root_unlock_time=120 unlock_time=600
如果您希望必须由管理员来解锁帐户,请不要使用 unlock_time
选项。下面两个示例命令显示失败的登录尝试次数以及如何锁定用户帐户:
root #
pam_tally2 -u username
Login Failures Latest failure From username 6 12/17/19 13:49:43 pts/1root #
pam_tally2 -r -u username
尝试访问的默认位置记录在 /var/log/tallylog
中。
如果用户在登录超时失效后或在管理员重设置其帐户之后成功登录,计数器将重设置为 0。
配置其他登录服务,以在 /etc/pam.d/
下其各自的配置文件中使用 pam_tally2
:sshd、su、sudo、sudo-i
和 su-l
。
16.5 限制 root
登录 #
默认情况下,为 root
用户分配了口令,并且该用户可以使用各种方法进行登录 — 例如,在本地终端上、在图形会话中,或者通过 SSH 远程登录。应尽可能限制使用这些方法登录。应避免共享使用 root 帐户。而是由各个管理员使用 su
或 sudo
等工具(有关详细信息,请键入 man 1 su
或 man 8 sudo
)获取提升的特权。如此可将 root
登录与特定用户相关联。同时还可增加了另一层安全保护;要获得完全的 root 访问权限,需要破解的不仅仅是 root
口令,而是 root
口令以及管理员普通帐户的口令。本节说明如何限制在不同级别系统上的直接 root 登录。
16.5.1 限制本地文本控制台登录 #
TTY 设备通过控制台提供文本模式的系统访问权限。对于桌面系统,通过本地键盘进行访问;如果是服务器系统,则通过连接到 KVM 交换机或远程管理卡(例如 ILO 和 DRAC)的输入设备进行访问。Linux 默认会提供 6 个不同的控制台,在文本模式下运行时,可通过组合键 Alt–F1 到 Alt–F6 切换它们;在图形会话中运行时,可通过组合键 Ctrl–Alt–F1 到 Ctrl–Alt–F6 进行切换。关联的终端设备命名为 tty1
至 tty6
。
下面的步骤限制对第一个 TTY 的 root 访问。此访问方法仅作为系统的紧急访问方式,绝不应将其用于日常系统管理任务。
此处显示的步骤根据 PC 体系结构(x86 和 AMD64/Intel 64)进行定制。在 POWER 等体系结构上,可以使用 tty1
以外的其他终端设备名称。请小心不要因为指定了错误的终端设备名称而将您自己完全锁定。您可以通过运行 tty
命令确定当前登录的终端的设备名称。请注意不要在虚拟终端(例如通过 SSH)或图形会话(设备名称 /dev/pts/N
)中执行此操作,而只通过实际登录终端(可通过 Alt–FN 访问)进行操作。
请确保 PAM 堆栈配置文件
/etc/pam.d/login
包含auth
块中的pam_securetty
模块:auth requisite pam_nologin.so auth [user_unknown=ignore success=ok ignore=ignore auth_err=die default=bad] pam_securetty.so noconsole auth include common-auth
这样系统会在本地控制台处理身份验证期间包含
pam_securetty
模块,该模块会将root
限制为仅可在文件/etc/securetty
中列出的 TTY 设备上登录。去除
/etc/securetty
中除这一项外的其他所有项。这将限制对 TTY 设备的 root 访问。# # This file contains the device names of tty lines (one per line, # without leading /dev/) on which root is allowed to login. # tty1
检查是否会拒绝
root
登录其他终端。应立即拒绝在tty2
等终端上登录,甚至无需查询帐户口令。同时确保您仍可以成功登录tty1
,因而不会将root
完全锁定在系统之外。
请不要将 pam_securetty
模块添加到 /etc/pam.d/common-auth
文件中。这将破坏 su
和 sudo
命令,因为这些工具也会拒绝 root
身份验证。
这些配置更改还将导致拒绝在 /dev/ttyS0
等串行控制台上进行 root 登录。如果您需要此类用例,则需要在 /etc/securetty
文件中额外列出相应的 TTY 设备。
16.5.2 限制图形会话登录 #
要提高您服务器的安全性,请完全避免使用图形环境。通常,图形程序不会设计为以 root
身份运行,因此与控制台程序相比更可能包含安全问题。如果您需要图形登录,请使用非 root
登录。配置您的系统,禁止通过 root
登录图形会话。
为了防止通过 root
登录图形会话,您可以采用第 16.5.1 节 “限制本地文本控制台登录”中概述的相同基本步骤。只需将 pam_securetty
模块添加到属于显示管理器的 PAM 堆栈文件 — 例如,GDM 的 /etc/pam.d/gdm
。图形会话还会在 TTY 设备上运行:默认为 tty7
。因此,如果您限制 root
登录到 tty1
,将拒绝通过 root
登录图形会话。
16.5.3 限制 SSH 登录 #
默认情况下,还允许 root
用户通过 SSH 网络协议远程登录计算机(如果 SSH 端口未被防火墙阻止)。要限制此类登录,请对 OpenSSH 配置进行以下更改:
编辑
/etc/ssh/sshd_config
并调整以下参数:PermitRootLogin no
重启动
sshd
服务以使更改生效:systemctl restart sshd.service
对于 OpenSSH,不适合使用 PAM pam_securetty
模块,因为在授权期间并非所有 SSH 登录都会通过 PAM 堆栈进行(例如使用 SSH 公共密钥身份验证时)。此外,攻击者能够区分错误口令和策略只能在稍后予以拒绝的成功登录。
16.6 为交互式外壳会话设置无活动超时 #
最好在一段无活动时间之后终止交互式外壳会话。例如,通过此方式可以阻止打开的无人监管会话或避免浪费系统资源。
默认情况下,外壳没有无活动超时。如此当外壳处于打开状态且在几天甚至几年内未被使用时,也不会有任何反应。不过,您可以将大多数外壳配置为在一段时间后自动终止空闲会话。以下示例显示如何为一些常见类型的外壳设置无活动超时。
可仅为登录外壳配置无活动超时,也可以为所有交互式外壳配置无活动超时。在后一种情况下,将针对每个外壳实例单独运行无活动超时。这意味着超时将会累积。当启动子外壳时,会为子外壳开始新的超时,并且仅在此超时过后,才会继续运行父外壳的超时。
下表包含 SUSE Linux Enterprise Server 随附的常见外壳选集的配置详细信息:
软件包 | 外壳特点 | 外壳变量 | 时间单位 | 只读设置 | 配置路径(仅登录外壳) | 配置路径(所有外壳) |
---|---|---|---|---|---|---|
|
|
| 秒 |
|
|
|
|
|
| 秒 |
|
|
|
|
|
| 分钟 |
|
|
|
|
|
| 秒 |
|
|
|
每个列出的外壳支持使用一个内部超时外壳变量,可将该变量设置为某个特定时间值以触发无活动超时。如果您要防止用户覆盖超时设置,可以将相应的外壳超时变量标记为只读。上表中还提供了相应的变量声明语法。
此功能仅有助于避免因用户疏忽或遵循不安全做法而导致的风险。而无法防范恶意用户。超时只适用于外壳的交互式等待状态。恶意用户总是能找到绕过超时的方法,使得无论在任何情况下,都可以让其会话保持打开状态。
要配置无活动超时,需要为每个外壳的启动脚本都添加匹配的超时变量声明。可仅为登录外壳使用一种路径,或为所有外壳使用一种路径,如表中所列。以下示例使用适合 bash
和 ksh
的路径和设置,设置了无法被用户覆盖的只读登录外壳超时。使用以下内容创建文件 /etc/profile.d/timeout.sh
:
# /etc/profile.d/timeout.sh for SUSE Linux # # Timeout in seconds until the bash/ksh session is terminated # in case of inactivity. # 24h = 86400 sec readonly TMOUT=86400
建议使用 screen
工具在注销前分离会话。screen
会话不会终止,一旦有需要便可重新挂接。可以在未注销的情况下锁定活动会话(有关细节,请阅读 man screen
中的 Ctrl–a–x / lockscreen
)。
16.7 防止意外拒绝服务 #
Linux 允许您对用户和组可以使用的系统资源量设置限制。如果因为程序中的 bug 导致用户和组耗尽太多资源(例如内存泄漏)、降低计算机速度,甚至使系统无法使用,此项设置也非常有用。错误的设置可能会允许程序使用过多资源,这可能会导致服务器无法响应新连接,甚至无法响应本地登录请求(例如,如果某个程序用掉主机上的所有可用文件句柄)。这也会成为一个安全问题,例如,如果允许某人用掉所有系统资源,将会导致拒绝服务攻击(无论是无意的还是更糟的恶意攻击)。设置用户和组的资源限制可能是一种有效的系统保护方法,具体视环境而定。
16.7.1 限制系统资源示例 #
以下示例演示了设置或限制 Oracle 用户帐户的系统资源使用的实际用法。有关系统资源设置列表,请参见 /etc/security/limits.conf
或 man limits.conf
。
Bash 等大多数外壳都会提供基于用户的各种资源控制(例如允许的打开文件描述符数量上限或最大进程数)。要检查外壳中的所有当前限制,请执行以下命令:
root #
ulimit -a
有关 Bash 外壳的 ulimit
的详细信息,请查看 Bash 手册页。
使用 SSH 会话时,设置“硬”限制和“软”限制可能不会起到预期的效果。要查看有效行为,可能需要以 root 身份登录,然后使用 su
命令切换到权限受限的身份(例如,在这些示例中为 Oracle
)。假设应用程序在引导过程中已自动启动,资源限制也应生效。如果通过 SSH 对资源限制进行的更改似乎未生效,可能需要将 /etc/ssh/sshd_config
中的 UsePrivilegeSeparation
设置为 no
,并重启动 SSH 守护程序 (systemctl restart sshd
)。但一般不建议这样做,因为这会降低系统安全性。
ssh
进行口令登录功能
您可以通过禁用 SSH 的口令身份验证来为服务器增加一定程度的安全性。请记住,您需要配置 SSH 密钥,否则无法访问服务器。要禁用口令登录,请在 /etc/ssh/sshd_config
中添加下面几行:
UseLogin no UsePAM no PasswordAuthentication no PubkeyAuthentication yes
在此示例中,可通过以 root
身份编辑 /etc/security/limits.conf
并进行以下更改,来更改用户 oracle
可使用的文件句柄数或打开的文件数:
oracle soft nofile 4096 oracle hard nofile 63536
第一行中的软限制定义了登录后 oracle
用户将拥有的文件句柄(打开的文件)数目限制。如果用户看到有关文件句柄用尽的错误消息,则可以执行以下命令,将此示例中所示的文件句柄数增加到硬限制(在此示例中为 63536):
root #
ulimit -n 63536
必要时,您可以设置更高的软限制和硬限制。
请务必合理利用 ulimit。允许用户的 nofile
的“硬”限制(相当于内核限制 (/proc/sys/fs/file-max
))是非常糟糕的设置!如果用户占用了所有可用文件句柄,系统将无法启动新的登录,因为它无法访问执行登录所需的 PAM 模块。
您还需要确保在 /etc/pam.d/common-auth
中全局配置 pam_limits
,或者针对以下文件中的 SSH、su、login 和 telnet 等个别服务进行配置:
/etc/pam.d/sshd (用于 SSH) |
/etc/pam.d/su (用于 su) |
/etc/pam.d/login (本地登录和 telnet) |
如果您不想为所有登录启用该配置,会有一个特定 PAM 模块读取 /etc/security/limits.conf
文件。PAM 配置指令中的项将如下所示:
session required /lib/security/pam_limits.so session required /lib/security/pam_unix.so
请务必注意,更改不会立即生效,需要新的登录会话:
root #
su - oracletux >
ulimit -n 4096
请注意,这些示例特定于 Bash 外壳;其他外壳的 ulimit
选项会有所不同。用户 oracle
的默认限制为 4096
。要将用户 oracle
可使用的文件句柄数增加至 63536
,请执行以下命令:
root #
su - oracletux >
ulimit -n 4096tux >
ulimit -n 63536tux >
ulimit -n 63536
要使其成为永久设置,需要向用户配置文件(~/.bashrc
或 ~/.profile
文件)添加设置 ulimit -n 63536
(仍是适用于 Bash),该配置文件为 SUSE Linux Enterprise Server 上的 Bash 外壳的用户启动文件(要校验外壳,请运行 echo $SHELL
)。为此,可以针对用户 oracle
的 Bash 外壳运行以下命令:
root #
su - oracletux >
cat >> ~oracle/.bash_profile << EOF ulimit -n 63536 EOF
16.8 显示登录标题 #
出于法律/审计政策原因,或者为了向用户提供安全说明,通常有必要在所有服务器上的登录屏幕上设置一个标题。
如果您想在用户登录文本型终端(例如,使用 SSH 或在本地控制台上)后列显登录标题,可以使用 /etc/motd
文件(motd = 当天的消息)。默认情况下,该文件存在于 SUSE Linux Enterprise Server 上,但是空文件。只需向适用的/组织所需的文件中添加内容。
请尽量将登录标题内容放在一个终端页面(或更少)中,如果一页容纳不下而需要滚动屏幕,会使阅读变得更加困难。
您也可以在用户登录文本型终端前列显登录标题。如果是本地控制台登录,您可以编辑 /etc/issue
文件,这会使标题在出现登录提示前显示。如果是通过 SSH 进行登录,您可以编辑 /etc/ssh/sshd_config
文件中的“Banner”参数,这会在出现 SSH 登录提示前相应地显示标题文本。
如果是通过 GDM 进行的图形登录,您可以遵循 GNOME 管理员指南设置登录标题。此外,您可以进行以下更改,以要求用户通过选择 或 来对法律标题进行确认。编辑 /etc/gdm/Xsession
文件,并在脚本开头添加下面几行:
if ! /usr/bin/gdialog --yesno '\nThis system is classified...\n' 10 10; then /usr/bin/gdialog --infobox 'Aborting login' exit 1; fi
需要将文本 This system is classified... 替换为所需的标题文本。请务必注意,此对话框不会阻止登录进行。有关 GDM 脚本的详细信息,请参见 GDM 管理员手册。
16.9 连接统计实用程序 #
下面是您可以用于获取有关用户登录的数据的命令列表:
who
:
列出当前登录的用户。
w
:
显示登录者及其执行的操作。
last
:
显示最近登录的用户列表,包括登录时间、注销时间、登录 IP 地址等。
lastb
:
与 last
相同(除了默认显示 /var/log/btmp
),包含所有无效登录尝试。
lastlog
:
此命令报告 /var/log/lastlog
中维护的数据,该文件是用户上次登录的记录。
ac
:
安装 acct
软件包之后提供。按每个用户或每天等条件列显连接时间(以小时为单位)。此命令读取 /var/log/wtmp
。
dump-utmp
:
将原始数据从 /var/run/utmp 或 /var/log/wtmp
转换为 ASCII 可分析格式。
此外,如果未运行任何日志记录工具,请检查 /var/log/messages
文件或 journalctl
的输出。有关 systemd
日记的详细信息,请参见第 17 章 “journalctl
:查询 systemd
日志”。