/ 中存储网

Nginx服务器全局变量和CC攻击防御设置

2014-04-10 14:45:01 来源:kejihao
经常需要配置Nginx ,其中有许多以 $ 开头的变量,经常需要查阅nginx 所支持的变量。

可能是对 Ngixn资源不熟悉,干脆就直接读源码,分析出支持的变量。

Nginx支持的http变量实现在 ngx_http_variables.c 的 ngx_http_core_variables存储实现

ngx_http_core_variables

  1 static ngx_http_variable_t ngx_http_core_variables[] = {

  2

  3     { ngx_string("http_host"), NULL, ngx_http_variable_header,

  4       offsetof(ngx_http_request_t, headers_in.host), 0, 0 },

  5

  6     { ngx_string("http_user_agent"), NULL, ngx_http_variable_header,

  7       offsetof(ngx_http_request_t, headers_in.user_agent), 0, 0 },

  8

  9     { ngx_string("http_referer"), NULL, ngx_http_variable_header,

 10       offsetof(ngx_http_request_t, headers_in.referer), 0, 0 },

 11

 12 #if (NGX_HTTP_GZIP)

 13     { ngx_string("http_via"), NULL, ngx_http_variable_header,

 14       offsetof(ngx_http_request_t, headers_in.via), 0, 0 },

 15 #endif

 16

 17 #if (NGX_HTTP_PROXY || NGX_HTTP_REALIP)

 18     { ngx_string("http_x_forwarded_for"), NULL, ngx_http_variable_header,

 19       offsetof(ngx_http_request_t, headers_in.x_forwarded_for), 0, 0 },

 20 #endif

 21

 22     { ngx_string("http_cookie"), NULL, ngx_http_variable_headers,

 23       offsetof(ngx_http_request_t, headers_in.cookies), 0, 0 },

 24

 25     { ngx_string("content_length"), NULL, ngx_http_variable_header,

 26       offsetof(ngx_http_request_t, headers_in.content_length), 0, 0 },

 27

 28     { ngx_string("content_type"), NULL, ngx_http_variable_header,

 29       offsetof(ngx_http_request_t, headers_in.content_type), 0, 0 },

 30

 31     { ngx_string("host"), NULL, ngx_http_variable_host, 0, 0, 0 },

 32

 33     { ngx_string("binary_remote_addr"), NULL,

 34       ngx_http_variable_binary_remote_addr, 0, 0, 0 },

 35

 36     { ngx_string("remote_addr"), NULL, ngx_http_variable_remote_addr, 0, 0, 0 },

 37

 38     { ngx_string("remote_port"), NULL, ngx_http_variable_remote_port, 0, 0, 0 },

 39

 40     { ngx_string("server_addr"), NULL, ngx_http_variable_server_addr, 0, 0, 0 },

 41

 42     { ngx_string("server_port"), NULL, ngx_http_variable_server_port, 0, 0, 0 },

 43

 44     { ngx_string("server_protocol"), NULL, ngx_http_variable_request,

 45       offsetof(ngx_http_request_t, http_protocol), 0, 0 },

 46

 47     { ngx_string("scheme"), NULL, ngx_http_variable_scheme, 0, 0, 0 },

 48

 49     { ngx_string("request_uri"), NULL, ngx_http_variable_request,

 50       offsetof(ngx_http_request_t, unparsed_uri), 0, 0 },

 51

 52     { ngx_string("uri"), NULL, ngx_http_variable_request,

 53       offsetof(ngx_http_request_t, uri),

 54       NGX_HTTP_VAR_NOCACHEABLE, 0 },

 55

 56     { ngx_string("document_uri"), NULL, ngx_http_variable_request,

 57       offsetof(ngx_http_request_t, uri),

 58       NGX_HTTP_VAR_NOCACHEABLE, 0 },

 59

 60     { ngx_string("request"), NULL, ngx_http_variable_request_line, 0, 0, 0 },

 61

 62     { ngx_string("document_root"), NULL,

 63       ngx_http_variable_document_root, 0, NGX_HTTP_VAR_NOCACHEABLE, 0 },

 64

 65     { ngx_string("realpath_root"), NULL,

 66       ngx_http_variable_realpath_root, 0, NGX_HTTP_VAR_NOCACHEABLE, 0 },

 67

 68     { ngx_string("query_string"), NULL, ngx_http_variable_request,

 69       offsetof(ngx_http_request_t, args),

 70       NGX_HTTP_VAR_NOCACHEABLE, 0 },

 71

 72     { ngx_string("args"),

 73       ngx_http_variable_request_set,

 74       ngx_http_variable_request,

 75       offsetof(ngx_http_request_t, args),

 76       NGX_HTTP_VAR_CHANGEABLE|NGX_HTTP_VAR_NOCACHEABLE, 0 },

 77

 78     { ngx_string("is_args"), NULL, ngx_http_variable_is_args,

 79       0, NGX_HTTP_VAR_NOCACHEABLE, 0 },

 80

 81     { ngx_string("request_filename"), NULL,

 82       ngx_http_variable_request_filename, 0,

 83       NGX_HTTP_VAR_NOCACHEABLE, 0 },

 84

 85     { ngx_string("server_name"), NULL, ngx_http_variable_server_name, 0, 0, 0 },

 86

 87     { ngx_string("request_method"), NULL,

 88       ngx_http_variable_request_method, 0,

 89       NGX_HTTP_VAR_NOCACHEABLE, 0 },

 90

 91     { ngx_string("remote_user"), NULL, ngx_http_variable_remote_user, 0, 0, 0 },

 92

 93     { ngx_string("body_bytes_sent"), NULL, ngx_http_variable_body_bytes_sent,

 94       0, 0, 0 },

 95

 96     { ngx_string("request_completion"), NULL,

 97       ngx_http_variable_request_completion,

 98       0, 0, 0 },

 99

100     { ngx_string("request_body"), NULL,

101       ngx_http_variable_request_body,

102       0, 0, 0 },

103

104     { ngx_string("request_body_file"), NULL,

105       ngx_http_variable_request_body_file,

106       0, 0, 0 },

107

108     { ngx_string("sent_http_content_type"), NULL,

109       ngx_http_variable_sent_content_type, 0, 0, 0 },

110

111     { ngx_string("sent_http_content_length"), NULL,

112       ngx_http_variable_sent_content_length, 0, 0, 0 },

113

114     { ngx_string("sent_http_location"), NULL,

115       ngx_http_variable_sent_location, 0, 0, 0 },

116

117     { ngx_string("sent_http_last_modified"), NULL,

118       ngx_http_variable_sent_last_modified, 0, 0, 0 },

119

120     { ngx_string("sent_http_connection"), NULL,

121       ngx_http_variable_sent_connection, 0, 0, 0 },

122

123     { ngx_string("sent_http_keep_alive"), NULL,

124       ngx_http_variable_sent_keep_alive, 0, 0, 0 },

125

126     { ngx_string("sent_http_transfer_encoding"), NULL,

127       ngx_http_variable_sent_transfer_encoding, 0, 0, 0 },

128

129     { ngx_string("sent_http_cache_control"), NULL, ngx_http_variable_headers,

130       offsetof(ngx_http_request_t, headers_out.cache_control), 0, 0 },

131

132     { ngx_string("limit_rate"), ngx_http_variable_request_set_size,

133       ngx_http_variable_request_get_size,

134       offsetof(ngx_http_request_t, limit_rate),

135       NGX_HTTP_VAR_CHANGEABLE|NGX_HTTP_VAR_NOCACHEABLE, 0 },

136

137     { ngx_string("nginx_version"), NULL, ngx_http_variable_nginx_version,

138       0, 0, 0 },

139

140     { ngx_string("hostname"), NULL, ngx_http_variable_hostname,

141       0, 0, 0 },

142

143     { ngx_string("pid"), NULL, ngx_http_variable_pid,

144       0, 0, 0 },

145

146     { ngx_null_string, NULL, NULL, 0, 0, 0 }

147 };

把这些变量提取下,总结如下:

nginx防DDOS攻击的简单配置

nginx本身就有防DDOS攻击这方面的模块ngx_http_limit_req_module和ngx_http_limit_conn_module。

一、基本介绍

1.ngx_http_limit_req_module

配置格式及说明:

设置一个缓存区保存不同key的状态,这里的状态是指当前的过量请求数。而key是由variable指定的,是一个非空的变量,我们这里使用$binary_remote_addr,表示源IP为key值。

limit_req_zone $variable zone=name:size rate=rate;

  指定要进行限制的缓存区和最大的请求到达后有多少个请求放入延迟队列(其它的直接丢弃)。如果不希望请求数达到上限而被延迟,就需要使用nodelay。

limit_req zone=name [burst=number] [nodelay];

例子:

缓存区为10M,请求限制为每秒1次,延迟队列为5

http {

limit_req_zone $binary_remote_addr zone=one:10m rate=1r/s;

...

server {

...

location /search/ {

limit_req zone=one burst=5;

}

}

2.ngx_http_limit_conn_module

  配置格式及说明:

  设置一个缓存区保存不同key的状态。我们这里使用源IP来作为key,以此限制每个源IP的链接数

limit_conn_zone $binary_remote_addr zone=addr:10m;

  指定限制的缓存区,并指定每个key的链接个数

limit_conn zone number;

  例子:

http {

limit_conn_zone $binary_remote_addr zone=addr:10m;

...

server {

...

location /download/ {

limit_conn addr 1;

}

}

二、实际应用

如果作为代理服务器,我们需要限制每个用户的请求速度和链接数量,但是,由于一个页面有多个子资源,如果毫无选择的都进行限制,那就会出现很多不必要的麻烦,如:一个页面有40个子资源,那么如果想让一个页面完整的显示,就需要将请求速度和连接数都调整到40,以此达到不阻塞用户正常请求,而这个限制,对服务器性能影响很大,几百用户就能把一台nginx的处理性能拉下来。

所以我们需要制定哪些请求是需要进行限制的,如html页面;哪些是不需要限制的,如css、js、图片等,这样就需要通过配置对应的location进一步细化。

我们不对css、js、gif、png,jpg等进行连接限制,而对除此之外的链接进行限制

http {

limit_conn_zone $binary_remote_addr zone=addr:10m;

limit_req_zone $binary_remote_addr zone=one:10m rate=5r/s;

...

server {

...

location ~ .*.(gif|png|css|js|icon)$ {

proxy_set_header Host $http_host;

proxy_set_header X-Real_IP $remote_addr;

proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;

}

location ~* .*.(jpeg|jpg|JPG)$ {

proxy_set_header Host $http_host;

proxy_set_header X-Real_IP $remote_addr;

proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;

#    image_filter resize 480 -;

#    image_filter_jpeg_quality 50;

#    image_filter_sharpen 10;

#    image_filter_buffer 4M;

}

location / {

proxy_set_header Host $http_host;

proxy_set_header X-Real_IP $remote_addr;

proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;

#limit

limit_conn addr 3;

limit_req zone=one burst=5;

}

}

Location配置简单介绍:

语法规则: location [=|~|~*|^~] /uri/ { … }

= 开头表示精确匹配

^~ 开头表示uri以某个常规字符串开头,理解为匹配 url路径即可。nginx不对url做编码,因此请求为/static/20%/aa,可以被规则^~ /static/ /aa匹配到(注意是空格)。

~ 开头表示区分大小写的正则匹配

~*  开头表示不区分大小写的正则匹配

!~和!~*分别为区分大小写不匹配及不区分大小写不匹配 的正则

/ 通用匹配,任何请求都会匹配到。