摘要: 凌晨三点收到监控告警,VPS流量暴涨、CPU跑满、网站无法访问——这是每个站长最不愿面对的噩梦。本文不是安全理论课,而是一份可执行的应急手册。从攻击识别、紧急止血、根因分析到加固预防,每一步都附带具体命令,让你在慌乱中也能按图索骥。
一、先确认:是真的被攻击,还是自己想多了
流量突增不等于被攻击。先排查这几个常见误报:
系统更新或备份任务。 很多面板默认在凌晨执行自动备份,rsync或mysqldump会瞬间拉满IO和带宽。查看crontab:crontab -l,检查是否有定时任务与告警时间重合。
爬虫集中抓取。 搜索引擎爬虫、竞品监控程序、或某个突然走红的内容被大量转发,都会导致流量激增。用iftop或nethogs查看连接来源,如果是Googlebot、Bingbot等合法爬虫,属于正常业务波动。
自身程序bug。 某个死循环脚本、内存泄漏的应用、或配置错误导致的服务疯狂重试,表象像攻击,实则是内部问题。查看应用日志定位异常请求模式。
真正的攻击通常有这些特征:大量来自不同IP的同类请求(DDoS)、单一IP高频尝试登录(暴力破解)、Web日志中出现大量异常UA或payload(CC攻击/漏洞扫描)、境外IP集中访问本不该暴露的服务端口。
二、紧急止血:先活下来,再查原因
第一步:切断入口
如果是Web攻击,临时关闭80/443端口,保留SSH:
sudo ufw deny 80
sudo ufw deny 443
如果SSH也被爆破,修改端口并限制来源IP:
sudo sed -i 's/#Port 22/Port 22222/' /etc/ssh/sshd_config
sudo ufw allow from 你的本地IP to any port 22222
sudo systemctl restart sshd
第二步:定位异常进程
# 查看CPU/内存占用最高的进程
top -o %CPU
# 查看异常网络连接
ss -tulnp | grep ESTAB
# 查找可疑进程的文件位置
ls -la /proc/异常PID/exe
如果发现陌生进程占用大量资源,先记录PID和文件路径,不要立即kill——某些恶意程序会设置watchdog,杀死主进程后立即重启。先隔离网络:
sudo iptables -A OUTPUT -m owner --pid-owner 异常PID -j DROP
第三步:保存证据
在清理之前,把关键日志和可疑文件打包备份到外部存储:
sudo tar czvf /tmp/incident-evidence-$(date +%Y%m%d).tar.gz \
/var/log/auth.log \
/var/log/nginx/access.log \
/var/log/syslog \
/tmp/可疑文件路径
用scp或rsync立即传到另一台服务器或本地电脑。日志在重启后可能被清理,证据越早固定越好。
三、根因分析:攻击从哪来,怎么进来的
检查入侵入口
查看SSH登录记录:
sudo grep "Accepted" /var/log/auth.log | tail -50
sudo last -a | head -30
关注非工作时间登录、非预期IP登录、以及登录后立即执行敏感命令的记录。
检查是否有新增用户或提权:
cat /etc/passwd | grep -E ":/bin/bash|:/bin/sh"
sudo awk -F: '$3 >= 1000 {print $1}' /etc/passwd
sudo grep sudo /etc/group
检查定时任务后门:
crontab -l
sudo cat /etc/crontab
sudo ls -la /etc/cron.d/
sudo ls -la /etc/cron.hourly/ /etc/cron.daily/ /etc/cron.weekly/
攻击者常通过crontab植入持久化后门,即使清理了主程序,定时任务也会重新下载。
分析Web攻击面
如果是Web应用被入侵,检查:
Nginx/Apache访问日志中的异常请求:
sudo awk '{print $1}' /var/log/nginx/access.log | sort | uniq -c | sort -nr | head -20
查找高频IP和异常UA:
sudo grep -E "(wget|curl|python|nikto|sqlmap|nmap)" /var/log/nginx/access.log
检查Web目录是否有新增可疑文件:
sudo find /var/www -type f -mtime -1 -ls
重点关注.php、.jsp、.py、.sh等可执行文件,尤其是名称看起来像系统文件(如index.php.bak、wp-config.php.swp)的伪装文件。
检查系统级后门
查找SUID提权文件:
sudo find / -perm -4000 -type f 2>/dev/null
正常系统只有少数几个SUID文件(如/usr/bin/sudo、/usr/bin/passwd),如果发现陌生路径,极可能是后门。
检查内核模块:
lsmod | grep -i "hide\|rootkit"
高级攻击者会加载内核级rootkit隐藏进程和文件,普通命令行工具无法发现。如果怀疑到此层面,建议直接重装系统,不要尝试清理。
四、清理与恢复:重建信任
轻度感染:针对性清理
如果确认只是某个Web漏洞被利用、或某个弱密码被爆破,且尚未扩散到系统层面:
停止相关服务,清理恶意文件,修补漏洞(更新软件版本、修改配置),修改所有密码和密钥,重新部署应用。
重度感染:重装是唯一选择
如果发现以下任一情况,不要犹豫,直接重装系统:存在未知用户或无法解释的进程;crontab被篡改且无法确认全部后门位置;发现内核模块异常;服务器被用作挖矿、DDoS肉鸡、或代理跳板。
重装后不要直接恢复全量备份——备份中可能已包含后门。只恢复数据文件(数据库dump、静态资源、配置文件),应用程序重新安装最新版本。
五、加固:让下次攻击更难成功
SSH加固清单
# 禁用root登录
sudo sed -i 's/PermitRootLogin yes/PermitRootLogin no/' /etc/ssh/sshd_config
# 禁用密码认证,改用密钥
sudo sed -i 's/#PasswordAuthentication yes/PasswordAuthentication no/' /etc/ssh/sshd_config
# 限制登录用户
echo "AllowUsers youruser" | sudo tee -a /etc/ssh/sshd_config
sudo systemctl restart sshd
安装fail2ban
sudo apt install fail2ban
sudo systemctl enable fail2ban
# 配置自定义规则
sudo tee /etc/fail2ban/jail.local <<EOF
[DEFAULT]
bantime = 3600
findtime = 600
maxretry = 3
[sshd]
enabled = true
port = ssh
filter = sshd
logpath = /var/log/auth.log
maxretry = 3
[nginx-http-auth]
enabled = true
filter = nginx-http-auth
port = http,https
logpath = /var/log/nginx/error.log
EOF
sudo systemctl restart fail2ban
Web应用层防护
- 所有输入点做过滤和参数化查询,杜绝SQL注入
- 上传目录禁止脚本执行:
location ~* /uploads/.*\.php$ { deny all; } - 隐藏版本信息:
server_tokens off; - 启用WAF规则(如Nginx ModSecurity)或接入云WAF
网络层加固
# 默认拒绝所有入站,只开放必要端口
sudo ufw default deny incoming
sudo ufw default allow outgoing
sudo ufw allow 22222/tcp # SSH
sudo ufw allow 80/tcp
sudo ufw allow 443/tcp
sudo ufw enable
监控与告警
安装Netdata或Prometheus+Grafana,监控以下指标:CPU使用率持续超过80%;网络入站流量突增超过基线3倍;磁盘IO等待时间异常;失败登录次数5分钟内超过10次。
六、写在最后
被攻击不是耻辱,被攻击后不做复盘才是。每次事件都是一次免费的安全审计,暴露了你防御体系中最薄弱的环节。把应急过程文档化,形成团队知识库,下次响应速度至少快一倍。
安全是持续投入的过程,不是一次性勾选的任务清单。今天的加固措施,明天可能就有新的绕过方式。保持关注CVE公告、订阅安全邮件列表、定期做渗透测试——这些习惯比任何工具都重要。
