一台公网服务器的 20 项基线加固(附脚本)
每次开新机器,我都会跑一遍这套流程。20 项,大概 40 分钟。
不是「安全等级保护」那种大而全的清单,就是一台个人服务器该做的基本功。
一、账号与认证
1. 创建普通用户,禁用 root 直连
useradd -m -s /bin/bash deploy
usermod -aG sudo deploy
# 复制公钥
mkdir -p /home/deploy/.ssh && cp /root/.ssh/authorized_keys /home/deploy/.ssh/
chown -R deploy:deploy /home/deploy/.ssh && chmod 700 /home/deploy/.ssh && chmod 600 /home/deploy/.ssh/authorized_keys
2. 只允许密钥登录
# /etc/ssh/sshd_config
PermitRootLogin no
PasswordAuthentication no
PubkeyAuthentication yes
PermitEmptyPasswords no
MaxAuthTries 3
LoginGraceTime 20
改完先 sshd -t 校验,再 systemctl reload sshd,并且保持当前会话不要断开,另开一个窗口验证能登录。
3. 限制可登录用户
AllowUsers deploy
4. 装 fail2ban
apt install fail2ban
/etc/fail2ban/jail.local:
[DEFAULT]
bantime = 1h
findtime = 10m
maxretry = 5
[sshd]
enabled = true
二、网络
5. 默认拒绝的防火墙
# nftables 还是 ufw 都行,我用 ufw 因为它简单
ufw default deny incoming
ufw default allow outgoing
ufw allow 22/tcp
ufw allow 80,443/tcp
ufw enable
6. 只监听需要的地址
ss -tlnp
MySQL、Redis、Docker API 这些绝对不要监听 0.0.0.0。MySQL 改:
bind-address = 127.0.0.1
7. 关掉 IPv6(如果没有用)
# /etc/sysctl.d/99-disable-ipv6.conf
net.ipv6.conf.all.disable_ipv6 = 1
net.ipv6.conf.default.disable_ipv6 = 1
注意:这会影响到依赖 IPv6 的服务。如果服务器在只有 IPv6 的环境,跳过。
8. 禁用不用的服务
systemctl list-unit-files --state=enabled
# 常见可关:cups、avahi-daemon、bluetooth、rpcbind
三、内核参数
9. 防 SYN Flood
# /etc/sysctl.d/99-hardening.conf
net.ipv4.tcp_syncookies = 1
net.ipv4.tcp_max_syn_backlog = 2048
net.ipv4.tcp_synack_retries = 2
10. 关闭 IP 转发(除非做路由)
net.ipv4.ip_forward = 0
11. 禁止 ICMP 重定向
net.ipv4.conf.all.accept_redirects = 0
net.ipv4.conf.all.send_redirects = 0
net.ipv6.conf.all.accept_redirects = 0
12. 开启反向路径过滤
net.ipv4.conf.all.rp_filter = 1
注意:多网卡或者有策略路由的机器上,这一项可能导致网络不通,要谨慎。
13. 隐藏内核指针
kernel.kptr_restrict = 2
kernel.dmesg_restrict = 1
应用:
sysctl --system
四、文件与权限
14. 检查 SUID 文件
find / -perm -4000 -type f 2>/dev/null
不需要的去掉 SUID 位。常见需要保留的:/usr/bin/sudo、/usr/bin/passwd、/bin/su、/usr/bin/mount。
15. 关键目录权限
chmod 700 /root
chmod 700 /home/*/.ssh
chmod 600 /etc/shadow
chmod 644 /etc/passwd
16. 把 /tmp 挂成 noexec(可选)
# /etc/fstab
tmpfs /tmp tmpfs defaults,nosuid,nodev,noexec 0 0
风险:有些程序的安装脚本要在 /tmp 里执行二进制,会失败。要评估。
五、日志与审计
17. auditd 记录关键操作
apt install auditd
# 监控提权、敏感文件修改
cat > /etc/audit/rules.d/hardening.rules <<'EOF'
-w /etc/passwd -p wa -k identity
-w /etc/shadow -p wa -k identity
-w /etc/sudoers -p wa -k sudoers
-w /root/.ssh -p wa -k sshkeys
-a always,exit -F arch=b64 -S execve -F euid=0 -k rootcmd
EOF
systemctl restart auditd
18. 日志外发或定期归档
本地日志被删是常有的事。至少要每天 rsync 一份到另一台机器。
# /etc/cron.daily/log-backup
rsync -az /var/log/ backup@10.0.0.5:/backup/$(hostname)/log/
19. 时间同步
timedatectl set-ntp true
timedatectl status
时间不准会导致日志时间错乱、TLS 证书校验失败、TOTP 验证码错误。
20. 定期更新
# 自动装安全更新(Debian/Ubuntu)
apt install unattended-upgrades
dpkg-reconfigure -plow unattended-upgrades
一个脚本
把上面大部分做成脚本:
#!/usr/bin/env bash
set -euo pipefail
echo "[1/8] SSH 加固"
sed -i 's/^#\?PermitRootLogin.*/PermitRootLogin no/' /etc/ssh/sshd_config
sed -i 's/^#\?PasswordAuthentication.*/PasswordAuthentication no/' /etc/ssh/sshd_config
sed -i 's/^#\?MaxAuthTries.*/MaxAuthTries 3/' /etc/ssh/sshd_config
sshd -t && systemctl reload sshd
echo "[2/8] 内核参数"
cat > /etc/sysctl.d/99-hardening.conf <<'EOF'
net.ipv4.tcp_syncookies = 1
net.ipv4.conf.all.accept_redirects = 0
net.ipv4.conf.all.send_redirects = 0
net.ipv4.conf.all.rp_filter = 1
kernel.kptr_restrict = 2
kernel.dmesg_restrict = 1
EOF
sysctl --system > /dev/null
echo "[3/8] 防火墙"
ufw --force default deny incoming
ufw --force default allow outgoing
ufw allow 22/tcp
ufw allow 80,443/tcp
ufw --force enable
echo "[4/8] fail2ban"
apt-get install -y fail2ban > /dev/null
systemctl enable --now fail2ban
echo "[5/8] 文件权限"
chmod 700 /root
chmod 600 /etc/shadow
echo "[6/8] SUID 检查"
find / -perm -4000 -type f 2>/dev/null > /root/suid-baseline.txt
echo "[7/8] 时间同步"
timedatectl set-ntp true
echo "[8/8] 自动安全更新"
apt-get install -y unattended-upgrades > /dev/null
systemctl enable --now unattended-upgrades
echo "完成。请检查 /root/suid-baseline.txt,并用新窗口验证 SSH 登录。"
三个提醒
- 在控制台做,不要只靠 SSH。改 SSH 配置很容易把自己锁在外面,VNC/控制台是你的保险。
- 每改一项验证一项,不要一口气全改完再重启。
- 记录基线。加固之前的端口列表、SUID 列表、服务列表存一份,出问题时能对比。
最后
这 20 项挡不住针对性的攻击,但能挡掉 90% 的自动化扫描和暴力破解。
我自己的机器上,加固前每天有上千次 SSH 爆破尝试,加固后日志基本干净了——不是因为没人试,是因为他们连密码验证的入口都摸不到。
安全是个成本问题。这 40 分钟的成本,是所有投入里回报最高的。
评论 (0)
还没有评论,来说两句吧~
发表评论