HTTP 400错误表示"Bad Request",即服务器无法理解客户端发送的请求。以下是分析和解决Nginx日志中出现大量400错误的方法:
请求头过大
无效的Host头
URL过长
无效的HTTP协议
恶意请求
http {
# 增大请求头缓冲区大小(默认1k)
client_header_buffer_size 4k;
# 增大大型请求头的缓冲区(默认8k)
large_client_header_buffers 4 16k;
# 限制请求体大小(默认1m)
client_max_body_size 10m;
# 设置允许的URI长度(默认无限制,但实际受缓冲区限制)
# client_header_buffer_size和large_client_header_buffers共同决定
}
server {
# 只允许特定Host头
server_name example.com;
# 拒绝空Host头或无效Host头
if ($host = "") {
return 444; # 直接关闭连接
}
# 或者返回400错误
if ($host !~* ^(example.com|www.example.com)$ ) {
return 400;
}
}
location / {
# 只允许常见HTTP方法
limit_except GET POST HEAD {
deny all;
}
}
# 阻止包含可疑内容的请求
if ($http_user_agent ~* (nmap|nikto|wikto|sf|sqlmap|bsqlbf|w3af|acunetix|havij|libwww-perl) ) {
return 403;
}
# 阻止包含大量特殊字符的URL
if ($request_uri ~* "[<>{}|^~\\[\\]]") {
return 400;
}
检查Nginx错误日志获取更多细节:
grep "400" /var/log/nginx/error.log | awk -F '"' '{print $2}' | sort | uniq -c | sort -nr
配置fail2ban来阻止频繁返回400错误的IP:
[nginx-badrequest]
enabled = true
filter = nginx-badrequest
action = iptables-multiport[name=nginx-badrequest, port="http,https", protocol=tcp]
logpath = /var/log/nginx/access.log
maxretry = 10
findtime = 3600
bantime = 86400
通过以上措施,您应该能够显著减少Nginx服务器上的HTTP 400错误。如果问题仍然存在,可能需要更深入地分析具体的请求内容来定位问题根源。