[Share Experiences] Deepin Linux 的 pam_deepin_authentication 验证登录模块在默默守护
Tofloor
poster avatar
littlebat
deepin
2021-12-23 19:35
Author

(转自:学习日记 https://www.learndiary.com/2021/12/deepin-linux-auth-mod/ )

一、起因
前些日子,我在一台装有最新版 Deepin 20.3 Linux 的系统添加了一个名为 test 的测试账号。用这个账号在 lightdm 登录界面却不能登录,提示“请1440分钟分再试”。新建用户竟然不能登录,难道是 Deepin 又一个 bug 来了?由此开启我的探索之旅。

二、排查原因
因为我需要从远程使用这台 Deepin 系统,于是我开了公网 ssh 端口,并修改了默认的 22 为其它的端口。
排查一个问题先从日志着手,于是,我查看了用户异常登录的相关日志。分别是 /var/log/btmp 和 /var/log/auth.log
首先查看 /var/log/btmp,记录失败的登录尝试信息,默认由lastb命令查看。执行:sudo lastb -f btmp | less 简单翻阅一下,就可以发现大量失败的登录信息,尝试用不同的用户名登录,主要来自几个IP,可知是来自这几个IP的×××登录,因为是远程,那就肯定是我的 ssh 端口被他们扫描到了,并尝试通过 ssh 端口来登录。示例行如下:
weijiyu ssh:notty 139.59.212.238 Mon Nov 29 10:17 – 10:17 (00:00)
下面我们排序筛选一下都是些什么用户名和IP。

sudo lastb -f btmp | awk '{print $1}'| sort | uniq | less # 查看
sudo lastb -f btmp | awk '{print $1}'| sort | uniq | wc -l # 尝试过的不同的用户名,11月一共 9080 条
sudo lastb -f btmp | awk '{print $1}'| grep '^test$' | wc -l # 用 test 用户名11月尝试了 239次
sudo lastb -f btmp | awk '{print $3}'| sort | uniq | grep '[0-9].*'  #尝试登录的 IP,11月一共5个不同的IP

可以看到,用户名里面有不少中文名字的汉字拼音,所以,如果你是用自己名字的汉语拼音作用户名,密码又简单的话,那么你就要注意了。

查了一下,这5个不同的IP都是 vps 提供商 digital ocean 分布几个国家的IP。
然后查看 /var/log/auth.log,是详细记录登录信息和过程的日志文件。
比如,下面是一次 test 用户完整的登录过程记录,系统中本来是没有这个用户名的。

Nov 18 11:46:47 e5450 sshd[27311]: Invalid user test from 165.232.118.21 port 46408
Nov 18 11:46:47 e5450 sshd[27311]: pam_deepin_authentication(sshd:auth): run getpwnam failed: Success
Nov 18 11:46:47 e5450 sshd[27311]: pam_deepin_authentication(sshd:auth): Failed to call 'FindUserByName': com.deepin.DBus.Error.Unnamed, Invalid username: test
Nov 18 11:46:47 e5450 sshd[27311]: pam_deepin_authentication(sshd:auth): IsMFA: '0', Username: 'test'
Nov 18 11:46:47 e5450 sshd[27311]: pam_deepin_authentication(sshd:auth): 请1318分钟后再试
Nov 18 11:46:47 e5450 sshd[27311]: Failed password for invalid user test from 165.232.118.21 port 46408 ssh2
Nov 18 11:46:47 e5450 sshd[27311]: Received disconnect from 165.232.118.21 port 46408:11:Normal Shutdown, Thank you for playing [preauth]
Nov 18 11:46:47 e5450 sshd[27311]: Disconnected from invalid user test 165.232.118.21 port 6408 [preauth]

可以看出这个test用户连接了 ssh 服务器,中间登录过程被 pam_deepin_authentication 验证模块处理,使 test 用户只能 1318分钟后再尝试登录。
我测试了一下,即使这个用户在系统中存在,只要是计时锁定中,这时输入正确的密码也是无效的。必须等待锁定的时间,再输入正确的密码才能登录。

三、 Deepin 的 pam_deepin_authentication 模块
从上面的 /var/log/auth.log 信息可以看出。挡住无效登录并计数锁定的模块是一个名为 pam_deepin_authentication 的模块。经研究,这个模块属于 deepin-authenticate 包。
通过 dpkg -L deepin-authenticate 可以查到此包安装的所有文件,可以查到有几个配置文件是:
/etc/pam.d/deepin_pam_unix
/var/lib/deepin/authenticate/config.json
/etc/deepin-authenticate/pam-tool/pam-tool.conf
其中,/var/lib/deepin/authenticate/config.json 定义登录失败多少次锁定,锁定多久的策略。

另外,通过 apt-get source deepin-authenticate 下载源码包,在源文件 service/authenticate/limit.go 里详细注释了配置文件各参数的含义。如下:

type LimitConfig struct {
Type                   string
UnlockSecs             int   // 超出认证失败次数后,解除锁定需要等待的时间(秒数),如果 <0 则永久锁定。
MaxTries               int   // 认证失败几次后拒绝, 如果 == 0 则不限制
DynamicLimit           bool  // 是否是动态锁定
DynamicLimitUnlockSecs []int // 动态锁定时间,可随次数变化,次数起始为 MaxTries ,第一个元素x含义为,失败 MaxTries 之后,锁定 x 秒
}

四、Deepin Linux 的努力
从上可以看见,在我不知不觉中,Deepin Linux 已经为我挡住了一波又一波的 ssh ××××攻击。我查了下,在 Deepin 的上游操作系统 Debian 中默认是没有这个功能的,需要自己通过 pam_tally.so 或pam_tally2.so 之类来手动配置实现,而 deepin 已经帮我们配置了较通用的效果。

另外,作为国内的国际化发行版,我看他们源码有详细的注释,不过是中文的。这说明,注释认真,是认真在做产品。也说明,可能国际化的参与还有待提高。

Deepin Linux 在背后作了很多工作,感谢 deepin linux 为大家奉献了桌面操作系统的一个有了一定份量的可选项。

Reply Favorite View the author
All Replies
lv36
deepin
2021-12-23 20:03
#1

👍

Reply View the author
jjcui8595
Moderator
2021-12-23 20:29
#2

为deepin点赞

Reply View the author
shalling
Deepin Wiki Editor
2021-12-29 03:29
#3

为deepin点赞,为作者点赞,好的产品更需要好的用户

Reply View the author
APU
deepin
2023-12-25 07:36
#4

deepin好样的
我骄傲

Reply View the author