nginx域名访问的白名单配置梳理

原文:http://www.cnblogs.com/kevingrace/p/6086652.html

在日常运维工作中,会碰到这样的需求:设置网站访问只对某些ip开放,其他ip的客户端都不能访问。可以通过下面四种方法来达到这种效果:
1)针对nginx域名配置所启用的端口(比如80端口)在iptables里做白名单,比如只允许100.110.15.16、100.110.15.17、100.110.15.18访问.但是这样就把nginx的所有80端口的域名访问都做了限制,范围比较大!

1
2
3
4
5
[root@china ~]# vim /etc/sysconfig/iptables
......
-A INPUT -s 100.110.15.16 -p tcp -m state --state NEW -m tcp --dport 80 -j ACCEPT
-A INPUT -s 100.110.15.17 -p tcp -m state --state NEW -m tcp --dport 80 -j ACCEPT
-A INPUT -s 100.110.15.18 -p tcp -m state --state NEW -m tcp --dport 80 -j ACCEPT

2)如果只是针对nginx下的某一个域名进行访问的白名单限制,那么可以在nginx的配置文件里进行设置,利用$remote_addr参数进行访问的分发限制,如下:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
[root@china vhosts]# cat testwww.wangshibo.com.conf
server {
        listen       80;
        server_name  testwww.wangshibo.com;
        root /var/www/vhosts/testwww.wangshibo.com/httpdocs/main;
 
 
        access_log  /var/www/vhosts/testwww.wangshibo.com/logs/access.log  main;
        error_log  /var/www/vhosts/testwww.wangshibo.com/logs/error.log;
 
 
        ##白名单设置,只允许下面三个来源ip的客户端以及本地能访问该站。主要是下面这三行
        if ($remote_addr !~ ^(100.110.15.16|100.110.15.17|100.110.15.18|127.0.0.1)) {
         rewrite ^.*$ /maintence.php last;
        }
 
        location / {
            try_files $uri $uri/ @router;
            index  index.php;
        }
     
 
        error_page   500 502 503 504  /50x.html;
 
        location @router {
            rewrite ^.*$ /index.php last;
        }
 
 
        location ~ \.php$ {
            fastcgi_pass   127.0.0.1:9001;
            fastcgi_read_timeout 30;
            fastcgi_index  index.php;
            fastcgi_param  SCRIPT_FILENAME  /scripts$fastcgi_script_name;
            #include        fastcgi_params;
            include        fastcgi.conf;
        }
 
    }
 
 
错误页面内容设置:
[root@china vhosts]# cat /var/www/vhosts/testwww.wangshibo.com/main/maintence.html
<html>
<head>
<meta http-equiv="Content-Type" content="text/html; charset=utf-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0, maximum-scale=1.0, user-scalable=no">
</head>
<body>
网站临时维护中,请稍后访问...
</body>
</html>

3)也可以使用$http_x_forwarded_for参数进行访问的分发限制,如下:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
server {
        listen       80;
        server_name  testwww.wangshibo.com;
        root /var/www/vhosts/testwww.wangshibo.com/httpdocs/main;
 
 
        access_log  /var/www/vhosts/testwww.wangshibo.com/logs/access.log  main;
        error_log  /var/www/vhosts/testwww.wangshibo.com/logs/error.log;
 
 
  ##白名单设置,只允许下面三个来源ip的客户端以及本地能访问该站。
       if ($http_x_forwarded_for !~ ^(100.110.15.16|100.110.15.17|100.110.15.18|127.0.0.1)) {
           rewrite ^.*$  /maintence.php last;
        }
         
         
        location / {
            try_files $uri $uri/ @router;
            index  index.php;
        }
     
 
        error_page   500 502 503 504  /50x.html;
 
        location @router {
            rewrite ^.*$ /index.php last;
        }
 
 
        location ~ \.php$ {
            fastcgi_pass   127.0.0.1:9001;
            fastcgi_read_timeout 30;
            fastcgi_index  index.php;
            fastcgi_param  SCRIPT_FILENAME  /scripts$fastcgi_script_name;
            #include        fastcgi_params;
            include        fastcgi.conf;
        }
 
    }

4)还可以利用nginx的allow、deny参数进行访问限制

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
[root@china vhosts]# cat testwww.wangshibo.com.conf
server {
        listen       80;
        server_name  testwww.wangshibo.com;
        root /var/www/vhosts/testwww.wangshibo.com/httpdocs/main;
 
 
        access_log  /var/www/vhosts/testwww.wangshibo.com/logs/access.log  main;
        error_log  /var/www/vhosts/testwww.wangshibo.com/logs/error.log;
 
        ##白名单设置,只允许下面三个来源ip的客户端以及本地能访问该站。
        allow 100.110.15.16;
        allow 100.110.15.17;
        allow 100.110.15.18;
        allow 127.0.0.1;
        deny all;
 
        location / {
            try_files $uri $uri/ @router;
            index  index.php;
        }
     
 
        error_page   500 502 503 504  /50x.html;
 
        location @router {
            rewrite ^.*$ /index.php last;
        }
 
 
        location ~ \.php$ {
            fastcgi_pass   127.0.0.1:9001;
            fastcgi_read_timeout 30;
            fastcgi_index  index.php;
            fastcgi_param  SCRIPT_FILENAME  /scripts$fastcgi_script_name;
            #include        fastcgi_params;
            include        fastcgi.conf;
        }
 
    }

---------------------------------nginx中remote_addr和x_forwarded_for参数使用说明---------------------------------

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
做网站时经常会用到remote_addr和x_forwarded_for这两个头信息来获取客户端的IP,然而当有反向代理或者CDN的情况下,这两个值就不够准确了,需要调整一些配置。
 
1)什么是remote_addr
remote_addr代表客户端的IP,但它的值不是由客户端提供的,而是服务端根据客户端的ip指定的,当你的浏览器访问某个网站时,假设中间没有任何代理,那么网站的
web服务器(Nginx,Apache等)就会把remote_addr设为你的机器IP,如果你用了某个代理,那么你的浏览器会先访问这个代理,然后再由这个代理转发到网站,这样web
服务器就会把remote_addr设为这台代理机器的IP。
 
2)什么是x_forwarded_for
正如上面所述,当你使用了代理时,web服务器就不知道你的真实IP了,为了避免这个情况,代理服务器通常会增加一个叫做x_forwarded_for的头信息,把连接它的客户
端IP(即你的上网机器IP)加到这个头信息里,这样就能保证网站的web服务器能获取到真实IP
 
 
-------------------使用HAProxy做反向代理----------------------
通常网站为了支撑更大的访问量,会增加很多web服务器,并在这些服务器前面增加一个反向代理(如HAProxy),它可以把负载均匀的分布到这些机器上。你的浏览器访
问的首先是这台反向代理,它再把你的请求转发到后面的web服务器,这就使得web服务器会把remote_addr设为这台反向代理的IP,为了能让你的程序获取到真实的客户端
IP,你需要给HAProxy增加以下配置:
 
option forwardfor
它的作用就像上面说的,增加一个x_forwarded_for的头信息,把你上网机器的ip添加进去
 
 
 
------------------使用Nginx的realip模块--------------------
当Nginx处在HAProxy后面时,就会把remote_addr设为HAProxy的IP,这个值其实是毫无意义的,你可以通过nginx的realip模块,让它使用x_forwarded_for里的值。使用这
个模块需要重新编译Nginx,增加--with-http_realip_module参数
 
set_real_ip_from   10.1.10.0/24;
real_ip_header     X-Forwarded-For;
上面的配置就是把从10.1.10这一网段过来的请求全部使用X-Forwarded-For里的头信息作为remote_addr
 
 
------------------将Nginx架在HAProxy前面做HTTPS代理---------------
网站为了安全考虑通常会使用https连接来传输敏感信息,https使用了ssl加密,HAProxy没法直接解析,所以要在HAProxy前面先架台Nginx解密,再转发到HAProxy做负载均
衡。这样在Web服务器前面就存在了两个代理,为了能让它获取到真实的客户端IP,需要做以下配置。
 
首先要在Nginx的代理规则里设定:
proxy_set_header   X-Forwarded-For  $proxy_add_x_forwarded_for;
这样会让Nginx的https代理增加x_forwarded_for头信息,保存客户的真实IP。
 
其次修改HAProxy的配置:
option     forwardfor except 10.1.10.0/24
这个配置和之前设定的差不多,只是多了个内网的IP段,表示如果HAProxy收到的请求是由内网传过来的话(https代理机器),就不会设定x_forwarded_for的值,保证后面的
web服务器拿到的就是前面https代理传过来的。
 
 
 
-----------------为什么PHP里的HTTP_X_FORWARDED_FOR和Nginx的不一样------------------
当你的网站使用了CDN后,用户会先访问CDN,如果CDN没有缓存,则回源站(即你的反向代理)取数据。CDN在回源站时,会先添加x_forwarded_for头信息,保存用户的真实IP,
而你的反向代理也会设定这个值,不过它不会覆盖,而是把CDN服务器的IP(即当前remote_addr)添加到x_forwarded_for的后面,这样x_forwarded_for里就会存在两个值。
Nginx会使用这些值里的第一个,即客户的真实IP,而PHP则会使用第二个,即CDN的地址。为了能让PHP也使用第一个值,你需要添加以下fastcgi的配置。
 
fastcgi_param HTTP_X_FORWARDED_FOR $http_x_forwarded_for;
它会把nginx使用的值(即第一个IP)传给PHP,这样PHP拿到的x_forwarded_for里其实就只有一个值了,也就不会用第二个CDN的IP了。
 
忽略x_forwarded_for
 
其实,当你使用了Nginx的realip模块后,就已经保证了remote_addr里设定的就是客户端的真实IP,再看下这个配置
 
set_real_ip_from   10.1.10.0/24;
real_ip_header     X-Forwarded-For;
它就是把x_forwarded_for设为remote_addr,而nginx里的x_forwarded_for取的就是其中第一个IP。
 
使用这些设置就能保证你的remote_addr里设定的一直都是客户端的真实IP,而x_forwarded_for则可以忽略了:)

---------------------------------下面简单说明下nginx location匹配规则-------------------------------------------

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
location匹配命令
~   表示执行一个正则匹配,区分大小写
~* 表示执行一个正则匹配,不区分大小写
^~ 表示普通字符匹配,如果该选项匹配,只匹配该选项,不匹配别的选项,一般用来匹配目录
=    进行普通字符精确匹配
@   定义一个命名的 location,使用在内部定向时,例如 error_page, try_files
 
=前缀的指令严格匹配这个查询。如果找到,停止搜索。
所有剩下的常规字符串,最长的匹配。如果这个匹配使用^〜前缀,搜索停止。
正则表达式,在配置文件中定义的顺序。
如果第3条规则产生匹配的话,结果被使用。否则,如同从第2条规则被使用。
 
location 匹配的优先级(与location在配置文件中的顺序无关)
= 精确匹配会第一个被处理。如果发现精确匹配,nginx停止搜索其他匹配。
普通字符匹配,正则表达式规则和长的块规则将被优先和查询匹配,也就是说如果该项匹配还需去看有没有正则表达式匹配和更长的匹配。
^~ 则只匹配该规则,nginx停止搜索其他匹配,否则nginx会继续处理其他location指令。
最后匹配理带有"~""~*"的指令,如果找到相应的匹配,则nginx停止搜索其他匹配;当没有正则表达式或者没有正则表达式被匹配的情况下,那么匹配程度最高的逐字匹配指令会被使用。
location = / {                     # 只匹配"/".
[ configuration A ]
}
 
location / {                        # 匹配任何请求,因为所有请求都是以"/"开始,但是更长字符匹配或者正则表达式匹配会优先匹配
[ configuration B ]
}
 
location ^~ /images/ {           # 匹配任何以 /images/ 开始的请求,并停止匹配 其它location
[ configuration C ]
}
 
location ~* \.(gif|jpg|jpeg)$ {         # 匹配以 gif, jpg, or jpeg结尾的请求. 但是所有 /images/ 目录的请求将由 [Configuration C]处理.
[ configuration D ]
}
***************当你发现自己的才华撑不起野心时,就请安静下来学习吧***************

(转)nginx域名访问的白名单配置梳理的更多相关文章

  1. nginx域名访问的白名单配置梳理

    在日常运维工作中,会碰到这样的需求:设置网站访问只对某些ip开放,其他ip的客户端都不能访问.可以通过下面四种方法来达到这种效果:1)针对nginx域名配置所启用的端口(比如80端口)在iptable ...

  2. xinetd黑/白名单配置教程(以telnet为例)

    对于诸如telnet等托管于xinetd的服务,当请求到来时由于是通过xinetd进行通知,所以可以直接在xinetd上配置白名单允许和拒绝哪些ip连接服务. 本文主要参考xinetd.conf的ma ...

  3. PHP 限制访问ip白名单

    一  上代码 config.php //ip白名单配置 'ipWlist'=>[ 'ifFilter'=>true, //是否开启白名单功能 'wlist'=>[ '10.0.0.1 ...

  4. nginx限速白名单配置

    在<nginx限制连接数ngx_http_limit_conn_module模块>和<nginx限制请求数ngx_http_limit_req_module模块>中会对所有的I ...

  5. 【树莓派】Squid代理以及白名单配置

    Squid安装: sudo apt-get install squid3 -y 首先,建议备份一下这个配置文件,以免配错之后,无法恢复,又得重新安装: sudo cp /etc/squid3/squi ...

  6. 项目适配iOS9遇到的一些问题及解决办法 ,以及URL 白名单配置方法

    1.网络请求报错.升级Xcode 7.0发现网络访问失败.输出错误信息 The resource could not be loaded because the App Transport Secur ...

  7. Laravel 5 如何实现网站在维护模式下允许指定 IP 用户访问(白名单)

    为了测试需要,有时候需要在网站处于维护模式下允许特定IP访问网站,在 Laravel 中,这可以通过为维护模式编写自定义中间件来实现. 默认情况下,Laravel 使用 CheckForMainten ...

  8. nginx利用geo模块做限速白名单以及geo实现全局负载均衡的操作记录

    geo指令使用ngx_http_geo_module模块提供的.默认情况下,nginx有加载这个模块,除非人为的 --without-http_geo_module.ngx_http_geo_modu ...

  9. (转)nginx利用geo模块做限速白名单以及geo实现全局负载均衡的操作记录

    nginx利用geo模块做限速白名单以及geo实现全局负载均衡的操作记录 原文:http://www.cnblogs.com/kevingrace/p/6165572.html Nginx的geo模块 ...

随机推荐

  1. 集训Day13

    我这个肥宅一点都不快乐嘤嘤嘤 bzoj3456 求n个点的无向简单连通图的个数 我们可以用容斥推出递推式 首先我们令为 于是有 这样就是可以用CDQ分治解决的一类递推式了 不是那么明显的变形一下得到 ...

  2. AndyQsmart ACM学习历程——ZOJ3870 Team Formation(位运算)

    Description For an upcoming programming contest, Edward, the headmaster of Marjar University, is for ...

  3. 开发工作之外的修炼Live笔记

    “开发工作之外的修炼”这期Live分享了下列话题: [1] 如何发现自己的兴趣 [2] 财富.资源与被动收入 [3] 目标管理 [4] 快速做选择 [5] 时间管理 [6] 如何投资自己 >&g ...

  4. AGC600 C Rabbit Exercise —— 置换

    题目:https://agc006.contest.atcoder.jp/tasks/agc006_c 考虑 \( i \) 号兔子移动后位置的期望,是 \( x_{i+1} + x_{i-1} - ...

  5. Html5 canvas 元素

    canvas 元素用于在网页上绘制图形. 什么是 Canvas? HTML5 的 canvas 元素使用 JavaScript 在网页上绘制图像. 画布是一个矩形区域,您可以控制其每一像素. canv ...

  6. 如何得到WPF中控件绑定的EventTrigger

    System.Windows.Interactivity.Interaction.GetTriggers(sender as DependencyObject)[0].Actions

  7. 组播基本概念、IGMP、IGMP监听学习笔记

    前言 一直对组播这个概念迷迷糊糊,特别是交换机处理组播的方式,非常想搞懂但是懒癌发作.这几天终于耐心地看了下有关组播的资料,大致了解了一下同一广播域内组播的相关知识.组播占了计算机网络的一大部分,特别 ...

  8. fabric添加多主机ssh互信

    最近折腾fabric,把服务器ssh互信用fabric写了一遍,单向互信,master可以无密码访问client,具体如下: 执行:fab  -f ./copyrsa.py allsshkey 即可, ...

  9. 【转】Pro Android学习笔记(二):开发环境:基础概念、连接真实设备、生命周期

    在Android学习笔记(二):安装环境中已经有相应的内容.看看何为新.这是在source网站上的Android架构图,和标准图没有区别,只是这张图颜色好看多了,录之.本笔记主要讲述Android开发 ...

  10. [51nod1065]最小正子段和

    题意:求一个序列中大于0的最小子段和. 解题关键: 先求出前缀和和,对于每个位置求某个位置到当前位置和大于1的和的最小值.然而这是复杂度是O(n^2)的.其实可以通过排序优化到O(nlogn).对前缀 ...