服务器安全自检:几个工具跑一遍就知道大概

不知道服务器安不安全,就跑一遍工具。它们不能替代专业审计,但能抓出绝大多数低级问题。

一、lynis:系统安全审计

bash
sudo apt install -y lynis
sudo lynis audit system

输出分几类:

bash
Warnings (1):
  - Set a password on GRUB bootloader [BOOT-5122]

Suggestions (15):
  - Configure a firewall [FIRE-4513]
  - Enable auditd [ACCT-9628]
  ...

每个建议都有编号,去官网能查到详细解释和修复方法。

bash
# 看报告文件
cat /var/log/lynis-report.dat

# 只看警告和建议
sudo lynis audit system | grep -A100 "Warnings"

# 只审计某个类别
sudo lynis audit system --tests-from-group "ssh"

常见会报的项目和处理:

项目说明处理
FIRE-4513没配防火墙装 ufw
SSH-7408SSH 参数可加强按加固清单改
BOOT-5122GRUB 没密码单用户物理接触才需要,云主机可忽略
ACCT-9628没开 auditd装 auditd,吃一点资源
KRNL-6000内核参数参考 sysctl 调优篇

二、rkhunter:Rootkit 检测

bash
sudo apt install -y rkhunter
sudo rkhunter --update
sudo rkhunter --propupd        # 建立基线(确认系统干净时做)
sudo rkhunter --check --sk

# 看报告
sudo cat /var/log/rkhunter.log | grep -i warning

rkhunter 误报不少(比如某些隐藏文件、更新的二进制)。重点看 Warning 里的 Rootkit 项和被修改的系统命令。

三、端口审计:对外暴露了什么

bash
# 本机监听
sudo ss -lntp

# 从外网看(在另一台机器上跑)
nmap -Pn -sV your-server-ip
nmap -Pn --top-ports 1000 your-server-ip

# 只看开放的端口
nmap -Pn --open your-server-ip

对照检查:

bash
ss -lntp | awk '{print $4, $6}' | sort -u

看到不该有的端口就要查是谁:

bash
sudo lsof -i :8080
sudo ss -lntp | grep 8080
ps aux | grep <PID>

四、账号审计

bash
# 所有能登录的用户(有 shell 的)
cat /etc/passwd | grep -v nologin | grep -v false

# UID 为 0 的(应该只有 root)
awk -F: '($3 == 0) {print}' /etc/passwd

# 空密码账号(应该没有)
sudo awk -F: '($2 == "") {print}' /etc/shadow

# 最近新建的用户
sudo tail -20 /var/log/auth.log | grep -i "new user"

# 有 sudo 权限的
sudo grep -Po '^sudo.+:\K.*$' /etc/group
sudo ls /etc/sudoers.d/

# 谁在什么时候登录过
last -20
lastb -20            # 失败的登录尝试
who

五、SSH 配置核查

bash
sudo sshd -T | grep -E "permitrootlogin|passwordauthentication|permitemptypasswords|x11forwarding|port|maxauthtries"

期望值:

期望
permitrootloginno
passwordauthenticationno
permitemptypasswordsno
x11forwardingno
maxauthtries≤ 4
bash
# 看哪些公钥被授权了(有没有不认识的)
cat ~/.ssh/authorized_keys
sudo find / -name authorized_keys 2>/dev/null

# 登录失败统计
sudo grep "Failed password" /var/log/auth.log | awk '{print $11}' | sort | uniq -c | sort -rn | head

# fail2ban 封了多少
sudo fail2ban-client status sshd

六、文件完整性

bash
# 找出最近 7 天被修改的系统文件
sudo find /etc /usr/bin /usr/sbin -mtime -7 -type f 2>/dev/null

# 检查 suid/sgid 文件(有没有异常多的)
sudo find / -perm -4000 -type f 2>/dev/null
sudo find / -perm -2000 -type f 2>/dev/null

# 世界可写的文件(不该有)
sudo find / -xdev -type f -perm -0002 2>/dev/null | head

# 校验包完整性(Debian)
sudo apt install -y debsums
sudo debsums -c            # 列出被改动的文件(有正常改动会误报)

七、定时任务与自启动(后门高发区)

bash
# 当前用户和 root 的 crontab
crontab -l
sudo crontab -l -u root
sudo ls -la /etc/cron.d/ /etc/cron.daily/

# systemd 定时器
systemctl list-timers --all

# 所有开机自启的服务(看有没有不认识的)
systemctl list-unit-files --state=enabled

# 老式自启动
ls /etc/init.d/
cat /etc/rc.local 2>/dev/null

八、一份季度巡检清单

写成脚本定期跑:

bash
#!/usr/bin/env bash
# /opt/scripts/security-check.sh
echo "=== 监听端口 ==="
sudo ss -lntp
echo
echo "=== UID 0 账号 ==="
awk -F: '($3 == 0) {print $1}' /etc/passwd
echo
echo "=== 登录失败 TOP10 ==="
sudo grep "Failed password" /var/log/auth.log 2>/dev/null \
  | awk '{print $11}' | sort | uniq -c | sort -rn | head
echo
echo "=== fail2ban ==="
sudo fail2ban-client status sshd 2>/dev/null | grep -E "Currently|Total"
echo
echo "=== SSH 关键配置 ==="
sudo sshd -T | grep -E "^(permitrootlogin|passwordauthentication)"
echo
echo "=== 磁盘 ==="
df -h /
bash
chmod +x /opt/scripts/security-check.sh
sudo /opt/scripts/security-check.sh

配合 systemd timer 每月跑一次,结果发到日志里。

九、发现异常之后

  1. 不要惊慌地直接删文件,先看清楚是什么;
  2. 保全证据:备份日志、记录进程列表;
  3. 断网或封端口,阻止继续通信;
  4. 排查入口(弱密码?未修复漏洞?暴露的服务?);
  5. 无法确认清理干净就重建服务器,从备份恢复数据。
bash
# 保全现场
ps aux > /tmp/ps-$(date +%F).txt
sudo ss -antp > /tmp/net-$(date +%F).txt
sudo cp -r /var/log /tmp/log-$(date +%F)

安全没有终点,但跑一遍工具 + 定期看日志,已经能挡掉大部分风险。