现在的位置: 首页 > 综合 > 正文

http code 400

2012年09月26日 ⁄ 综合 ⁄ 共 1080字 ⁄ 字号 评论关闭

最近服务器异常,nginx访问日志中出现大量的如下形式的请求:

x23.1x3.21x.xx - - [08/Jun/2012:04:46:39 +0800] "-" 400 0 "-" "-"
x23.1x3.21x.xx - - [08/Jun/2012:04:46:39 +0800] "-" 408 0 "-" "-"

每天这种请求大概占请求量的50%左右。
在php代码中,未定义400的异常,因此可以判定非php抛出。

网上查的出现这种日志主要有如下原因:

  1. 请求头过长,尤其是在cookie过多的情况下。
  2. chrome的preconnect技术,会生成大量的如上日志。
  3. no Host header sent

1. 请求头过长,那么可以修改nginx的请求头参数设置到一个合理的值。

参数: 

client_header_buffer_size 64k;
large_client_header_buffers 4 32k;

但是事实上一般不会出现这种错误,因为nginx资深设置的请求头一般够用。

除非你定义了大量的cookie。

2. chrome preconnect

如果是因为chrome的原因,有个很明显的特征:在每个400 0请求之前的请求user-agent='chrome'

而且这个是无解的。

3. no host header sent.

主要是指ip扫描工具,扫描当前机器ip,会生成一个请求,header中无host

如下脚本,就可以生成:

#!/bin/bash
exec 8<>/dev/tcp/openapi.360.cn/443
echo -ne "" >&8
cat <&8 

我们可以通过定义一个default_server来接受所有的ip请求。

server {
        listen 80 default_server;
        server_name _;
        access_log off;
        location / {
            deny all;
        }        
    } 

这样所有的ip请求被抛到default_server中,且关闭了日志。

这样这些烦人的"400 0"就不见了

说到这里,问题就基本解决了。但是还有一项事情要注意:

https服务器必须加入ssl_certificate, ssl_certificate_key两个参数

server {
    listen 443 ssl default_server;
    server_name _;
    ssl_certificate      /usr/local/nginx/conf/ssl/edward.crt;
    ssl_certificate_key  /usr/local/nginx/conf/ssl/edward.key;
    access_log off;
    location / {
        deny all;
    }
}

抱歉!评论已关闭.