服务器攻击与防御实战指南:从DDoS到WebShell的排查与加固

📅 发布时间:2026/10/8 15:25:26
服务器攻击与防御实战指南:从DDoS到WebShell的排查与加固
干服务器运维这行越久越明白一件事你永远不知道下一分钟攻击会从哪个方向来。我接手过一台被挖矿脚本占满CPU的Web服务器半夜替电商客户处理过CC攻击打到带宽爆掉的告警也亲眼见过同事因为一条文件上传漏洞整个后台被重装成别人的“肉鸡”。服务器攻击与防御这件事表面上是工具和规则的对抗本质上是对攻击者思路的还原——你只有知道对方怎么进来的才知道该把门锁在哪里。这篇文章不打算从教科书定义讲起而是结合我自己在服务器运维、安全加固和应急排查中踩过的坑把最常见的攻击手法、防御落地步骤、排查实录和避坑清单一次说清楚。适合刚接触服务器的新手也适合做运维和开发的朋友对照着查漏补缺。1. 先从攻击面说起一台服务器到底哪里最容易被盯上很多人对攻击的理解是“黑客用工具扫一下端口然后黑进来”真实情况复杂得多。一台服务器就像一个房子门、窗、烟囱、空调外机全是入口攻击者只挑最容易撬的那个。所以做防御的第一步不是急着装一堆安全软件而是先搞清楚自己门前到底有什么“可燃物”。1.1 从一次半夜告警看攻击入口去年底有一次凌晨三点监控平台突然报警一台承载官网的ECS实例带宽跑满了。登录上去一看公网入方向流量接近2Gbps但CPU和内存占用都不高。第一反应是DDoS流量攻击可仔细看防火墙日志流量并不是单一来源而是几十个IP轮番发起大量GET请求每个请求都带着不同的随机UA头。这实际上是CC攻击——通过大量应用层请求耗尽Web服务的连接池和带宽。为什么会有这种攻击很多时候不是有人专门针对你而是你的服务器被扫描工具发现后成了批量攻击列表里的一个节点。服务器上开放的端口越少、暴露的服务越少被盯上的概率就越低。所以我现在的项目中第一件事永远是资产清点这台服务器上跑了哪些服务监听哪些端口哪些端口是必须对公网开放的哪些其实只在内网用。提示你永远不知道你的服务器IP被扫描了多少次。只要公网可达扫描器每几分钟就会来一轮这是常态。1.2 端口、服务与资产清点的具体做法资产清点听起来简单实际做起来需要耐心。我通常用下面的办法用ss -tlnp或netstat -tlnp查看当前监听的端口和对应的进程这一步是摸清家底。对照业务清单逐一确认每个端口是否必须对外开放不认识的进程要查清来源。对公网开放的端口做服务版本登记比如 Nginx 1.20、OpenSSH 8.2、MySQL 5.7版本号是后续判断漏洞影响范围的关键。记录域名、证书、CDN、回源IP之间的关系防止出现“CDN背后裸奔”的情况。有一次我排查一台数据库服务器发现3306端口对公网开放。一问才知道是当初为了方便本地调试直接在安全组里加了0.0.0.0/0放行规则。这种端口暴露在公网上等同于把金库大门敞开着任何人都能拿工具尝试暴力破解。1.3 攻击面梳理的隐患盘点攻击面不光是端口还包括几个容易被忽略的点默认口令和弱口令。很多人觉得“密码长一点就安全”但像root/123456、admin/admin这种组合在暴力破解工具字典里排在最前面。管理后台暴露在公网。比如 WordPress 后台、Tomcat Manager、phpMyAdmin任何一个都可以成为突破口。敏感信息泄露。网页源码注释、接口报错信息、备份文件.bak/.sql被直接放在web目录下等于把地图送给了攻击者。第三方组件版本过旧。比如某个开源CMS用了老版本已知漏洞直接可查攻击者根本不需要多高深的技术。把这些点记下来之后攻击面才算真正清楚。接下来看具体攻击手法时就有的放矢了。2. 常见攻击手法与底层逻辑防御的前提是理解攻击。我挑了几个在真实业务中高频出现的类型每个都结合我处理过的案例来讲尽量不说空话。2.1 流量型攻击DDoS与CC攻击的典型特征DDoS和CC攻击经常被混为一谈其实触发层级完全不同。DDoS主要打网络层和传输层比如SYN Flood、UDP Flood目的是把带宽和交换机处理能力耗尽让正常用户连不上。CC攻击打的是应用层模拟真实用户请求不停请求某个动态接口或搜索接口把CPU、数据库连接池打满网站响应变慢甚至直接502。我在处理一次CC攻击时发现攻击方只盯着一个URL重复请求这个URL是会员中心的查询接口。当时上游WAF没有配频控导致每个请求都正常转发到后端数据库连接瞬间被打穿。后面加了针对该接口的单IP每秒请求数限制同时在Nginx层做了队列深度控制情况立刻缓解。注意CC攻击比DDoS更隐蔽因为流量特征和正常用户很像光看带宽看不出问题要看每个请求的频次、UA分布、来源IP聚合度。2.2 文件上传攻击为什么总被低估文件上传攻击是我在Web安全项目里最常遇到的漏洞之一。基本原理是借助上传功能攻击者上传一个包含恶意代码的文件比如PHP一句话木马、JSP后门如果服务器把文件解析执行了攻击者就拿到了WebShell相当于在服务器里安了一个“远程遥控器”。真实的攻击流程通常是这样的攻击者找到一个上传点头像上传、附件上传、导入功能上传一个伪装成图片的脚本文件访问这个文件路径使脚本被解析执行然后通过WebShell执行系统命令。我去帮一个客户排查时发现他们的上传目录里躺着一个名为avatar.jpg的文件后缀是jpg但文件头尾被拼接了PHP代码。原因就是上传时只校验了Content-Type前端可控没有校验文件真实内容而且上传目录还开了脚本执行权限。防御上我目前比较认可的组合是白名单后缀校验加上MIME类型校验、文件重命名脱离可控路径、上传目录禁止执行脚本、文件存储和Web解析目录分离。这四个动作做完大部分文件上传绕过手段就失效了。2.3 SSRF攻击内网跳板是怎么打出来的SSRF服务端请求伪造是很多应用层漏洞里比较特殊的一个。它利用的是服务器自身发起的请求让服务器去访问攻击者指定的内网或外部地址。由于请求是从服务器发出的很多防火墙规则会认为这是“可信流量”于是攻击者就能借服务器这个“跳板”探测内网。最典型的场景是图片处理功能用户提交一个URL服务器去抓取图片。如果这个功能没有做域名白名单和IP限制攻击者可以传http://127.0.0.1:3306来探测本机数据库端口甚至传http://10.0.0.5/来扫描内网其他主机。我遇到过一台服务器通过这种漏洞被读取了内网云元数据接口从而拿到了临时凭证。防御的核心不是简单屏蔽localhost而要限制请求目标只允许访问特定协议不留file协议、特定端口白名单、特定域名白名单并禁止302跳转跟随、禁止访问内网IP段。2.4 反序列化攻击看起来没事的接口最危险反序列化攻击在一线业务里不算高频但一旦发生往往就是管理员权限级别的沦陷。很多开发对“序列化”不敏感觉得就是把对象变成字符串存起来但反序列化是把字符串恢复成对象的过程如果数据源不可信攻击者就能构造恶意内容在恢复过程中触发危险方法。Java、PHP、Python都有对应的反序列化利用链。比如Java里常见的攻击点是把序列化后的对象直接交给ObjectInputStream.readObject()处理攻击者构造好某个存在漏洞的类让服务器在反序列化时执行命令。排查这类问题时我一般会重点看代码里是否对反序列化数据做了签名校验以及是否引入了容易被利用的组件库。防御上最有效的方法是不接受不可信来源的反序列化数据如果必须接受使用白名单类过滤比如ObjectInputFilter或改成JSON等安全格式传输。这个问题最大的难点在于它不是“一眼就能看出来”的漏洞代码审查时要留意所有接收二进制数据的入口。2.5 注入类与WebShellXSS、SQL注入的防御思路XSS和SQL注入属于老生常谈但我不打算略过因为实际项目里“换了马甲”的注入依然很多。XSS的核心是用户输入被当作页面内容输出导致脚本在他人浏览器里执行。SQL注入的核心是用户输入被拼进SQL语句导致数据库被拖走或篡改。两者的共同点是对输入过于信任。前几年我审计过一个后台登录后的搜索框直接把参数拼到SQL里当时用 OR 11 --一测试就出数据。后来整改时统一封装了参数化查询开始引入ORM约束。对于XSS主要还是输出端的编码转义要到位前端框架自带的防XSS机制不要随意关闭。3. 防御体系落地方案从基线加固到纵深防御攻击手法学完接下来就是动手防。防御不能靠单点必须一层一层叠起来这也就是常说的纵深防御。3.1 系统层基线加固系统层的基础打不牢上层做再多都白搭。我建议按下面的顺序逐项落实禁用root远程登录改用普通用户加sudoSSH使用密钥认证。定期应用系统更新和安全补丁关键漏洞要优先修复。关闭不必要的系统服务用firewalld或iptables只放行必要端口。设置合理的文件权限web目录的写入权限尽量收窄。修改默认端口或使用Fail2ban等工具对暴力破解做自动封禁。我实际操作中会把SSH端口改到高位并开启密钥登录虽然不能彻底防住扫描但能把自动爆破的流量挡掉一大半。改端口不是安全手段只是减小暴露面真正的防线是密钥和访问来源限制。# 以CentOS/RHEL系为例允许指定IP段访问SSH端口 firewall-cmd --permanent --add-rich-rulerule familyipv4 source address10.10.0.0/16 port port2222 protocoltcp accept firewall-cmd --permanent --remove-servicessh firewall-cmd --reload3.2 网络层与接入层防御网络层防御重点在入口也就是防火墙和安全组。这里有两个容易踩的坑第一个是安全组规则配得过于宽松比如把某个端口对所有IP开放第二个是只关注入方向忽略了出方向服务器被入侵后向外发起的攻击流量没人管。我在给一个项目做加固时直接把出方向默认拒绝只放行必要的DNS、HTTPS和软件源端口。这样即使WebShell执行成功了攻击者想连外网下载工具也会因为出方向被限制而失败较多。接入层方面有条件就上WAF配合IP黑白名单、地区封禁、频率限制和CC防护规则。如果预算有限先用Nginx层的限速和访问控制顶上# 限制同一IP每分钟请求数超过后返回503 limit_req_zone $binary_remote_addr zonereq_one:10m rate30r/m; server { listen 80; server_name example.com; location /api/ { limit_req zonereq_one burst20 nodelay; proxy_pass http://backend; } }3.3 应用层控制输入、输出、权限三板斧到应用层防御动作要落到代码和配置里主要盯三件事输入校验所有外部参数做合法性校验包括长度、类型、取值范围。能走白名单就不要用黑名单。输出编码动态内容输出到页面时做好HTML实体编码防止XSS拼接SQL时全部参数化。权限控制接口遵循最小权限同一个接口不能既是普通用户入口又是管理员入口。文件读写权限也要注意。我见过有项目把/data/upload配成了777权限导致WebShell上传后还能被修改执行。我通常会把上传目录的owner固定为某个低权限用户并禁止脚本解析。3.4 运维层监控、日志与备份监控和日志是防御体系中偏“事后”的环节但很多攻击在爆发之前都是有前兆的。我推荐的监控指标包括CPU和内存使用率、带宽出入方向、数据库慢查询、Web日志中4xx/5xx状态码占比、登录失败次数、关键文件完整性。日志采集上我习惯用“三份日志”方案操作系统日志、Web访问日志、应用日志分别落盘和集中存储。Web访问日志至少保留90天建议每日做日志切割防止单文件过大导致问题。备份则要保证“异地多版本”至少有一个ecph存到对象存储里不能和服务器在同一台机器上否则服务器被勒索加密时备份也会被一起加密。提示备份之前先测恢复。不要等到服务器真的挂了才发现备份文件是坏的这个坑我替客户踩过一次数据恢复不了时整个人是崩溃的。4. 攻击模拟、排查与应急实录纸上谈兵结束这才是真正考验运维能力的地方。我平时会做大量的攻击模拟和故障演练为的是真出事时不慌。4.1 如何模拟一次DDoS/CC攻击并验证防御效果不推荐在线上环境直接做破坏性测试我一般在预发布环境或单独的测试机上进行。先用压测工具模拟高并发请求观察Nginx配置的限速是否生效再用ab/Wrk这类的工具构造高频请求验证WAF的CC防护规则是否响应。模拟时要关注三个指标一是服务器是否还能正常响应非被攻击的接口二是CPU和内存是否处于安全水位三是误杀率也就是正常用户请求有没有被误伤。有一次我配了过于严格的限速策略每IP每分钟只许5个请求测试时发现正常用户翻页都会触发503业务直接没法用。后来把rate放宽到60r/m才找到平衡点。4.2 服务器被“打挂”后如何快速定位原因服务器出现过一次“打挂”的情况很多人的第一反应是“是不是被DDoS了”。实际上不一定可能是代码死循环、数据库连接泄漏、磁盘写满等多种原因。我一般按下面的顺序排查先用uptime和top/htop看系统负载如果CPU或内存被占满初步判断是计算资源耗尽。用ss -antp查看连接数如果大量SYN_RECV或ESTABLISHED连接异常大概率是流量型攻击或连接池失控。用sar或iftop看流量和带宽结合时间点和Web日志里的请求集中度判断是DDoS、CC还是爬虫。最后看应用日志如果有大量超时或异常报错优先查代码层面的瓶颈。有一次客户报“H5页面打不开”我查下来发现是磁盘被日志写满了df -h显示使用率100%。这不是攻击而是日志轮转配置没生效造成的“自伤”。所以排查时先别急着甩锅给攻击多个指标对比着看才靠谱。4.3 疑似被入侵后的止血与溯源流程一旦确认服务器被拿下时间就是生命。我建议按下面的流程走每一步都要留下证据立即将被感染的主机从对外服务中摘除可以停机或断开外网避免攻击者持续控制。保留现场给系统盘做镜像或快照保护内存和日志不被破坏。收集入侵线索last登录记录、/var/log/auth.log或 secure日志、crontab任务、启动项、异常进程和安全工具的告警信息。查WebShell在web目录下搜索最近修改的php/jsp/aspx文件重点检查后缀伪装、内容中包含eval/system/base64函数调用的文件。溯源分析判断是通过哪里进来的弱口令漏洞供应链找到根因后再做系统重装或修复。查找WebShell时可以先用命令扫描定位可疑文件后再人工判断# 搜索web目录下最近7天内修改过的脚本文件 find /data/www -name *.php -mtime -7 # 搜索常见的危险函数调用需配合人工确认 grep -rlE eval\(|assert\(|system\(|shell_exec\(|passthru\( /data/www --include*.php注意WebShell扫描的结果只能作为线索不是命中就一定是恶意文件。部分框架源码本身就会调用这些函数必须人工确认。4.4 常见问题速查表我在多个项目里梳理过一批高频问题整理成表格方便对照排查。问题现象可能原因排查方法带宽被占满CPU不高DDoS流量攻击iftop看IP分布联系机房或云厂商上高防CPU高但带宽正常CC攻击或Web代码死循环看Web日志请求集中度配合Nginx限速数据库连接数打满SQL查询未优化或连接池泄漏show processlist分析慢SQL重启后观察登录日志中有大量失败记录暴力破解启用密钥登录配合Fail2ban自动封禁页面被植入非法广告WebShell或篡改全线扫描WebShell检查文件修改时间上传目录出现可疑脚本文件上传漏洞立即禁用目录脚本解析整改上传校验内网被外部访问SSRF或端口暴露收严出网策略检查应用层URL请求校验服务器被加密文件后缀勒索病毒先隔离断网从备份恢复排查感染源这张表里的每一项我都实际处理过对照着查能省很多时间。但真正的经验不是这张表本身而是判断问题时的思路先看整体指标再缩小范围最后落到具体日志和代码。5. 几个让我印象深刻的踩坑经历说了这么多还是想分享几个特别典型的坑。第一个是“改了安全组就万事大吉”的心态。有次客户配置好安全组觉得防护到位了结果没留意服务器本机的防火墙是关闭状态。安全组过滤的是云平台层面的流量但服务器本地防火墙关了等于外面的防线再强内部的门没锁。后来我都是安全组和本机防火墙两手抓缺少任何一个都不算数。第二个坑是“日志没有同步出事后无从查起”。有一次某台服务器被入侵我想看攻击者的进入路径结果发现这台机器根本没开日志收集原有的auth日志因为磁盘满了被轮转清掉。从那以后我接手的每台服务器第一件事就是确认日志有没有集中存储时间同步有没有配好。没有日志的服务器出了事就是“无头悬案”。第三个坑是“只防外部不看内部”。很多团队默认内部网络是安全的导致数据库、Redis、管理后台的密码常年不换防火墙也不设内部隔离。结果攻击者通过一个前台文件上传漏洞进来后在内网横向移动如入无人之境。防御一定要有纵深内部服务和外部流量一样要做鉴权和访问控制。6. 最后的几点个人体会做了这些年服务器攻击与防御相关的工作我最大的体会是安全不是装几个软件、开几个服务就完事的它是一个持续的、需要融进日常操作习惯的事情。哪怕一台服务器只跑一个小网站也应该按照“清点资产—收紧暴露面—持续监控—及时响应”的节奏来维护。如果你刚接手一台服务器可以从今天就开始做三件事检查开放端口和登录方式、确认日志是否集中存储和轮转、给系统盘和数据库做一次可验证的备份。这三件事花不了几个小时但能在很多场景下救命。我在实际运维中遇到的事故多数都不是因为攻击者技术多高明而是因为基础工作长期欠账。把地基打好绝大多数攻击都会在门口被挡下来。