CodeIgniter站点日志出现异常404错误求助
让我帮你拆解下这个问题——你日志里的这些404请求分两类,成因和解决方式各有不同,咱们一个个说:
第一类:存在的文件但请求路径畸形(比如Apple-touch-iconpng/index)
这类请求的核心问题是:原本的文件名丢失了点(比如apple-touch-icon.png变成了Apple-touch-iconpng),还多了个/index后缀。这大概率是爬虫或者恶意扫描工具的错误请求——它们在构造请求时误删了文件名里的点,再加上你的.htaccess重写规则,这些请求被转发到CodeIgniter的index.php,最终触发框架的404。
少数情况也可能是老旧浏览器或有bug的客户端请求站点图标时的异常行为,但扫描工具的可能性更高。
第二类:完全不存在的随机路径(比如404testpage4525d2fdc/index)
这类明显是自动化扫描工具在枚举你的站点路径,试图找漏洞入口或未公开页面。它们会生成大量随机字符串的路径,这些请求自然会被框架判定为404。
为什么前台没显示404,只有日志有记录?
因为这些请求都不是正常用户点击站内链接产生的,而是外部直接发送到服务器的异常请求。你的站点内部链接都是正确的,所以用户访问时完全不会碰到这些问题,只有服务器日志会记下这些扫描行为。
解决方案:
1. 修复站点图标类的畸形请求
在你的.htaccess现有规则之前,添加专门的重定向规则,把丢失点的请求导向正确的文件:
# 修复丢失点的站点图标请求,重定向到正确文件 RewriteRule ^Apple-touch-iconpng/?(.*)$ /apple-touch-icon.png [R=301,L] RewriteRule ^Faviconico/?(.*)$ /favicon.ico [R=301,L]
这样既能减少不必要的404日志,也能让发送畸形请求的客户端拿到正确的图标。
2. 拦截恶意扫描的批量请求
如果这类随机路径的请求量很大,可以用以下方式限制:
- 用.htaccess做简单的频率限制(需要服务器启用mod_rewrite和mod_unique_id):
# 限制单个IP10秒内最多5次非静态文件请求,超过则返回403 RewriteEngine On RewriteCond %{REMOTE_ADDR} ^(.*)$ RewriteCond %{TIME_MINUTE} ^(.*)$ RewriteCond %{REQUEST_URI} !^/apple-touch-icon\.png$ RewriteCond %{REQUEST_URI} !^/favicon\.ico$ RewriteCond %{REQUEST_FILENAME} !-f RewriteCond %{REQUEST_FILENAME} !-d RewriteCond %{ENV:REQTIME_%1_%2} !^$ RewriteCond %{ENV:REQTIME_%1_%2} >5 RewriteRule ^ - [F,L] RewriteCond %{REMOTE_ADDR} ^(.*)$ RewriteCond %{TIME_MINUTE} ^(.*)$ RewriteRule ^ - [E=REQTIME_%1_%2:%{ENV:REQTIME_%1_%2}+1] - 自定义CodeIgniter的404处理:把路由里的
$route['404_override'] = '';改成$route['404_override'] = 'errors/custom_404';,然后创建一个Custom_404控制器,在里面记录请求的IP、User-Agent等信息,甚至可以自动拉黑频繁发送异常请求的IP。
3. 优化现有重写规则
你的.htaccess规则是CodeIgniter的标准写法,但可以微调下,减少框架的不必要处理:
RewriteEngine On # 排除已存在的文件和目录 RewriteCond %{REQUEST_FILENAME} !-f RewriteCond %{REQUEST_FILENAME} !-d # 直接排除站点图标,不用走框架 RewriteCond %{REQUEST_URI} !^/(apple-touch-icon\.png|favicon\.ico)$ # 转发到index.php(去掉多余的问号,更符合CodeIgniter规范) RewriteRule ^(.*)$ index.php/$1 [L]
总结
这些异常404本质上是外部扫描或畸形请求,不会影响正常用户体验,但通过上面的方法,你可以优化日志清晰度、减少服务器资源消耗,甚至拦截恶意扫描。如果后续请求量突然暴增,建议检查服务器防火墙,或者用CDN的WAF功能进一步拦截。
内容的提问来源于stack exchange,提问作者falc2

