🛡️ Server Security Ops
> 本 skill 仅限自管服务器运维使用。所有破坏性操作均要求用户显式确认,并自动配置 5 分钟回滚保险。
⚠️ 操作前必读
- iptables 改动前必跑
echo "sudo iptables --flush" | sudo at now + 5 minutes配自动回滚 - 改 sshd 之前先确认 key 登录可用,否则改
PasswordAuthentication no会锁自己出去 - CDN/反代后面 ban 反代出口 = 误伤,真实 IP 在
X-Forwarded-For - 所有配置变更前先备份:
sudo cp 原文件 原文件.bak.$(date +%Y%m%d)
Inputs to collect
- OS(Ubuntu/CentOS)、暴露面(SSH/HTTP)、已有防御(fail2ban/ufw/CDN)、当前症状(异常/被穿)、是否有 sudo
Procedure
Phase 1 — 态势感知(只读不改)
完整命令集见 references/forensics-commands.md。核心命令:
# SSH 攻击源 TOP 20
sudo grep "Failed password" /var/log/auth.log 2>/dev/null | \
awk '{for(i=1;i<=NF;i++) if($i=="from") print $(i+1)}' | \
sort | uniq -c | sort -rn | head -20
# ⚠️ 最关键:成功登录记录(找陌生 IP 是否已登入)
sudo grep "Accepted" /var/log/auth.log 2>/dev/null | tail -30
# Web 路径扫描(nginx 路径为例)
sudo grep -E "wp-admin|wp-login|phpmyadmin|\.env|\.git" \
/var/log/nginx/access.log 2>/dev/null | \
awk '{print $1, $7, $9}' | sort | uniq -c | sort -rn | head -20
# 当前 fail2ban 状态
sudo fail2ban-client status
Phase 2 — 分层防御
L1 fail2ban(最低成本,先做)
完整模板见 references/jail-local-template.md。write 工具写 /etc/fail2ban/jail.local 后:
sudo cp /etc/fail2ban/jail.local /etc/fail2ban/jail.local.bak.$(date +%Y%m%d) 2>/dev/null
sudo systemctl reload fail2ban
L2 iptables(内核层兜底)
# ⚠️ 第 1 步:必跑回滚保险
echo "sudo iptables --flush" | sudo at now + 5 minutes
# 第 2 步:SSH 限速
sudo iptables --insert INPUT --protocol tcp --dport 22 --match connlimit --connlimit-above 3 --jump DROP
sudo iptables --insert INPUT --protocol tcp --dport 22 --match state --state NEW --match recent --set --name SSH
sudo iptables --insert INPUT --protocol tcp --dport 22 --match state --state NEW --match recent --update --seconds 60 --hitcount 4 --name SSH --jump DROP
# 第 3 步:Web 限速(80/443 完整规则见 references/iptables-rules.md)
sudo iptables --insert INPUT --protocol tcp --dport 80 --match state --state NEW --match recent --update --seconds 60 --hitcount 60 --name HTTP --jump DROP
sudo iptables --insert INPUT --protocol tcp --dport 443 --match state --state NEW --match recent --update --seconds 60 --hitcount 60 --name HTTPS --jump DROP
# 第 4 步:验证(新开窗口 SSH 进去)+ 取消回滚 + 落盘
sudo atrm $(atq | awk '{print $1}')
sudo netfilter-persistent save # Debian/Ubuntu
# CentOS: sudo service iptables save
L3 sshd 加固(让密码爆破失效)
完整模板见 references/sshd-config-template.md。必跑:
sudo cp /etc/ssh/sshd_config /etc/ssh/sshd_config.bak.$(date +%Y%m%d)
# ⚠️ 改前确认 key 登录 OK
sudo sshd -t # 必跑验语法
sudo systemctl reload ssh # 用 reload 不用 restart
L4 nginx 加固
完整配置见 references/nginx-config-template.md。
sudo nginx -t && sudo systemctl reload nginx
Phase 3 — 持续监控
完整脚本见 references/daily-report-script.md。
sudo chmod +x /usr/local/bin/security-daily.sh
echo "0 8 * * * root /usr/local/bin/security-daily.sh" | sudo tee /etc/cron.d/security-daily
Phase 4 — 应急响应(被穿了)
完整流程见 references/incident-checklist.md。核心命令:
w; who; last -n 20; lastb -n 20 # 1. 在线用户
sudo ss --listening --tcp --numeric --programs # 2. 监听端口(找后门)
sudo crontab --list; for u in $(cut -f1 -d: /etc/passwd); do
sudo crontab --user "$u" --list 2>/dev/null # 3. cron
done
sudo find /tmp /var/tmp /dev/shm --type f # 4. 可疑文件
# 5. 断网保命
YOUR_IP=$(who am i | awk '{print $NF}' | tr --delete '()')
sudo iptables --insert INPUT --source "$YOUR_IP" --jump ACCEPT
sudo iptables --insert INPUT --match state --state ESTABLISHED,RELATED --jump ACCEPT
sudo iptables --insert INPUT --jump DROP
Output contract & failure handling
详见 references/usage-and-failure.md(输出格式规范 + 失败处理表 + 安全承诺 + 适用边界)
References
references/usage-and-failure.md— 输出规范 + 失败处理references/forensics-commands.md— 完整取证命令references/jail-local-template.md— fail2ban 模板references/iptables-rules.md— iptables 完整规则references/sshd-config-template.md— sshd_config 模板references/nginx-config-template.md— nginx 配置references/daily-report-script.md— 日报脚本references/incident-checklist.md— 救火流程
License
MIT-0 — 公共领域贡献,可自由使用、修改、再发布,无需署名。