在提供答案之前,请先阅读问题直至结束。特别是我不想要的“解决方案”部分!
我有一台在公共 IP 地址上运行 SSH 的服务器。毫不奇怪,我看到很多登录尝试失败,但都成功登录/var/log/btmp
。系统的哪个部分会记录这些消息,我该如何停止它?sshd 会btmp
自行更新吗?还是它是一个 PAM 模块?
我在手册页中找到了禁用日志记录nowtmp
的选项,我想知道这是否也会禁用,即使手册页没有这样说。pam_lastlog
wtmp
btmp
我的sshd_config
是:
Subsystem sftp /usr/lib64/misc/sftp-server
HostbasedAuthentication no
KbdInteractiveAuthentication no
PasswordAuthentication no
PubkeyAuthentication yes
PermitRootLogin no
LogLevel ERROR
UsePAM yes
PrintMotd no
PrintLastLog no
AcceptEnv LANG LC_ALL LC_COLLATE LC_CTYPE LC_MESSAGES LC_MONETARY LC_NUMERIC LC_TIME LANGUAGE LC_ADDRESS LC_IDENTIFICATION LC_MEASUREMENT LC_NAME LC_PAPER LC_TELEPHONE
AcceptEnv COLORTERM
启用 PAM 是我的发行版的默认设置,我想保留它,因为有几个 PAM 模块在登录期间执行相关操作(pam_systemd 和 pam_limits 强制执行某些用户限制)。
使用的PAM模块列表:
server ~ # cat /etc/pam.d/* | egrep -o -e 'pam_.*\.so' | sort | uniq
pam_access.so
pam_cap.so
pam_deny.so
pam_env.so
pam_faillock.so
pam_lastlog.so
pam_limits.so
pam_loginuid.so
pam_mail.so
pam_motd.so
pam_nologin.so
pam_passwdqc.so
pam_permit.so
pam_rootok.so
pam_shells.so
pam_systemd.so
pam_time.so
pam_unix.so
pam_wheel.so
pam_xauth.so
此外,我在 中/etc/login.defs
进行 grepping 时发现了以下代码片段:[uwb]tmp
/etc
#
# Enable logging and display of /var/log/lastlog login(1) time info.
#
# NOTE: This setting should be configured via /etc/pam.d/ and not in this file.
#LASTLOG_ENAB yes
#
# If defined, login(1) failures will be logged here in a utmp format.
# last(1), when invoked as lastb(1), will read /var/log/btmp, so...
#
# NOTE: This setting should be configured via /etc/pam.d/ and not in this file.
#FTMP_FILE /var/log/btmp
显然,配置指令是不是已定义,但已注释掉。遗憾的是,注释并未说明应配置哪个 PAM 模块。
我不寻求的“解决方案”:
btmp
安装 logrotate 并定期轮换btmp
使用 cron 任务或类似程序定期删除或清除,例如echo -n > /var/log/btmp
- 使用 fail2ban 或其他工具暂时阻止这些 IP,以减少失败尝试的次数,从而减少日志数据量
- 出于与上一点相同的原因,将 SSH 移至另一个端口
- 通过 iptables 限制允许的源 IP(因为我不使用固定源 IP)
- 完全禁用 PAM(因为需要某些模块)
- 任何其他解决方法
我正在寻找一个真正的解决方案,首先停止记录失败的尝试。如果可能的话,我想保留 、 和 中过去和当前成功登录的记录/var/log/lastlog
, /var/log/utmp
但这/var/log/wtmp
不是必须的。
答案1
我的解决方案(最简单的)是执行以下操作:
- rm -r /var/log/btmp*
- 再次确保 /etc/logrotate.conf 或 /etc/logrotate.d 下的任何配置文件中没有任何引用 /var/log/btmp 的内容
- ln -s /dev/null /var/log/btmp
如果你想进一步深入系统,根据我从网络搜索中得出的结论,systemd 是负责任的。有一个配置文件,你可能(我不作任何保证、担保,使用风险自负等)能够更改它以防止创建此文件。
- rm -f /var/log/btmp*
- 再次确保 /etc/logrotate.conf 或 /etc/logrotate.d 下的任何配置文件中没有任何引用 /var/log/btmp 的内容
- 编辑文件 /usr/lib/tmpfiles.d/var.conf 以删除 /var/log/btmp 的创建。
- 验证 /var/log/btmp* 是否存在 5. 重新启动以验证更改
答案2
经过一番调查,我断定我想做的事情根本不可能实现。日志是由 OpenSSH 本身创建的,似乎没有配置选项可以禁用该行为。
我看了一下 OpenSSH 9.5 的源代码。
文件configure.ac
检查 OpenSSH 是否正在通过 为 Linux 编译case $host
。该案例*-*-linux*
定义了 C 宏USE_BTMP
。
USE_BTMP
如果设置了C 宏,则该文件defines.h
定义该 C 宏CUSTOM_FAILED_LOGIN
。
在文件中,auth2.c
函数userauth_finish
总是无条件调用该函数auth_log
。
在文件中,auth.c
函数auth_log
总是在尝试失败时调用该函数record_failed_login
。函数调用由 C 宏保护CUSTOM_FAILED_LOGIN
,但这已定义(见上文)。此函数调用被编译到 Linux 版本中。除此之外,CUSTOM_FAILED_LOGIN
没有其他条件。特别是,似乎不依赖于可以在运行时设置的任何配置。
最终,在文件中loginrec.c
该函数record_failed_login
会更新btmp
。
也许我错过了什么,但似乎btmp
Linux 版本的 OpenSSH 总是会记录失败的尝试。