Linux 主机基线
面向内部服务器的 Linux 加固清单:最小化安装、SSH 加固、内核参数与审计,以及一条条能跑的验证命令。
面向内部服务器(Debian / RHEL 系)。容器和开发机另算。
SSH
# /etc/ssh/sshd_config
PermitRootLogin no
PasswordAuthentication no
PermitEmptyPasswords no
MaxAuthTries 3
X11Forwarding no
AllowUsers deploy@10.0.0.0/8 ops@10.0.0.0/8
PasswordAuthentication no 意味着必须先确认密钥能登进去再改配置,否则把自己锁在外面。改配置时保持一个已登录的会话不要关,用 sshd -t 验证语法后 reload 而不是 restart。
sshd -t && systemctl reload sshd # 语法检查 + 平滑重载
登录审计
# /etc/ssh/sshd_config
Banner /etc/issue.net
ClientAliveInterval 300
ClientAliveCountMax 2
MaxSessions 4
ClientAlive* 配了之后,超过 10 分钟没有任何响应的连接会被断开。这条常被忽略,但它直接决定了「一个被劫持但没人用的会话能挂多久」。
同时在 /etc/audit/rules.d/50-login.rules 留档:
-w /var/log/faillog -p wa -k auth
-w /etc/passwd -p wa -k identity
-w /etc/group -p wa -k identity
-w /etc/sudoers -p wa -k privilege
-w /etc/ssh/sshd_config -p wa -k sshd
auditd 的规则重启才生效,但可以用 -e 1 临时开启审计而不重启——调试阶段很有用。
内核参数
# /etc/sysctl.d/99-hardening.conf
net.ipv4.conf.all.accept_redirects = 0
net.ipv4.conf.all.send_redirects = 0
net.ipv4.conf.all.accept_source_route = 0
net.ipv4.conf.all.log_martians = 1
net.ipv4.tcp_syncookies = 1
net.ipv4.ip_forward = 1
kernel.randomize_va_space = 2
kernel.kptr_restrict = 2
kernel.dmesg_restrict = 1
fs.protected_hardlinks = 1
fs.protected_symlinks = 1
sysctl --system
sysctl net.ipv4.conf.all.accept_redirects # 验证应为 0
net.ipv4.ip_forward 需要单独看:容器和路由器需要它,普通应用服务器不需要。这一条不要照抄,按角色定。
最小化
# 列出实际被依赖的包,反查该删什么
apt-mark showmanual # Debian
dnf repoquery --userinstalled # RHEL
# 关闭不需要的服务
systemctl list-unit-files --state=enabled
systemctl disable --now telnet.socket rsh.service talk.service
别用 apt autoremove 清理生产机器上的包。它会删掉你以为没人用但其实是某个服务运行依赖的库,报错发生在一周后最难查的时候。要删的包逐个删,删完跑一遍服务健康检查。
验证
sshd -T | grep -Ei '^(permitrootlogin|passwordauthentication|maxauthtries)'
systemctl is-enabled telnet.socket 2>/dev/null || echo "telnet: not enabled (ok)"
aureport --summary 2>/dev/null | head -20
find / -perm -4000 -type f 2>/dev/null # SUID 文件清单
最后一条尤其重要:SUID 文件是提权的第一站。基线生效之后应当只有 /usr/bin/{passwd,su,sudo,gpasswd,chsh,chfn,newgrp,mount,umount,pkexec} 这些,剩下的都要解释。