ARTICLE DETAIL

资讯详情

深耕网站视觉设计与运营推广的一线实战洞察。

从一条异常URL拆解到日志分析:虚拟主机访问排查实战

从一条异常URL拆解到日志分析:虚拟主机访问排查实战 做网站排查的人基本都经历过这种场景翻访问日志或者后台来源数据时一抬眼扫到一行特别奇怪的记录像http://chang54188.3vzhuji.cn//a-li 常安钰 33这种。里面有看不懂的子域名路径带着短横线和中文末尾还挂一个“33”乍一看就是乱码加拼凑的产物。多数人会把这类链接当成垃圾数据直接过滤掉但我的经验是这种记录很少凭空出现尤其在小成本虚拟主机、个人项目或者产品演示站点里它往往对应着一个真实的路由入口、一段业务参数甚至是搜索引擎抓到了某个默认子域名之后引发的一系列连锁访问。这篇文章就围绕这条链接把从拆 URL、翻日志、查根目录到定位重写规则的完整排查思路讲一遍过程中会给出能直接上手的命令和判断技巧最终帮你快速判断这类记录到底是正常请求、内部跳转还是需要处理的异常流量。1. 先别急着搜把链接逐段拆开看1.1 从域名段判断网站归属和访问入口chang54188.3vzhuji.cn这个域名结构很典型根域名是3vzhuji.cn前面挂着一个自定义前缀chang54188。在国内的虚拟主机环境里很多服务商开通主机时都会默认生成一个“用户名.服务商域名”的次级地址方便客户在域名解析还没完成前先预览一下网站或者作为临时测试入口。这种地址不是用户自己注册的顶级域名更像是主机商分配的一个别名一旦建站之后没有在后台禁止访问它就会一直保留在公网上可以被搜索引擎和目录扫描器抓到。排查这种链接时第一步要明确访问者走的到底是不是你的主域名。如果在日志中看到大量请求集中在这个默认子域名上而你的正式域名访问量很低那大概率不是正常访客而是爬虫顺着子域名找到站点并开始枚举路径。此时你要做的不是去查“常安钰”是谁而是先确认该子域名是否仍然指向当前服务器、是否被搜索引擎收录以及有没有在你的站点配置里被强制跳转到主域名。1.2 路径里的双斜杠和短横线先别当目录处理路径段//a-li有两个值得注意的地方第一是双斜杠第二是短横线命名方式。HTTP 协议里大部分服务端会把相邻的斜杠合并成一个所以请求//a-li和/a-li在多数 Nginx 或 Apache 配置下最终会落到同一个资源上但日志里记录下来的原始 URI 会保留双斜杠。这意味着你直接用grep /a-li可能匹配不到所有记录需要兼容双斜杠的写法。短横线命名很像 Linux 环境下常见的目录或文件命名方式也可能是后端框架生成的路由别名。如果这是个内容管理系统a-li可能是某篇文章的拼音别名比如“阿里”文章详情页如果这是个后端服务a-li可能对应一个 API 端点或者静态文件目录。我的习惯是先在 Web 根目录下实际查一遍是否存在这个名字的物理目录或文件如果找不到再去看路由重写规则不要一开始就猜它是某个具体业务模块。1.3 “常安钰 33”在请求串中的真实角色请求记录里出现中文和数字的组合常见有三类情况一是路径参数或查询参数中的中文值被日志原样记录比如/search?q常安钰如果后端开启了日志缓冲或者用了某些中间件记录格式会变得很怪二是某个表单提交或 API 调用在 POST 请求中携带了标识信息日志框架把请求体或注释一并写入日志三是项目内部约定好的代号比如工单编号、用户 ID、页面 ID 等其中“33”更像是一个 ID 或序号。在排查阶段不要因为看到了中文人名就直接联想到个人信息或者寻找某个人这是最容易被带偏的一点。你应该把它当作一个普通的请求参数去处理重点看它的来源 IP、User-Agent、请求方法、状态码和会话信息通过这些字段组合来判断它到底来自哪一类客户端。2. 日志里的一行记录就是一套完整的访问链路2.1 先找到日志落盘位置再谈分析处理这类问题最忌讳在搜索引擎里找答案正确的做法是先找到服务器上的访问日志和错误日志。以最常见的 Linux 加 Nginx 环境为例默认日志一般存放在/var/log/nginx/access.log和/var/log/nginx/error.log。如果是 Apache则常见于/var/log/apache2/access.log和/var/log/apache2/error.log。很多虚拟主机控制面板也会在站点目录下生成独立的 access 日志文件路径格式通常是/home/用户名/logs/需要根据你使用的面板和建站方式灵活判断。确认日志路径后先不要急着全文件扫描因为 access.log 可能已经写入了上百万行。正确的姿势是先查看日志文件大小和最后修改时间确认这个记录了包含奇怪链接的日志是实时写入的旧文件还是几天前的归档文件。如果是实时文件后续分析完可以直接通过修改配置阻断异常流量如果是归档文件则说明异常访问发生在过去需要结合当时的处理内容和服务器状态综合判断不要把当下已经修复的问题误判成正在发生的攻击。2.2 用 grep 和 awk 快速把可疑记录拎出来日志分析中grep 和 awk 是最常用的两个命令足够解决大部分问题。我一般在拿到chang54188.3vzhuji.cn//a-li 常安钰 33这种记录后会分两步走第一步先确认这个地址在日志里出现的频率和首次出现时间grep -c chang54188 /var/log/nginx/access.log grep chang54188 /var/log/nginx/access.log | head -50第一条命令统计总数第二条命令看前 50 条的格式。如果总数很少比如只有几条那大概率是一次性触发可能是手工访问或者某个服务请求如果数量很多且间隔规律就值得警惕可能是脚本在批量遍历。第二步按 IP 地址聚合看请求集中在哪些来源上grep chang54188 /var/log/nginx/access.log | awk {print $1} | sort | uniq -c | sort -rnawk 提取客户端 IPsort 排序uniq 去重统计最后按次数倒序排列。正常情况下个人用户访问次数不会特别密集而爬虫或扫描工具会出现单个 IP 请求上百次的情况。这个结果能直接告诉你该不该继续深挖。2.3 结合 User-Agent、Referer 和状态码判断访问性质单纯看 URI 只能知道访问目标要判断访问性质必须把 User-Agent、Referer 和状态码放到一起看。举例来说如果 User-Agent 是空值或者包含 Python、Go-http-client、curl 等库特征那基本可以确定不是普通浏览器访客如果 User-Agent 是搜狗、百度、谷歌的蜘蛛标识那说明搜索引擎已经收录了这个子域名路径如果 Referer 是空的或来自其他站点可能是直接输入地址或者外链跳转。状态码的作用更直接。返回 200说明资源存在且正常输出需要检查资源内容是否合规返回 301 或 302说明存在重定向要顺带检查重定向目标是否可控返回 404说明当前站点映射规则里没有这个路径请求大概率是盲目扫描。我在写排查结论时一定会把这三个字段单独列出来做成表格因为这些信息比你自己猜一百次都准确。3. 顺着地址把目录结构和路由规则找全3.1 Web 根目录到底在哪别靠猜日志分析只能告诉你“谁来访问过”要弄清楚“访问到了什么”必须落到服务器文件系统里看。先定位 Web 根目录。Nginx 的站点配置常见位置是/etc/nginx/sites-enabled/或/etc/nginx/conf.d/打开配置文件后搜索root字段就能看到当前站点对应的文档根目录比如/var/www/html或/home/user/www。Apache 的配置则通常在/etc/apache2/sites-available/下DocumentRoot 字段负责指定目录。这里有一个很多人忽视的细节如果服务器上一台机部署了多个站点不同域名指向不同根目录那么你必须先判断chang54188.3vzhuji.cn这个请求到底命中了哪份配置。执行命令时最好同时查看 server_name 字段确认它是否匹配当前子域名。Nginx 中如果配置了默认站点未匹配 server_name 的请求会落到默认站点上这时日志里的 URI 路径对应的可能完全不是你预想的项目方向就全偏了。3.2 在根目录里验证“a-li”是否真实存在确定根目录后直接在根目录下查找这个路径find /var/www/html -maxdepth 3 -iname *a-li* -o -iname *ali*如果找到了同名目录打开目录里的文件看看是静态页面还是程序入口确认日志记录是否对应它的实际内容。如果找不到说明这个路径是后端路由或伪静态生成的不需要有物理对应文件直接进入下一步检查重写规则。还要注意一个情况如果目录里存在类似.git、.env、backup、config.php.bak这样的敏感文件而日志中这些路径也出现相关请求问题就不是“一条异常链接”这么简单了需要立刻检查泄露面。常规权限之下浏览器无法直接列出目录内容但如果 Web 服务器未开启禁止目录遍历的配置就很容易暴露文件清单。3.3 用 curl 复现请求走一遍真实访问流程静态判断只能说明规则存在不能证明实际访问就是这样的返回效果所以我会在服务器本机直接使用 curl 复现请求curl -I http://chang54188.3vzhuji.cn//a-li-I 参数只获取响应头方便快速查看状态码、Content-Type 和 Location 信息。如果返回 301需要带上 -L 参数跟随跳转看最终落点curl -L -I http://chang54188.3vzhuji.cn//a-li这一步非常有用。我曾经排查过一条 URL它本身返回 301Location 指向首页而首页又被安全插件拦截跳转到验证页面最后用户看到的是空白页。如果不逐步跟踪跳转链路你永远不知道这些访问到底给了访客什么结果。对于包含中文参数的情况也建议把请求中的中文做一次 URL 编码后再发起请求否则部分服务器可能因为编码不一致直接返回 400。4. 共享虚拟主机和小成本站点绕不开的四个坑4.1 默认子域名和主域名混在同一条日志里统计被带偏虚拟主机环境最让人头疼的一点就是默认子域名和正式域名经常共用一套站点文件日志也会写在同一个文件里。这样一来主域名的访问统计会导致流量数据被放大尤其是搜索引擎收录了子域名之后爬虫会一个劲儿地抓取你在子域名下的所有路径对应到访问统计里就是大量来自“莫名其妙来源”的请求。遇到这种情况应当在网站配置里把默认子域名统一 301 到主域名或者在服务商控制台关闭子域名访问入口避免流量统计被干扰。另外处理这类问题时不要把日志里的所有记录都视为“有人在攻击你”。子域名只是一个网络入口而已入口被收录被请求都是正常现象关键在于搞清楚有没有内容被错误地暴露在上述入口下。4.2 双斜杠和中文路径带来的 301/404 连锁反应双斜杠本身通常会被服务端宽容处理但在带中文参数的路径里情况就不一样了。有些后端框架在做路由解析时会先解码 URL 中的百分号编码再按斜杠分割路径段一旦参数里包含中文且未正确编码解析就会失败轻则返回 404重则触发异常。常见表现是日志里记录着请求到达但用户侧实际看到的是 404 页面两边对不上。排查时我习惯先看 Nginx 的merge_slashes配置和 Apache 的AllowEncodedSlashes配置这两个参数决定了双斜杠是否会被自动合并、编码斜杠是否会被解码。如果站点设计时就没考虑这些边界情况最简单的处理是在入口代码里做一次 URL 规范化把连续斜杠替换成单斜杠再执行路由匹配。4.3 共享 IP 环境下指纹识别能力和访问追踪受限小成本站点经常挂在共享 IP 下同一台服务器可能有几十个站点IP 访问记录并不一定能直接定位到你的站点。做安全排查时如果只根据客户端 IP 去拉黑用户很可能会误伤同 IP 下访问其他站点的正常用户反过来攻击者也能借共享 IP 隐藏自己的真实身份。所以在共享环境下做访问追踪更可靠的方式是保留完整的 Cookie 会话信息和请求指纹比如 TLS 指纹、HTTP 头顺序等不要单纯依赖 IP。实操中为了降低被误伤的概率我一般会在 Web 服务器层面对包含可疑路径的请求做限速而不是直接封 IP。例如 Nginx 里配置limit_req_zone对同一 IP 的每秒请求次数做限制这样既能阻隔批量抓取又不会影响正常用户的单次访问。4.4 日志不轮转会打爆磁盘分析时又拿不到有效数据这条链接排查不仅是一次定性问题还能顺便暴露日志管理的隐患。虚拟主机空间通常很小如果 access.log 长期不清理几个星期就能把磁盘写满。一旦磁盘满了网站会出现无法写入缓存、Session 失效、甚至直接 502 的错误。处理异常请求时如果日志文件已经膨胀到几百 MB光是用 grep 扫描一次就浪费大量时间。建议给日志配置好轮转策略Linux 系统下可以使用logrotate按天或按周切分日志并保留最近 30 天的历史文件配置示例里可以设置daily、rotate 30、compress。这样即使遇到需要回溯的异常记录也能按日期精确查文件而不是在巨型文件里漫无目的地 grep。5. 一次完整排查实操记录命令、输出与结论5.1 先设定场景再动手避免眉毛胡子一把抓为了让你看得更直观我模拟一个典型场景某台 CentOS 服务器部署了 Nginx 和 PHP 应用站点绑定正式域名www.example.com同时保留了一个服务商分配的默认子域名chang54188.3vzhuji.cn。某天在 access.log 中看到http://chang54188.3vzhuji.cn//a-li 常安钰 33开头的请求数量不多但每天都出现几条。接下来按顺序执行排查。5.2 分步执行的命令和预期输出第一步统计这个子域名在今天的日志里出现了多少次并提取最真实的请求样本grep chang54188 /var/log/nginx/access.log | grep $(date %d/%b/%Y) | head -20假设输出中有两条代表性记录123.45.67.89 - - [06/Feb/2025:10:22:31 0800] GET //a-li HTTP/1.1 200 1024 - curl/7.68.0 123.45.67.89 - - [06/Feb/2025:10:22:35 0800] GET /index.php?article_id33 HTTP/1.1 200 2048 http://chang54188.3vzhuji.cn//a-li Mozilla/5.0这两条记录信息量很大。UA 中存在 curl 的请求直接命中双斜杠路径间隔 4 秒后又有一条带 Referer 和文章 ID 的请求说明前一次请求把访问者引导到了文章详情页。这里的“33”更像是文章 ID 或者页码编号而不是用户标识。第二步查询这个 IP 的访问频率grep 123.45.67.89 /var/log/nginx/access.log | awk {print $4} | tail -20如果发现这个 IP 每分钟请求超过 30 次基本可以判定是脚本行为如果仅有这几条记录则可能是手工测试或者接口调用。上述场景里一共只有 6 条记录所以更接近开发者的手工验证。第三步到站点根目录确认路由find /var/www/html -type f -name *.php | xargs grep -l a-li 2/dev/null没有输出说明 URL 中/a-li不是物理文件。接着检查路由重写配置文件cat /var/www/html/.htaccess # 或 grep -r a-li /etc/nginx/conf.d/your-site.conf查看是否有把/a-li重写到index.php?article_id$1的规则。如果找到了结论就很清晰这条链接对应站点某篇文章的别名地址请求者是顺着某种工具或测试方式直接访问了这个入口不是恶意行为。第四步通过 curl 验证最终落点curl -L -I http://chang54188.3vzhuji.cn//a-li预期会先收到 301 或 302 跳转最终到达某篇 ID 为 33 的文章页面返回 200。到这里排查基本结束。5.3 最终结论应该怎么写结论不要只写“查过了没问题”。一个合格的排查结论至少要包含三条信息访问来源性质人工/脚本/搜索引擎、对应到站点的什么资源真实路径还是路由生成、是否需要处理屏蔽/加跳转/保持原样。基于上述模拟场景结论可以写成请求来自单一测试 IPUA 显示 curl 和浏览器两种形式访问路径/a-li经路由重写后对应文章 ID 33无目录遍历、无异常高频请求暂不需封禁建议在 Nginx 层将默认子域名统一 301 跳转到正式域名后再观察一周。6. 常见问题速查表为了后面排查类似问题时少走弯路我把这类记录处理中常见的现象、原因和处理方式整理成了表格直接查表操作即可。现象可能原因处理方式日志中大量双斜杠路径请求爬虫扫描目录、旧链接未清理检查路由合并策略必要时统一 301 到单斜杠地址URL 含中文参数但返回 404前端未对中文做 URL 编码对中文参数用encodeURIComponent处理后再拼接地址返回 200 但用户看到异常页面内部跳转被插件或安全模块拦截用 curl -L 跟随全链路找到真实落地 URL单个 IP 高频请求同一路径脚本遍历或爬虫抓取Nginx 配置limit_req_zone做速率限制默认子域名被搜索引擎收录未关闭虚拟主机默认入口配置统一跳转到主域名或后台关闭子域名访问日志条目里有中文名和数字查询参数或应用业务标识结合 UA、Referer、状态码综合分析不单独作为用户信息使用访问日志文件巨大grep 卡顿缺少日志轮转配置 logrotate按天切分并压缩归档关联请求返回 403目录权限配置过严或安全规则误拦截检查 Web 服务的 user 对目录是否可读再查安全模块规则不同 IP 轮换访问同一条路径分布式扫描行为增加频率特征分析必要时只封 UA 或路径特征避免错伤这种带子域名、中文标识和数字编号的访问记录单看一条会觉得非常诡异绝大部分情况下也不会是安全问题更多是某个旧地址、某个测试接口或者搜索引擎收录带来的残留现象。只要把链接拆开、日志拉出来、路由规则确认一遍基本就能还原整条访问链路。我个人在跑完这类排查之后通常还会顺手做一个小动作把默认子域名在 Nginx 层加一条 301 跳转到主站点再给访问日志挂上 logrotate。这样即使之后再出现类似链接也不会因为统计被带偏而反复折腾。最后分享一个我在实际操作中养成的习惯遇到任何“莫名链接”先在 memorize 在/etc/hosts和浏览器里访问一次再决定要不要深挖。很多东西你亲眼看过返回结果比在日志里看一万条记录都管用。
返回列表