源码部署意味着你直接面对服务器底层环境,不像云服务那样有厂商帮你做底层加固。一旦Web应用、数据库或系统配置存在漏洞,攻击者可以在几分钟内完成资产扫描、漏洞利用、权限维持,甚至拖走整个数据库。排查和加固不能依赖单一扫描器,必须从代码层、中间件层、系统层、运维层四个维度逐项过筛子。下面直接进入具体操作。

1. 源码层面的高频漏洞快速定位

源码漏洞是入侵的根源。排查时不要只看框架版本,要直接审计业务逻辑。第一,SQL注入。不要只盯着GET参数,POST里的JSON、XML、甚至HTTP Header里的X-Forwarded-For、User-Agent都可能被利用。重点检查动态拼接SQL语句的地方,尤其是用了like、in、order by这类无法直接参数化的场景。如果用的是MyBatis,全局搜索${},除了明确用于动态表名且做了严格白名单校验的情况,其余一律换成#{}。第二,任意文件上传。检查上传功能是否仅依赖前端JS校验,后端必须取文件头魔数校验,而不是简单判断Content-Type。文件扩展名要用白名单,像jsp、php、asp、phtml、war这些可执行后缀必须拦截。上传后的文件名要用随机字符串重命名,存储目录关闭脚本执行权限。第三,反序列化漏洞。如果你的Java项目用了Fastjson、Jackson,或者PHP用了unserialize,立刻检查是否对用户输入进行了反序列化操作。Fastjson全系版本基本都有漏洞,要么升级到最新版并开启SafeMode,要么直接换Gson或Jackson的严格模式。第四,SSRF漏洞。凡是用户提供的URL被服务端请求,比如远程图片下载、Webhook回调地址,必须限制协议仅允许http和https,禁止file、dict、gopher这类协议。同时做DNS白名单,禁止请求内网IP段,包括127.0.0.1、10.0.0.0/8、172.16.0.0/12、192.168.0.0/16,以及169.254.169.254这类云厂商元数据地址。

2. 依赖组件与供应链安全排查

现在几乎没有项目不依赖第三方库。攻击者经常通过npm、pip、maven仓库投毒,或者利用已知漏洞组件打穿应用。第一步,生成完整的软件物料清单。Java用mvn dependency:tree,Node.js用npm ls,Python用pip freeze,把依赖列表导出。第二步,用依赖检查工具做漏洞比对。第三步,重点排查低版本的fastjson、log4j、shiro、struts2、spring framework这些重灾区组件。Log4j2的JNDI漏洞影响范围极大,确认版本号在2.17.0以上,且配置了log4j2.formatMsgNoLookups为true。Shiro的rememberMe反序列化漏洞,如果用的版本低于1.10.0,且密钥硬编码在代码里,攻击者拿到key后可以直接构造恶意Cookie执行命令。排查时搜索源码中的cipherKey,确认不是常见的base64字符串,且长度足够复杂。另外,检查是否引用了已经停止维护的库,比如moment.js、request等,这类库即使当前没漏洞,未来也不会修复,必须制定替换计划。

3. 中间件与Web服务器配置加固

Nginx、Apache、Tomcat、IIS这些中间件默认配置往往存在信息泄露或权限问题。第一,关闭版本号暴露。Nginx在http块里加server_tokens off;,Tomcat修改server.xml里的server字段,去掉版本信息。Apache在httpd.conf里设ServerTokens Prod和ServerSignature Off。第二,限制不安全的HTTP方法。在Nginx里加if ($request_method !~ ^(GET|HEAD|POST)$) { return 405; },Tomcat在web.xml里配security-constraint禁用PUT、DELETE、TRACE、OPTIONS等危险方法。第三,目录浏览和文件访问控制。Nginx默认不会列目录,但如果你配了autoindex on,立刻关掉。更隐蔽的是路径穿越,比如Nginx配置里alias和location拼接不当,可能导致/files../etc/passwd这样的请求绕过限制。检查所有alias指令,确保路径以/结尾。第四,PHP-FPM配置。如果你用PHP,检查php.ini里disable_functions是否配置了exec、system、passthru、shell_exec、popen、proc_open等高危函数。同时设置open_basedir限制PHP脚本只能访问项目目录和临时目录,防止跨目录读取。第五,Tomcat管理后台。很多运维部署完Tomcat后忘记删掉webapps下的manager、host-manager目录,或者用了默认账号tomcat/tomcat。攻击者一旦登录,直接可以部署WAR包getshell。要么彻底删除这些目录,要么修改强密码并限制访问IP。

4. 系统层权限最小化与内核参数调优

应用层再安全,系统层配错了一样被提权。第一,运行账号隔离。绝对不要用root启动Web服务。为每个站点创建独立系统用户,用systemd或supervisor管理进程,设置User和Group指令。第二,文件权限收紧。项目代码文件属主设为运行用户,权限设为644;目录权限755。配置文件如果含数据库密码,权限必须设为600,属主为运行用户。上传目录设为不可执行,用chmod -R 755去掉x权限,或者挂载分区时加noexec选项。第三,SSH加固。改掉默认22端口,禁止root直接登录,PermitRootLogin no。开启密钥认证,禁用密码登录,PasswordAuthentication no。如果必须用密码,配fail2ban防止爆破。第四,内核参数优化。编辑/etc/sysctl.conf,开启SYN Cookie防护:net.ipv4.tcp_syncookies = 1。忽略ICMP广播请求:net.ipv4.icmp_echo_ignore_broadcasts = 1。开启反向路径过滤防IP欺骗:net.ipv4.conf.all.rp_filter = 1。记录火星包:net.ipv4.conf.all.log_martians = 1。这些参数能有效防御小规模DDoS和扫描探测。第五,用iptables或nftables做白名单策略。默认DROP所有入站流量,只开放80、443以及管理端口。数据库端口3306、6379、27017这类绝对不能对公网开放。如果应用和数据库在同一台机器,MySQL绑定127.0.0.1,Redis设置bind 127.0.0.1并加requirepass强密码。

5. 数据库安全加固要点

数据库是攻击者的终极目标。MySQL在安装后会创建匿名用户和test数据库,必须删除。执行mysql_secure_installation脚本,或者手动执行DROP USER ''@'localhost'; DROP DATABASE test;。检查user表里所有用户的Host字段,不允许出现%通配符,除非业务明确需要远程访问,且必须配合IP白名单和SSL加密连接。应用连接数据库的账号权限要最小化,只给SELECT、INSERT、UPDATE、DELETE,禁止ALTER、DROP、FILE、SUPER权限。特别是FILE权限,攻击者拿到后可以通过SELECT ... INTO DUMPFILE写webshell。Redis如果没设密码,且绑定在0.0.0.0,攻击者可以直接写SSH公钥或者crontab定时任务。排查时用redis-cli连接后执行CONFIG GET dir和CONFIG GET dbfilename,确认持久化文件不会写到Web目录或/etc/cron.d下。MongoDB同样存在未授权访问问题,老版本默认无认证,必须开启auth模式并创建管理员账号。

6. 日志审计与入侵检测部署

没有日志,被入侵了都不知道怎么进来的。第一,开启Web访问日志并记录完整请求。Nginx在log_format里加入$request_body、$http_user_agent、$http_referer、$remote_addr、$http_x_forwarded_for,这样能还原攻击payload。第二,应用日志记录关键操作。登录、注册、密码修改、支付回调这些接口,必须记录用户IP、操作时间、请求参数和响应状态。第三,部署文件完整性监控。用AIDE或Tripwire对/bin、/sbin、/usr/bin、/etc、Web目录做基线快照,一旦有文件被篡改立刻告警。更轻量的方案是用inotifywait写个脚本监控Web目录新增的.php、.jsp、.war文件,发现后马上通知管理员。第四,部署开源WAF。ModSecurity配合OWASP核心规则集,虽然误报需要调优,但能拦截大部分SQL注入、XSS、命令注入攻击。如果性能敏感,可以用Nginx+Lua自写简单的拦截规则,比如检测请求参数里包含select.*from、union.*select、../../etc/passwd等特征直接返回403。第五,设置crontab定时任务。每天凌晨用clamav扫描上传目录,用rkhunter或chkrootkit检查rootkit,用lynis做系统安全评分,结果邮件推送给管理员。

7. 自动化漏洞扫描与验证流程

人工排查总有遗漏,必须建立自动化检测流水线。第一,静态应用安全测试集成到CI/CD。用SonarQube配合SpotBugs、FindSecBugs插件,在代码提交时自动扫描SQL注入、XSS、硬编码密码等问题。第二,依赖检查自动化。在Jenkins或GitLab CI里加一个stage,用Dependency-Check或Snyk扫描依赖库漏洞,发现高危组件直接阻断构建。第三,上线前动态扫描。用开源的AWVS替代品如Arachni或w3af,对新部署的站点做全量爬虫和漏洞探测。注意扫描器会产生大量脏数据和异常日志,要在测试环境执行。第四,定期渗透测试。即使有自动化工具,每季度还是要做一次人工渗透,重点测逻辑漏洞,比如越权、支付篡改、验证码绕过、密码重置劫持。这类漏洞工具扫不出来,但危害极大。测试时记得获取授权,做好隔离,避免影响生产数据。

8. 应急响应与后门清理

如果已经发现被入侵,不要急着重装系统,先做好取证和隔离。第一步,断网但不关机。用iptables临时DROP所有外部连接,保留本地终端访问,防止攻击者擦除日志。第二步,备份关键数据。用dd或tar把整个系统盘、数据库、日志文件打包存到离线存储。第三步,查找异常进程和网络连接。用netstat -anp检查有没有反弹shell连接,用ps aux找名字带空格或特殊字符的进程,用lsof -p PID看进程打开了哪些文件。第四步,检查定时任务和启动项。cat /etc/crontab、/var/spool/cron/目录、systemctl list-unit-files,找可疑的定时下载脚本。第五步,查找webshell。用grep递归搜索eval、base64_decode、exec、system、assert等函数,结合文件修改时间,重点看最近一周内新增或修改的php、jsp、asp文件。也可以用D盾、河马等webshell扫描工具做交叉验证。第六步,清理后门并修复漏洞。根据日志还原攻击路径,修复源码漏洞、升级组件、加固配置后,再重新部署。原有系统建议重装,因为提权后攻击者可能植入内核级rootkit,难以彻底清除。

9. 持续安全运营的硬核建议

安全不是一次性工作。第一,建立资产台账。用Excel或开源CMDB记录所有服务器IP、端口、服务、版本、负责人,每月更新一次。第二,漏洞预警订阅。关注CNNVD、CNVD、CVE Details以及各组件官方安全公告,发现高危漏洞24小时内评估影响范围。第三,定期演练。每半年做一次红蓝对抗或桌面推演,模拟勒索病毒加密、数据库被删、主页被篡改等场景,检验备份恢复流程和应急响应速度。第四,备份策略。数据库每天全量备份,保留30天;源码和配置文件用Git管理并推送到远程仓库;上传文件用rsync同步到异地存储。备份文件必须加密,且恢复流程要写成文档,确保任何人拿到文档都能独立完成恢复。第五,最小化原则贯穿始终。每开一个端口、装一个软件、配一个权限,都要问自己:这个真的必须吗?多一个组件就多一份攻击面。