前言:
在查看 nginx 日志时,经常会发现一种攻击方式,攻击者不使用 GET 或 POST 方法,而是使用了一个 16 进制伪码:\0x01 作为请求方法。这种攻击的目的是使服务器溢出,并导致大量的 400 bad request 包外流。因此,最好的方式来应对这种攻击就是直接断开连接。
配置方式
下面代码放进 http{ }段内
map $request_method $ban_method{
default 1;
GET 0;
POST 0;
}
下面代码放进 server{}段内
if ( $ban_method = 1 ) {
return 444;
}
444: Nginx上的 HTTP 服务器扩展。服务器不向客户端返回任何信息,并关闭连接,以防止恶意软件的威胁。
map 指令说明:
map 指令是由 ngx_http_map_module 模块提供的,默认情况下,安装 nginx 时会自动安装该模块。
map 的主要作用是创建自定义变量,通过使用 nginx 的内置变量,匹配特定规则,如果匹配成功,则将某个值设置给自定义变量。而这个自定义变量可以在其他地方使用。
下面是一个例子,可以更清楚地理解:
场景:匹配请求的 URL 参数,如果参数是 debug,则设置$foo 为 1,否则默认设置$foo 为 0。
map $args $foo {
default 0;
debug 1;
}
解释:
$args 是 nginx 内置变量,就是获取的请求 url 的参数。 如果 $args 匹配到 debug 那么 $foo 的值会被设为 1 ,如果 $args 一个都匹配不到 $foo 就是 default 定义的值,在这里就是 0
map 语法
map $var1 $var2 {…}
map 指令的三个参数:
2、hostnames : 允许用前缀或者后缀掩码指定域名作为源变量值。这个参数必须写在值映射列表的最前面。
3、include : 包含一个或多个含有映射值的文件。
在 Nginx 配置文件中的作用段: http{} ,注意 map 不能写在 server{} 否则会报错
map 的 $var1 为源变量,通常可以是 nginx 的内置变量,$var2 是自定义变量。 $var2 的值取决于 $var1 在对应表达式的匹配情况。 如果一个都匹配不到则 $var2 就是 default 对应的值。
一个正则表达式如果以 “~” 开头,表示这个正则表达式对大小写敏感。以 “~*”开头,表示这个正则表达式对大小写不敏感。
map $http_user_agent $agent {
default "";
~curl curl;
~*apachebench" ab;
}
正则表达式里可以包含命名捕获和位置捕获,这些变量可以跟结果变量一起被其它指令使用。
map $uri $value {
/abc /index.php;
~^/teacher/(?<suffix>.*)$ /boy/;
~/fz(/.*) /index.php?fz=1;
}
注意:不能在 map 块里面引用命名捕获或位置捕获变量。如~^/qupeicom/(.*) /peiyin/$1; 这样会报错 nginx: [emerg] unknown variable
注意二:如果源变量值包含特殊字符如‘~’,则要以‘\’来转义。
map $http_referer $value {
Mozilla 111;
\~Mozilla 222;
}
源变量匹配表达式对应的结果值可以是一个字符串也可以是另外一个变量。
map $http_referer $value {
Mozilla 'chrom';
\~safity $http_user_agent;
}
实例(一)
使用 map 来实现允许多个域名跨域访问的问题
如果是允许单域名跨域访问直接配置就行了,如下:
add_header Access-Control-Allow-Origin “http://www.tutu.com”;
add_header Access-Control-Allow-Methods “POST, GET, PUT, OPTIONS, DELETE”;
add_header Access-Control-Max-Age “3600”;
add_header Access-Control-Allow-Headers “Origin, X-Requested-With, Content-Type, Accept;
上面的配置只允许 http://www.tutu.com 跨域访问,如果要支持所有域名都可以跨域调用该站。 把上面一行改成这样,不过不推荐这样做,因为不安全
add_header Access-Control-Allow-Origin "*";
如果不想允许所有,但是又需要允许多个域名,那么就需要用到 map
map $http_origin $corsHost {
default 0;
"~https://www.huizhanii.com/" https://www.huizhanii.com/;
"~https://www.huizhanii.com/" https://www.huizhanii.com/;
"~https://www.huizhanii.com/" https://www.huizhanii.com/;
}
server
{
listen 80;
server_name www.huizhanii.com;
root /nginx;
location /
{
add_header Access-Control-Allow-Origin $corsHost;
}
}
实例(二)
使用源变量(通常是 nginx 内置变量)匹配一些规则,创建自定义变量,然后在页面输出. 这通常在调试的时候非常有用
http {
map $uri $match {
~^/hello/(.*) http://www.hello.com/;
}
}
server {
listen 8080;
server_name test.hello.com;
location /hello {
default_type text/plain;
echo uri: $uri;
echo match: $match;
echo capture: ;
echo new: $match;
}
}
map 涉及的性能问题并不会对所有虚拟主机的请求都产生性能损失。只有在请求中使用到相关变量时,才会执行 map 操作。这样可以避免不必要的计算,提高性能。
当存在多个匹配的特定变量时,会按照以下顺序进行选择:
2. 最长的带前缀的字符串,例如: “.example.com”
3. 最长的带后缀的字符串,例如:“mail.”
4. 按照配置文件中的顺序,选择第一个匹配的正则表达式。
转载请注明:汇站网 » Nginx 强化防范 HTTP 伪请求头攻击