Files
.pouch/skills/host-sec-check/references/hardening.md
T

5.4 KiB
Raw Blame History

分阶段加固

本参考只在用户明确同意「加固 / 配置 / 修复」后使用。默认先做检查,不改变远端主机。

0. 变更前闸门

  1. 确认目标主机、系统、维护窗口、业务端口和允许的管理来源。
  2. 确认有云控制台/VNC/串口等带外回滚入口;没有就不要同时改 SSH 和防火墙。
  3. 保留当前 SSH 会话,再准备第二条测试会话。先验证新会话成功,再关闭旧入口。
  4. 记录 sshd -T、ss -lntup、ufw status verbose 或 nftables/iptables 状态、Docker/k8s 入口。
  5. 将待改配置复制到受限的备份目录,记录时间和校验值;备份中可能有敏感信息,不要贴进聊天。

不要要求用户把 root 密码发给 Agent,也不要使用 sshpass、命令行密码、SSHPASS 或关闭 host-key 校验。优先复用现有 SSH key;必须创建临时密码时,用控制台或交互式 passwd 设置,并在密钥验证后删除/锁定。

1. 账号和 SSH

先创建并验证一个非 root 管理账号,再收紧 root 和密码登录:

  • 用户加入发行版正确的管理组(Debian/Ubuntu 通常是 sudo,RHEL 系通常是 wheel)。
  • 用户的 ~/.ssh 为 0700,authorized_keys 为 0600,目录和文件归属正确;只记录 key 指纹,不复制私钥或完整 key 内容。
  • 配置应放在发行版支持的 drop-in 中,例如 /etc/ssh/sshd_config.d/60-host-sec-check.conf,不要删除或改名所有现有 drop-in。
  • 基线建议:PermitRootLogin no、PasswordAuthentication no、KbdInteractiveAuthentication no(启用 MFA/键盘交互时例外)、PermitEmptyPasswords no、PubkeyAuthentication yes、MaxAuthTries 3。
  • X11Forwarding、TCP 转发、Agent 转发和 AllowGroups 要按业务需要逐项确认,不能为了“看起来更安全”无条件关闭。
  • 改端口不是必需项;如果确实改,先放行云安全组和本机防火墙,再在第二条会话中用新端口测试。IPv4 和 IPv6 规则都要确认。

每次变更都按这个顺序:

sshd -t
sshd -T | grep -iE '^(port|permitrootlogin|passwordauthentication|kbdinteractiveauthentication|pubkeyauthentication|permitempty passwords|maxauthtries) '
systemctl reload ssh 2>/dev/null || systemctl reload sshd
# 从另一条终端测试新用户/新端口,成功后才关闭旧登录路径

不要按 Ubuntu 版本号猜 SSH socket 模式。先看 systemctl is-enabled ssh.socket、systemctl status ssh.socket ssh.service 和 ss -lntp,按实际监听单元配置;改动后再次用 sshd -T 和 ss 验证。

2. 防火墙和暴露面

  • 先识别实际后端:UFW、nftables、firewalld 和 Docker 规则可能同时存在;不能在不了解现有规则时直接 default deny incoming 或 reset。
  • 保留已有业务白名单,最小化放行管理来源;明确处理 IPv6,避免只收紧 IPv4。
  • 防火墙只解决入站路径,不代表云安全组已收紧。云平台规则查不到就写「未验证」。
  • Docker 默认会安装自己的转发规则,不能仅凭 daemon.json 中没有 iptables 就认定需要写入 "iptables": false。先检查现有规则、发布端口和业务依赖;优先修正 compose 的绑定(内部服务不发布、回源绑 loopback/VPN),必要时在 DOCKER-USER/nftables 设计明确策略。
  • 关闭 rpcbind、数据库、Docker API、Portainer、Cockpit、k8s API 等入口前,先确认没有业务或编排依赖,并从外部验证端口确实消失。

3. Fail2ban、补丁和日志

  • 安装/启用 Fail2ban 前确认日志后端(systemd journal 或 /var/log/auth.log/secure),配置 ignoreip 为可信管理网段/VPN,而不是只写 loopback。
  • 变更后检查 fail2ban-client status、对应 jail、过滤器命中和当前封禁;避免把维护网段封掉。
  • 按发行版包管理器修补安全更新,并记录是否需要重启;不要把“执行了 apt upgrade”当成补丁覆盖证明。
  • 检查时间同步、journal 持久化和日志轮转;日志缺失本身是审计结果,不要静默当作正常。
  • auditd、自动安全更新和登录通知属于按业务选择的增强项,不是所有机器都应无条件启用。通知脚本必须避免泄露 token、密码和完整环境变量。

4. 验证和回滚

加固完成后至少验证:

  1. 第二条会话可用:新用户、密钥、预期端口、预期来源均成功。
  2. sshd -t、sshd -T、服务状态、监听端口和防火墙规则与目标一致。
  3. 从外部探测 IPv4/IPv6:应关闭的端口不可达,业务域名和必要入口仍可用。
  4. Fail2ban jail 正常;Docker/k8s 业务仍能启动,关键容器没有意外变成公网监听。
  5. 记录未验证项、重启需求和回滚命令。SSH 或防火墙失败时,优先从带外控制台恢复备份,不要在失联状态下反复猜配置。

与“一键加固脚本”的边界

一键脚本可以提供检查清单,但以下做法不能作为本 skill 的默认行为:

  • 在命令行、环境变量或最终报告打印密码;
  • StrictHostKeyChecking=no / UserKnownHostsFile=/dev/null;
  • 先要求开启 root 密码登录,再自动收紧;
  • 删除/改名整个 sshd_config.d;
  • 无条件开启密码认证或把 root 保留为 prohibit-password;
  • 用 sed 拼接 JSON,或无条件把 Docker iptables 设为 false;
  • 只 sleep 几秒后重启 SSH/防火墙,未通过第二会话和外部探测验证。