Nginx访问控制
要实现用Nginx对WebServer做访问控制,常见的有两种方式
基于IP的访问控制 : http_access_module 允许哪些IP可以访问 , 不允许哪些IP可以访问
基于用的的信任登录 : http_auth_basic_module 通过用户的登录认证界面提供一个用户认证来控制用户的访问
一、基于IP的访问控制
ngx_http_access_module模块
模块ngx_http_access_module允许限制某些IP地址的客户端访问。也可以使用“密码”来限制访问,使用 “satisfy” 指令就能同时通过IP和密码来限制访问。
配置示例
location / {
deny 192.168.1.1;
allow 192.168.1.0/24;
allow 10.1.1.0/16;
allow 2001:0db8::/32;
deny all;
}
规则按照顺序一次检测,直到匹配到第一条规则。在这个例子里,IPv4的网络中只有10.1.1.0至10.1.1.16和192.168.1.0至192.168.1.24可以访问,但192.168.1.1不可以访问,IPv6的网络,只有2001:0db8::/32允许访问。在规则很多的情况下,使用 ngx_http_geo_module 模块变量更合适。
ngx_http_access_module局限性
如果我们访问不是客户端与服务端的直接连接,而是通过了一层"代理(可能是Nginx负载均衡、LSB、CDN)"来访问我们的服务端,这样的话可能就会出现一个问题,因为nginx的http_access_module它是基于remote_addr这个变量来进行识别客户端的IP,那么如下图,最终nginx的remote_addr变量并不是IP1这个客户端的IP,所以我们使用http_access_module限制某些IP地址的客户端访问是没有起到作用的,而直接是对"代理"做到了限制,这就是局限性。
ngx_http_access_module局限性解决方案
方法一:采用别的HTTP头信息控制访问 , 如 http_x_forwarded_for
http_x_forwarded_for是http常用的一个变量,必须HTTP请求头中携带了"X-Forwarded-For"参数,Nginx才能获取到$http_x_forwarded_for变量,Nginx做代理转发服务的时候,需要在HTTP请求转发的时候设置header头:
server {
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
}
$proxy_add_x_forwarded_for; nginx的这个变量含义就是,每次都追加$remote_address 到 xff头,如果xff头不存在,那么xff就被设置成跟$remote_address 一样了。如果本来就存在,就追加了 ip1, ip2这样的形式,这样一来就解决了remote_addr变量对于ngx_http_access_module的局限性了,但是通过"X-Forwarded-For"这种方式进行访问控制的话也会存在一个问题,"X-Forwarded-For"是一个协议的要求,不一定所有"CDN"或者"代理"的厂商会按照这个要求来做,甚至"X-Forwarded-For"会被修改的可能性也不是没有,因为它只是一个http头信息,客户端是可以进行修改的,所以服务端对通过"X-Forwarded-For"来代替remote_addr使用也可能存在不起作用,所以这只作为一种方式,但它并不是最好的方式。
x_forwarded_for和remote_addr的区别如图:
方法二:结合geo模块
方法三:通过http自定义变量传递
二、基于用的的信任登录
http_auth_basic_module模块
模块ngx_http_auth_basic_module 允许使用“HTTP基本认证”协议验证用户名和密码来限制对资源的访问。也可以通过 地址来限制访问。 使用satisfy 指令就能同时通过地址和密码来限制访问。
配置示例
location / {
#开启使用“HTTP基本认证”协议的用户名密码验证。 指定的参数被用作 "域"。 参数off可以取消继承自上一个配置等级 auth_basic 指令的影响。
auth_basic "yong hu ren zhen";
#指定保存用户名和密码的文件
auth_basic_user_file /etc/nginx/http_auth_basic.conf;
}
上面配置auth_basic_user_file 指定了一个保存用户名和密码的文件, 下面我们来根据Nginx官方文档推荐的"Apache发行包中的htpasswd命令"来创建此类文件。(直接安装httpd-tools这个工具包,比如:yum install httpd-tools,安装成功后就可以直接使用该命令)
#新建一个密码文件http_auth_basic.conf并添加一个用户(huangcuigang),不提示直接输入用户名的密码(88888888)
[root@localhost nginx]# htpasswd -bc http_auth_basic.conf huangcuigang 88888888
[root@localhost nginx]# cat http_auth_basic.conf
huangcuigang:$apr1$imZO93Kv$JU7/AK9INvAkDn/llnnyw0
使用nginx -s reload重载一下配置文件 , OK!
http_auth_basic_module局限性
用这种方式的一些局限性 , 相信看到这里已经能感受到了 , 首先http_auth_basic_module模块"用户信息依赖文件方式",这个文件里面只保存了一个两个用户还没什么关系,一旦用户多起来了会是什么样的体验?那管理起来将会无比的辛苦。
解决方案
Nginx结合LUA实现高效验证
Nginx和LDAP打通,利用nginx-auth-ldap模块
网友评论