在Debian系统上,默认情况下SSH通常允许root用户通过密码直接登录。这看似方便,实则是一个巨大的安全隐患。攻击者一旦通过暴力破解或字典攻击获取了root密码,就能直接拿到系统的最高控制权,且事后难以追溯具体是谁执行了哪些操作。解决这个问题的标准做法分两步:彻底禁止root用户的远程登录,强制使用普通用户通过sudo提权,并开启sudo的详细日志审计功能,让每一次特权操作都有据可查。
修改SSH配置禁止Root登录首先,我们需要修改SSH服务的配置文件。在开始之前,务必确保你至少有一个普通用户账号,并且该用户已经配置好sudo权限,否则一旦断开连接,你将无法再管理服务器。
使用你熟悉的文本编辑器打开SSH配置文件:
sudo vim /etc/ssh/sshd_config
在文件中找到以下这一行配置:
#PermitRootLogin prohibit-password
Debian 10及之后的版本,默认值通常是 prohibit-password,这意味着root用户只能通过密钥登录,密码登录已被禁止。但这还不够彻底。我们需要将其修改为:
PermitRootLogin no
这行配置的含义是,无论使用密码还是密钥,都完全禁止root用户通过SSH进行远程登录。如果文件中没有这一行,或者该行被注释掉了,直接添加或修改为上述内容即可。同时,建议检查一下是否禁止了密码认证,确保普通用户也尽量使用密钥登录:
PasswordAuthentication no
将该项设置为 no 后,所有用户都无法使用密码登录,只能使用SSH密钥。如果你的普通用户尚未配置好密钥,请先保持此项为 yes,等密钥配置完成后再修改。
保存文件后,必须重启SSH服务才能使配置生效:
sudo systemctl restart sshd
重启服务后,千万不要关闭当前的终端窗口。新开一个终端窗口,尝试使用root用户登录服务器,验证一下是否会被拒绝。同时,用普通用户测试能否正常登录,并执行 sudo -i 或 sudo su - 切换到root用户。确认一切正常后,再关闭原来的会话。这一步验证至关重要,能避免因配置错误导致自己被锁在服务器外面。
禁止root远程登录后,所有需要特权的操作都通过sudo来完成。Debian系统默认的sudo配置可能不够细致,我们需要对其进行加固和定制。使用 visudo 命令安全地编辑sudoers文件:
sudo visudo
在文件中,你可以看到类似这样的默认配置:
%sudo ALL=(ALL:ALL) ALL
这表示 sudo 用户组里的所有用户,可以在任何主机上以任何用户和任何组的身份执行任何命令。虽然方便,但权限过大。更安全的做法是遵循最小权限原则。比如,只授予运维人员管理服务的权限,而不是全部命令:
john ALL=(ALL) /usr/bin/systemctl restart nginx, /usr/bin/systemctl status nginx
上面的配置只允许用户 john 执行重启和查看Nginx状态的操作,其他sudo命令都会被拒绝。你还可以设置某些命令无需密码即可执行,但需要谨慎使用:
john ALL=(ALL) NOPASSWD: /usr/bin/systemctl status nginx
为了安全起见,建议保留默认要求输入密码的设置,这样即使普通用户账号被盗,攻击者也无法直接执行特权命令。
开启并配置Sudo日志审计仅仅禁止root登录并使用sudo还不够,必须要有完善的日志记录,才能在发生安全事件时进行追溯。默认情况下,sudo的执行记录会写入系统日志,但信息可能不够详细,且容易与其他日志混在一起。我们需要将其输出到独立的审计文件中。
首先,创建sudo日志的专用目录和文件:
sudo mkdir -p /var/log/sudo sudo touch /var/log/sudo/sudo.log sudo chmod 600 /var/log/sudo/sudo.log
接下来,配置rsyslog服务,将sudo相关的日志重定向到这个新文件。在 /etc/rsyslog.d/ 目录下创建一个新的配置文件:
sudo vim /etc/rsyslog.d/50-sudo.conf
写入以下内容:
local2.debug /var/log/sudo/sudo.log
这行配置指定了将设施名为 local2 且优先级为 debug 及以上的日志,全部写入我们刚刚创建的日志文件。
然后,还需要在sudoers文件中添加一行配置,告诉sudo将其日志发送到 local2 设施。再次执行 sudo visudo,在文件末尾添加:
Defaults logfile=/var/log/sudo/sudo.log Defaults !syslog
这两行的作用是,第一行指定sudo将日志直接写入文件,第二行禁止sudo再向系统默认的syslog发送日志,避免重复记录。不过,使用rsyslog进行集中管理是更推荐的做法,因此我们可以这样配置:
Defaults syslog=local2
添加这一行即可,无需指定logfile和禁用syslog。这样sudo日志会通过syslog机制,由rsyslog根据我们刚才定义的规则写入独立文件。
保存sudoers文件后,重启rsyslog服务:
sudo systemctl restart rsyslog
现在,执行一条sudo命令测试一下:
sudo ls /root
然后查看审计日志文件:
sudo cat /var/log/sudo/sudo.log
你应该能看到类似下面这样的详细记录,包含了时间、主机名、执行用户、切换到的用户以及具体执行的命令:
May 22 14:35:01 debian sudo: john : TTY=pts/0 ; PWD=/home/john ; USER=root ; COMMAND=/usr/bin/ls /root
这种程度的日志记录对于日常审计来说基本够用,但如果需要更精细的输入输出审计,也就是记录用户在sudo会话中具体敲击了哪些按键、看到了什么输出,就需要借助更强大的工具。
使用Sudo内置的I/O日志实现会话级审计sudo从1.8版本开始,内置了会话记录功能,可以将整个sudo会话的输入输出完整地记录下来,并以文件形式保存。这类似于一个针对特权操作的“屏幕录像机”。
要启用此功能,同样在sudoers文件中添加配置。执行 sudo visudo,添加或修改以下内容:
Defaults log_input, log_output
Defaults iolog_dir=/var/log/sudo-io/%{user}
Defaults log_host
这里逐行解释一下:
log_input 和 log_output 分别开启对用户输入和命令输出的记录。
iolog_dir 指定了日志文件的存放目录。使用 %{user} 变量可以为每个执行sudo的用户创建独立的子目录,便于管理。
log_host 会在日志目录名中加入主机名,这在管理多台服务器时非常有用。
配置完成后,创建对应的日志根目录并设置严格的权限:
sudo mkdir -p /var/log/sudo-io sudo chmod 700 /var/log/sudo-io
现在,当用户john执行 sudo vim /etc/hosts 时,sudo会在 /var/log/sudo-io/john/ 目录下创建一个以时间戳命名的子目录,里面包含多个文件:
log 文件记录了会话的元数据,如开始结束时间、用户、命令等。
ttyin 文件记录了用户所有的键盘输入。
ttyout 文件记录了命令的所有屏幕输出。
stdin, stdout, stderr 文件则分别记录了标准输入、输出和错误。
要回放这些记录,需要使用 sudoreplay 命令。首先,列出某个用户的会话记录:
sudo sudoreplay -l
你会看到会话ID列表。然后,指定一个ID进行回放,就像播放视频一样:
sudo sudoreplay 000001
你可以调整回放速度,比如以两倍速播放:
sudo sudoreplay -s 2 000001
这个功能极其强大,它让特权操作的审计达到了前所未有的深度。任何恶意操作或误操作都将被完整记录,无法抵赖。
日志的轮替与管理随着时间推移,sudo的审计日志会变得非常大,尤其是开启了I/O日志后。必须配置日志轮替,防止磁盘被写满。对于文本日志 /var/log/sudo/sudo.log,可以在 /etc/logrotate.d/ 下创建配置文件:
sudo vim /etc/logrotate.d/sudo
输入以下内容:
/var/log/sudo/sudo.log {
weekly
rotate 12
compress
delaycompress
missingok
notifempty
create 600 root root
}
对于I/O日志目录,情况稍复杂,因为它们是结构化目录。可以编写一个简单的脚本,通过 find 命令定期清理超过90天的目录,并将其加入crontab定时任务:
0 2 * * * find /var/log/sudo-io -type d -mtime +90 -exec rm -rf {} \;
这条任务会在每天凌晨2点执行,删除90天前的I/O日志目录。
集中化日志管理思路如果你管理的不是单台服务器,而是一个集群,那么将sudo日志集中收集起来统一分析是必然的选择。rsyslog本身支持将日志转发到远程日志服务器。修改 /etc/rsyslog.d/50-sudo.conf 文件:
local2.debug @192.168.1.100:514
这行配置会将sudo日志同时发送到IP为192.168.1.100的远程syslog服务器上。在日志服务器端,你可以部署ELK、Graylog等日志分析平台,对sudo日志进行聚合、告警和可视化展示。例如,设置一条告警规则:当某台服务器在5分钟内出现超过10次失败的sudo尝试时,立即发送通知。这种主动防御能力,是单机日志文件无法提供的。
整个方案的实施,从禁止root登录这个最简单的动作开始,到配置基本的文本日志,再到启用会话级I/O审计,最后到集中化日志管理,是一个安全防护逐步深入的过程。每一步都实实在在地提升了系统的可审计性和抗风险能力,没有花哨的理论,全是可落地执行的配置。
