对个人站长来说,"服务器被入侵"这四个字往往不是从安全报告里看到的,而是以最粗暴的方式砸过来:网站首页被改成博彩广告、CPU 跑满风扇狂转、收到云服务商的挖矿告警邮件、或者数据库被加密后留了一张勒索信。大多数站长从没经历过这个场景,一旦碰上就手忙脚乱,要么直接重装系统把证据全毁了,要么病急乱投医乱删文件把问题搞得更糟。本文给出一套冷静、可执行的应急响应流程,区分"确认入侵""遏制""取证""清除""加固"五个阶段,并重点讲清个人站长最容易犯的错误。
第一阶段:确认——先别慌着删东西
发现异常的典型信号有这些:网站被篡改、出现大量你没发过的页面、SSH 登录看到陌生的登录记录、top 里有个不认识的进程吃满 CPU、带宽莫名跑满、云厂商发来安全告警、磁盘里冒出奇怪的文件。出现任何一条,先做这件事——把自己从"想立刻修好"的冲动里拉出来,进入取证心态。
第一件事是确认到底有没有被入侵,还是只是误报。查几个关键点:
# 1. 最近的登录记录,看有没有陌生 IP / 异常时间
last -a | head -20
lastb | head -20 # 失败的登录尝试
# 2. 当前登录的会话和来源 IP
who -a
ss -tnp | grep -E ':22|ESTAB'
# 3. 谁在跑占用最高的进程
ps aux --sort=-%cpu | head -10
ps aux --sort=-%mem | head -10
# 4. 有没有监听在奇怪端口的进程
ss -tulnp如果 ss -tulnp 里出现一个你没见过的进程监听在高位端口,或者 ps aux 里有个名字像乱码、路径在 /tmp 或 /dev/shm 的运行进程,那基本可以确认中了挖矿木马。/tmp 和 /dev/shm 是恶意程序的经典落脚点,因为任何人都可写且通常不引人注意。
第二阶段:遏制——先断网,但别关机
确认被入侵后,第一优先级不是清除,而是防止损害扩大。攻击者可能还在远程控制、可能在横向渗透你同账号下的其他机器、可能正在下载更多载荷。遏制动作按优先级排列:
- 立即改掉所有相关密码:SSH、数据库、后台、云控制台、以及这些密码复用到的任何地方。改密码要在一台干净的设备上操作。
- 切断网络或限制 SSH:如果情况严重(比如被人拿到 root 且正在横向移动),最快的方式是把机器从公网隔离——在云控制台的安全组里删掉所有入站规则,或者直接断开网络。但这会同时切断你的排查通道,所以要权衡:更温和的做法是先把 SSH 端口访问限制到你自己的 IP。
- 千万别急着关机:内存里有攻击者进程的现场、有网络连接信息,一关机这些全没了。除非攻击者正在实时破坏数据,否则保持运行、先取证。
- 保留一份快照:如果云平台支持,对磁盘做一次快照。这是给后续深度分析留的后路,成本很低。
这一步的心理难点是"想赶紧恢复正常",但你要明白:在没搞清楚攻击者怎么进来、还在不在之前就急着恢复,等于把后门留给对方,他分分钟再进来一次。
第三阶段:取证——把现场固化下来
取证的目标是搞清楚三件事:谁进来了、从哪进来的、干了什么。下面这些证据在不重启的前提下尽快收集,最好直接导出到本地或另一台机器,因为登出后某些易失信息会丢失:
# 当前的网络连接和监听端口
ss -tunap > /root/evidence/ss.txt
# 进程树,看有没有可疑父子关系
ps -ef --forest > /root/evidence/ps_forest.txt
# 所有登录日志
cp /var/log/auth.log /root/evidence/ 2>/dev/null
cp /var/log/secure /root/evidence/ 2>/dev/null
# 计划任务(攻击者最爱藏后门的地方)
crontab -l > /root/evidence/root_cron.txt
cat /etc/crontab >> /root/evidence/root_cron.txt
ls -la /etc/cron.d/ /etc/cron.hourly/ /etc/cron.daily/ >> /root/evidence/root_cron.txt
# 开机自启
systemctl list-units --type=service --state=running > /root/evidence/services.txt
# 最近被修改的文件
find /etc /usr/bin /usr/sbin /tmp /dev/shm -mtime -3 -type f 2>/dev/null > /root/evidence/recent.txt重点看计划任务和开机自启。挖矿木马、后门几乎一定要在这些地方留一个持久化入口,否则重启就没了。另一个高频后门点是 /root/.ssh/authorized_keys——攻击者会把自己的公钥加进去,就算你改了密码他照样能登录。务必检查:
cat /root/.ssh/authorized_keys
cat /home/*/.ssh/authorized_keys 2>/dev/null看到任何不认识的密钥,那就是铁证。
第四阶段:清除——按"根因顺序"清理
清理不是简单地 kill 掉恶意进程,而是切断所有持久化点,再清除载荷,顺序错了会死灰复燃。正确顺序是:
- 先断持久化:删掉恶意的 cron 条目、systemd 服务、authorized_keys 里的陌生密钥、
/etc/rc.local、/etc/init.d/下的可疑脚本。这一步不删,你 kill 完进程它下次重启或下次 cron 触发又回来了。 - 再 kill 进程:
kill -9 <pid>。如果进程杀不掉(常见于被设了不可杀或父进程守护),用ls -l /proc/<pid>/exe找到实际二进制,先删文件再 kill。 - 删文件:
/tmp、/dev/shm下的可疑文件,以及任何find出来的近期异常可执行文件。 - 查 Web 后门:如果是网站被入侵,去 web 目录找 webshell。常见的如
find /var/www -name "*.php" -mtime -7,再人工看有没有eval($_POST、base64_decode、system(这类特征。
# 找最近被改动的 webshell 特征文件
grep -rlE "eval\(|assert\(|base64_decode\(|system\(|passthru\(" \
/var/www/html --include="*.php" 2>/dev/null对个人站长来说,最现实的一句话是:如果攻击者拿到了 root 且你无法百分之百确定清干净了,重装系统是最安全的清除方式。清理一个被 root 级入侵的系统,风险在于你不知道对方是否还埋了别的后门;而重装 + 迁数据 + 修漏洞,虽然麻烦,但边界清晰。
第五阶段:加固与复盘——堵住进来的门
清除之后必须回答一个问题:他是怎么进来的?不回答这个问题,加固就是瞎猜。最可能的入口通常是这几个:
- SSH 弱密码或暴力破解:看
auth.log里有没有大量失败登录后紧跟一次成功。lastb输出能直接看出攻击的猛烈程度。 - Web 应用漏洞:老版本的 CMS、插件、上传功能是重灾区。看 access.log 里有没有异常的上传 POST 或带
eval参数的请求。 - 暴露的数据库/Redis:Redis 未设密码且监听 0.0.0.0,是被入侵的经典入口。检查
bind配置和密码。 - 泄露的密钥:代码仓库里硬编码的密码、公开目录里的
.env或备份文件。
针对性的加固动作:SSH 禁用密码登录只留密钥、装 fail2ban 封禁爆破 IP、数据库/Redis 只监听 127.0.0.1、Web 目录禁止执行上传目录里的脚本、及时更新一切组件。这套动作不是一次性的,而应该固化成日常:lynis 做定期体检、unattended-upgrades 自动打安全补丁、日志集中留存以便事后追溯。
真实复盘:一次 Redis 未授权导致挖矿的完整处置
我的一台小 VPS 装的 Redis 图省事没设密码、绑在了 0.0.0.0。某天凌晨收到云厂商告警说出口流量异常,登录一看 top 里一个叫 kdevtmpfsi 的进程吃满 CPU,还有个 kinsing 在跑。
按上面的流程走:遏制阶段先限制 SSH 到我的 IP、改掉 Redis 密码;取证阶段 ss -tulnp 看到 Redis 的 6379 确实开着、crontab -l 发现一条伪装成系统任务的下载命令、/root/.ssh/authorized_keys 里多了一个陌生公钥;ps --forest 显示 kinsing 是 kdevtmpfsi 的守护进程。清除阶段我先删 cron 条目和陌生公钥,再 kill -9 两个进程并删除 /tmp 下对应文件,最后改 Redis 的 bind 127.0.0.1 并加 requirepass。
根因非常明确:Redis 未授权访问——攻击者连上 6379 后通过 CONFIG SET dir 和 dbfilename 把恶意任务写进 cron,就拿到了 root 级执行。前后对比:处置前 CPU 常年 100%、出口流量每天几十 GB 异常;收口后 CPU 回落到 3% 以下、流量正常。方法论提炼就一条:任何监听在 0.0.0.0 且无认证的服务,都是等着被入侵的门,尤其是 Redis、Memcached、MongoDB、Elasticsearch 这几个"默认无认证"的重灾区。
应急响应检查清单
- 发现异常先取证,不要立刻删文件、不要立刻关机、不要立刻重装。
- 遏制优先级:改密码 → 限制访问 → 做快照 → 保留内存现场。
- 必查四个持久化点:
crontab、systemd 服务、authorized_keys、/etc/rc.local。 - 任何 kill 不掉的进程,先
ls -l /proc/PID/exe找到实体文件。 - root 级入侵且无法确认清干净时,重装系统是最稳妥的选择。
- 收口后一定要回答"从哪进来的",否则下次还会中招。
总结
服务器应急响应的本质,是把"慌乱的操作"替换成"有顺序的流程":确认 → 遏制 → 取证 → 清除 → 加固,五个阶段一步都不能跳,尤其取证必须排在清除之前,因为一旦删掉痕迹,你就永远不知道为什么被入侵、也就防不住下一次。对个人站长来说,日常能做的性价比最高的三件事是:SSH 只用密钥登录、所有数据库和缓存服务只监听本地且设密码、装 fail2ban 抵挡暴力破解。这三件事做到了,就能挡掉绝大多数针对个人服务器的自动化攻击——而应急响应的知识,希望你永远用不上,但一旦用上,就是救命的。