post: 舰队安全加固日记(脱敏版)
This commit is contained in:
@@ -0,0 +1,91 @@
|
||||
---
|
||||
title: "舰队安全加固日记:从攻击溯源到 Ansible 自动化"
|
||||
description: "三节点 VPS 舰队的一天:SSL 续签排查、WAF 加固、Ansible 落地、域名迁移。全程踩坑记录。"
|
||||
date: 2026-08-01T16:00:00+08:00
|
||||
draft: false
|
||||
tags:
|
||||
- 运维
|
||||
- 安全
|
||||
- Ansible
|
||||
- Cloudflare
|
||||
---
|
||||
|
||||
## 背景
|
||||
|
||||
维护一个由三台海外 VPS 组成的"小舰队"(分别承担代理、博客、文件服务、监控等角色),配合本地 NAS 作为管理中心。今天做了一次全面安全巡检与加固,记录几个有价值的踩坑点。
|
||||
|
||||
## 一、SSL 自动续签的隐形坑
|
||||
|
||||
**现象**:三节点都配置了 acme.sh 自动续签 cron,看似无忧。
|
||||
|
||||
**真相**:cron 在跑 ≠ 续签链路完整。逐节点检查发现:
|
||||
|
||||
| 问题 | 影响 |
|
||||
|------|------|
|
||||
| 部署路径为空(`Le_RealFullChainPath` 没配置) | 续签后证书不会部署到 Nginx 引用位置 |
|
||||
| ReloadCmd 为空 | 新证书部署了但不 reload,一直用旧的 |
|
||||
|
||||
**最严重的情况**:某节点 4 个证书全部"部署路径 + reload 命令"双缺——key 会换新、证书不换,一旦 reload 就是 key/cert 不匹配,TLS 全挂。
|
||||
|
||||
**经验**:
|
||||
1. acme.sh 的字段名是 `Le_RealFullChainPath`(不是 `Le_RealCertPath`)
|
||||
2. 宝塔的 Nginx 不是 systemd 管理,reload 要用 `/etc/init.d/nginx reload`
|
||||
3. 部署前必须核对 Nginx 实际引用的证书路径,不同节点布局可能完全不同
|
||||
|
||||
## 二、fail2ban 误伤自家节点
|
||||
|
||||
**现象**:NAS 访问某节点突然超时,SSH 连不上,网站也打不开。
|
||||
|
||||
**根因**:fail2ban 的 `banaction_allports`(全端口封禁)把**自家 NAS 的出口 IP** 封了——原因是 NAS 通过堡垒机跳转时的认证失败触发了封禁规则。
|
||||
|
||||
**后果**:SSH(22)、HTTPS(443)全被 nftables 切断。
|
||||
|
||||
**经验**:
|
||||
1. **舰队节点之间互相探测/跳转频繁,防爆破规则很容易误伤自己人**
|
||||
2. 解决方案:把全部节点 IP 加入 fail2ban 的 `ignoreip` 白名单(注意要放在 `[DEFAULT]` 段,不是某个 jail 段末尾)
|
||||
3. SSH 防爆破不要用 allports 封禁,只封 22 端口即可
|
||||
|
||||
## 三、Ansible 落地:控制端放 NAS
|
||||
|
||||
**选型**:Ansible(无 agent、SSH 直连、YAML 声明式),控制端放在本地 NAS。
|
||||
|
||||
**认证方案**:生成 ed25519 密钥对,公钥分发到三节点 authorized_keys。注意:
|
||||
|
||||
1. **某节点 sshd 配置了 `PubkeyAuthentication no`**——公钥装了也连不上,需要改回 yes 并重启
|
||||
2. **网络回程问题**:NAS 直连某节点时"发送通、接收断"(命令执行成功但输出回不来)——SSH 长连接(如插件)没问题,但 Ansible 短连接卡死
|
||||
3. **解决方案**:用中间节点做 SSH 跳板(ProxyCommand 方式),绕开直连的线路问题
|
||||
|
||||
**注意**:Ansible 有个在野 RCE(CVE-2026-11332,ansible-galaxy role install 参数注入)——安装后立即升级到修复版(≥2.21.1),且只安装官方/高星 role。
|
||||
|
||||
## 四、Cloudflare WAF 加固
|
||||
|
||||
**发现**:托管 WAF 和 DDoS 规则集在列表里能看到,但实际**没有部署到域名**(entrypoint 不存在)——攻击根本没有防线。
|
||||
|
||||
**动作**:
|
||||
1. 用新版 WAF API(rulesets)部署自定义规则:拦截扫描器 UA、恶意路径(/.env、/.git、/phpmyadmin 等)
|
||||
2. 根据源 IP 统计,把非国内的高频攻击源(云主机僵尸网络)按 /24 网段批量封禁
|
||||
3. 三层防护:CF 边缘规则 + 源站防火墙 + 原有 fail2ban
|
||||
|
||||
**验证**:模拟攻击 `/.env` 请求 → 403 拦截成功 ✅
|
||||
|
||||
**局限**:CF 规则只对走 CF 代理(proxied)的域名生效,直连源站的域名需要靠源站防火墙兜底。
|
||||
|
||||
## 五、域名迁移:新域名做"前哨"
|
||||
|
||||
**思路**:把公开服务入口迁移到独立域名,走 CF 代理隐藏真实源站 IP。原域名收缩为内部服务,降低攻击面。
|
||||
|
||||
**要点**:
|
||||
- 新域名通过 CF DNS API 快速切换指向
|
||||
- acme.sh + DNS Challenge 签发证书(无需开放 80 端口)
|
||||
- 聚合导航页部署,一站式入口
|
||||
- 自动续期链路完整配置(部署路径 + reload)
|
||||
|
||||
## 小结
|
||||
|
||||
一天的巡检发现:**"看起来在自动运行"的服务最危险**——acme.sh cron 在跑但续签链路缺一半、WAF 规则集存在但没部署、fail2ban 在封禁但误伤自己人。
|
||||
|
||||
自动化是双刃剑:配置了就要验证完整闭环,否则"自动"只是虚假安全感。
|
||||
|
||||
---
|
||||
|
||||
*(本文基于真实运维经验撰写,出于安全考虑隐去具体域名、IP、凭证信息)*
|
||||
Reference in New Issue
Block a user