PAM03 — 身份认证的案例

前言

我们前面介绍了 PAM 中的概念、术语以及相关的配置文件,接下来看看 PAM 在实际使用过程中的一些认证案例。

密码复杂度要求

要求:对于普通用户(UID>=1000),更改密码时要求至少10位,必须至少一个数字、至少一个大写字母、至少一个小写字母、至少一个特殊字符,用户变更自己的密码时只允许重试3次。

Shell > vim /etc/pam.d/system-auth
...
password requisite  pam_pwquality.so  try_first_pass  local_users_only  retry=3  authtok_type=  minlen=10  dcredit=-1  lcredit=-1  ucredit=-1  ocredit=-1
...

在 GNU/Linux 中,Linux 内核通过 ID 号来识别每一个用户和用户组,ID 号类似用户或用户组的身份证。针对 uid 范围的不同,用户被划分为三类:

  1. 超级用户 – uid=0,在终端提示符上以 # 来显示
  2. 伪用户(系统用户) – 范围为 [1,999]。某些命令或程序会将系统用户限制在 [201,999]
  3. 普通用户 – uid 大于等于 1000 即普通用户,在终端提示符上以 $ 显示。某些命令或程序会将 uid 限制在一个范围,例如 useradd 命令中普通用户的 uid 的范围为 [1000,60000]

我没有添加 enforce_for_root 这个模块参数,表示密码的复杂度对 root 不生效。

Shell > id
uid=0(root) gid=0(root) groups=0(root)

Shell > whoami
root

Shell > useradd -u 3000 pam-user

# 若使用 root 用户对 pam-user 更新密码,则会忽略密码复杂度
## 如果密码更新为 123,虽然会有提示文本,但还是允许通过
Shell > passwd pam-user
Changing password for user pam-user.
New password:
BAD PASSWORD: The password contains less than 1 uppercase letters
Retype new password:
passwd: all authentication tokens updated successfully.

但如果是 pam-user 用户本身更新密码,则会严格遵守密码的安全策略。例如设置密码为 400!@GooBing.

Shell > su - pam-user

Shell(pam-user) > passwd
Changing password for user pam-user.
Current password: 
New password: 
Retype new password: 
passwd: all authentication tokens updated successfully.

任何不满足密码复杂度的密码都会请求失败:

Shell(pam-user) > passwd
Changing password for user pam-user.
Current password:
New password:
BAD PASSWORD: The password contains less than 1 uppercase letters
New password:
BAD PASSWORD: The password contains less than 1 digits
New password:
BAD PASSWORD: The password contains less than 1 non-alphanumeric characters
passwd: Have exhausted maximum number of retries for service

Shell(pam-user) >

限制 ssh 的密码尝试次数并锁定账号

要求:当用户使用 ssh 远程登录时,在 900 秒内密码输入错误 3 次后进行锁定,锁定时间为 180 秒

先看看 pam_faillock.so 模块的模块参数:

  • preauth – 预先授权。在要求输入用户凭据的模块(例如密码)之前必须使用 preauth 参数。
  • authfail – 授权失败
  • authsucc – 授权成功
  • silent – 不要打印信息性消息
  • deny=n – 如果登录用户在最近间隔的时间内连续登录失败的次数超过n,会被拒绝访问。默认值为3
  • audit – 如果找不到用户,将把用户名记录到系统日志中。
  • even_deny_root – 锁定账号的效果对 root 也生效
  • root_unlock_time=n – 锁定 root 账户的时间,如果未定义,则使用 unlock_time 的值
  • unlock_time=n – 锁定账户的时间,以秒为单位,默认值为600。超过定义的时间,账户自动解锁。
  • fail_interval=n – 定义登录失败的间隔时间,默认900,也就是说,十五分钟内登录失败都会被计数。

在不更改配置文件的默认情况下,ssh 的服务器端允许用户登录时重试 6 次,ssh 的客户端允许重试 3 次。我们可以通过手册页看到:

Shell > man 5 sshd_config
...
MaxAuthTries
            Specifies the maximum number of authentication attempts permitted per connection.  Once the number of failures reaches half this value, additional failures are logged. The default is 6.
...

Shell > man 5 ssh_config
...
NumberOfPasswordPrompts
            Specifies the number of password prompts before giving up.  The argument to this keyword must be an integer. The default is 3.
...

# 在 PowerShell 中指定密码的尝试次数
## 若不指定该选项,虽然 ssh 服务器端允许尝试的密码次数为 6 次,但 ssh 客户端默认的密码尝试次数只有 3 次
PS > ssh -p 22 -o NumberOfPasswordPrompts=6 [email protected]

先查看 sshd 策略文件是否包含了 password-auth 策略文件的内容:

Shell > cat /etc/pam.d/sshd
...
account    include      password-auth
...

修改 password-auth 文件:

Shell > vim /etc/pam.d/password-auth
auth        required      pam_faillock.so  preauth  silent audit even_deny_root deny=3  unlock_time=180  <<< 
auth        required      pam_env.so
auth        sufficient    pam_unix.so try_first_pass nullok
auth      [default=die]   pam_faillock.so  authfail  audit  even_deny_root  deny=3 unlock_time=180  <<< 
auth        required      pam_deny.so

account     required      pam_unix.so

password    requisite     pam_pwquality.so try_first_pass local_users_only retry=5 authtok_type=
password    sufficient    pam_unix.so try_first_pass use_authtok nullok sha512 shadow
password    required      pam_deny.so

session     optional      pam_keyinit.so revoke
session     required      pam_limits.so
-session     optional      pam_systemd.so
session     [success=1 default=ignore] pam_succeed_if.so service in crond quiet use_uid
session     required      pam_unix.so

使用 ssh 故意连续输错 3 次密码:

PS > ssh -p 22 [email protected]
[email protected]'s password:
Permission denied, please try again.
[email protected]'s password:
Permission denied, please try again.
[email protected]'s password:
[email protected]: Permission denied (publickey,gssapi-keyex,gssapi-with-mic,password).

再次连接时,即使您的用户密码正确也并不会通过认证,因为账户已经锁定了 180 秒。

可通过 faillock 命令查看到到具体的效果。也可以到 /var/log/secure 日志中查看到更加具体的信息。尝试失败后的相关数据存放在 /var/run/faillock/ 目录下,清空数据请使用 faillock --reset 命令。

Shell > faillock
root:
When                Type  Source                                           Valid
2025-02-16 10:21:01 RHOST 192.168.100.8                                        V
2025-02-16 10:21:06 RHOST 192.168.100.8                                        V
2025-02-16 10:21:11 RHOST 192.168.100.8                                        V

Shell > grep -i lock /var/log/secure
Feb 16 10:21:11 M1 sshd[1762]: pam_faillock(sshd:auth): Consecutive login failures for user root account temporarily locked

禁止修改密码为最近的三次

我们可以使用 pam_pwhistory.so 模块的 remember 参数记住用户的最近密码,即可达到禁止修改密码为最近的三次。该模块仅能在 password 链中使用。

请注意!只有用户密码修改成功后才能被 PAM 定义为「记住的密码」

我们仅需要修改 system-auth 文件即可:

Shell > vim /etc/pam.d/system-auth
#%PAM-1.0
# This file is auto-generated.
# User changes will be destroyed the next time authselect is run.
auth        required      pam_env.so
auth        sufficient    pam_unix.so try_first_pass nullok
auth        required      pam_deny.so

account     required      pam_unix.so

password    requisite     pam_pwquality.so try_first_pass local_users_only retry=3 authtok_type=
password    requisite     pam_pwhistory.so  remember=3 use_authtok  <<<<
password    sufficient    pam_unix.so try_first_pass use_authtok nullok sha512 shadow
password    required      pam_deny.so

session     optional      pam_keyinit.so revoke
session     required      pam_limits.so
-session     optional      pam_systemd.so
session     [success=1 default=ignore] pam_succeed_if.so service in crond quiet use_uid
session     required      pam_unix.so

用户密码修改成功后的记录会保存到 /etc/security/opasswd 中。

Shell > useradd -u 2500 hisuser

# 第一次修改密码
## 密码为 Flzx3QC<...>
Shell > passwd hisuser

# 第二次修改密码
## 密码为 Talk---5Ing,
Shell > passwd hisuser

# 第三次修改密码
## 密码为 u>=1000And
Shell > passwd hisuser

Shell > cat /etc/security/opasswd.old
hisuser:2500:2:!!,$6$VOHFPslBQ4BBDFJf$HqggjODYFGwBIJv6ZL7OTQOzSPIHt3J/6iCsl5SXhL0zo.wT2.83KK1jsHfcm2W22vBFgicU/0v/f3JLlUS7e.

Shell > cat /etc/security/opasswd
hisuser:2500:3:!!,$6$VOHFPslBQ4BBDFJf$HqggjODYFGwBIJv6ZL7OTQOzSPIHt3J/6iCsl5SXhL0zo.wT2.83KK1jsHfcm2W22vBFgicU/0v/f3JLlUS7e.,$6$dHWbr6x4WmV7Grf7$KXeREe5q5sVgnGoNC2Rbni3qGb4gT64yBTjL9S4vSfrXxexftee2KjUizeEOGBqEGGBIqBx7jyW4Vwg9jmg7n1

文件内容从左到右是用 ":" 分割的字段,依次表示:用户名、uid、序列号、密码密文。在第四个字段中,用 "," 分割并记录了历史的密码密文

请注意!上面修改密码的策略仅适用于普通用户修改其自身的密码,root(uid=0) 用户修改任何其他用户的密码不必遵守这样的策略。

若普通用户(uid>=1000)将密码变更为最近三次中的其中一个,则会输出这样的文本内容:

Password has been already used. Choose another.
Avatar photo

关于 陸風睿

GNU/Linux 从业者、开源爱好者、技术钻研者,撰写文档既是兴趣也是工作内容之一。Q - "281957576";WeChat - "jiulongxiaotianci"
用一杯咖啡支持我们,我们的每一篇[文档]都经过实际操作和精心打磨,而不是简单地从网上复制粘贴。期间投入了大量心血,只为能够真正帮助到您。
暂无评论

发送评论 编辑评论


				
|´・ω・)ノ
ヾ(≧∇≦*)ゝ
(☆ω☆)
(╯‵□′)╯︵┴─┴
 ̄﹃ ̄
(/ω\)
∠( ᐛ 」∠)_
(๑•̀ㅁ•́ฅ)
→_→
୧(๑•̀⌄•́๑)૭
٩(ˊᗜˋ*)و
(ノ°ο°)ノ
(´இ皿இ`)
⌇●﹏●⌇
(ฅ´ω`ฅ)
(╯°A°)╯︵○○○
φ( ̄∇ ̄o)
ヾ(´・ ・`。)ノ"
( ง ᵒ̌皿ᵒ̌)ง⁼³₌₃
(ó﹏ò。)
Σ(っ °Д °;)っ
( ,,´・ω・)ノ"(´っω・`。)
╮(╯▽╰)╭
o(*////▽////*)q
>﹏<
( ๑´•ω•) "(ㆆᴗㆆ)
😂
😀
😅
😊
🙂
🙃
😌
😍
😘
😜
😝
😏
😒
🙄
😳
😡
😔
😫
😱
😭
💩
👻
🙌
🖕
👍
👫
👬
👭
🌚
🌝
🙈
💊
😶
🙏
🍦
🍉
😣
Source: github.com/k4yt3x/flowerhd
颜文字
Emoji
小恐龙
花!
上一篇