什么更新了 `/var/log/btmp`?如何停止它?

什么更新了 `/var/log/btmp`?如何停止它?

在提供答案之前,请先阅读问题直至结束。特别是我不想要的“解决方案”部分!

我有一台在公共 IP 地址上运行 SSH 的服务器。毫不奇怪,我看到很多登录尝试失败,但都成功登录/var/log/btmp。系统的哪个部分会记录这些消息,我该如何停止它?sshd 会btmp自行更新吗?还是它是一个 PAM 模块?

我在手册页中找到了禁用日志记录nowtmp的选项,我想知道这是否也会禁用,即使手册页没有这样说。pam_lastlogwtmpbtmp

我的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

我的解决方案(最简单的)是执行以下操作:

  1. rm -r /var/log/btmp*
  2. 再次确保 /etc/logrotate.conf 或 /etc/logrotate.d 下的任何配置文件中没有任何引用 /var/log/btmp 的内容
  3. ln -s /dev/null /var/log/btmp

如果你想进一步深入系统,根据我从网络搜索中得出的结论,systemd 是负责任的。有一个配置文件,你可能(我不作任何保证、担保,使用风险自负等)能够更改它以防止创建此文件。

  1. rm -f /var/log/btmp*
  2. 再次确保 /etc/logrotate.conf 或 /etc/logrotate.d 下的任何配置文件中没有任何引用 /var/log/btmp 的内容
  3. 编辑文件 /usr/lib/tmpfiles.d/var.conf 以删除 /var/log/btmp 的创建。
  4. 验证 /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

也许我错过了什么,但似乎btmpLinux 版本的 OpenSSH 总是会记录失败的尝试。

相关内容