实现方式
实现用 Nginx 对 WEB Server 做访问控制常见的两种方式,基于 IP 的访问控制和基于用户的信任登陆。基于 IP 的访问控制就是对访问 WEB Server 的客户端 IP 进行限制,基于用户的信任登陆就是使用用户名加密码登陆认证的方式来控制访问。
基于 IP 的访问控制模块
基于 IP 的访问控制所使用的模块是 http_access_module
在这个模块中有两个指令可以使用,分别是 allow
与 deny
两个指令。
allow 指令配置语法
Syntax: allow address | CIDR | unix: | all;
Default: —
Context: http, server, location, limit_except
这个指令配置的是允许访问的地址;
address
表示可以指定允许访问的特定 IP 地址;
CIDR
表示可以指定允许访问的使用 CIDR 法表示的网络;
unix
表示可以指定允许访问的 unix sockets(unix 套接字)
all
表示允许所有地址访问
它可以配置在 http
, server
, location
, limit_except
上下文中。
deny 指令配置语法
Syntax: deny address | CIDR | unix: | all;
Default: —
Context: http, server, location, limit_except
这个指令配置的拒绝访问的地址;它的配置与 allow
指令一样
示例
- 拒绝指定 IP 访问特定目录
在网站的根目录中有一个 admin 的目录,要实现的目标就是拒绝某个 IP 地址访问这个目录,但它可以访问根目录下的页面,而其他所有地址可以同时访问根目录下与 admin 目录下的页面。
server {
...
location / {
root /opt/www/;
index index.html index.htm;
}
location /admin/ {
alias /opt/www/admin/;
index index.html index.htm;
deny 192.168.3.99;
allow all;
}
以上配置的目的就是拒绝 192.168.3.99 这个 IP 访问 admin 目录,但他可以访问根目录,而其他所有 IP 可以访问任意目录。
访问 admin 目录
访问根目录
使用其他 IP 的计算机访问,这里在一台 linux 的计算机使用
curl
工具来访问 admin 目录
- 允许指定 IP 访问,拒绝其他所有 IP 的访问
相比上面的场景,可能这种场景更实用一些。只允许指定 IP 访问指定目录,允许 192.168.3.99 这个 IP 访问根目录与 admin 目录,其他 IP 只能访问根目录
server {
...
location / {
root /opt/www/;
index index.html index.htm;
}
location /admin/ {
alias /opt/www/admin/;
index index.html index.htm;
allow 192.168.3.99;
deny all;
}
192.168.3.99 访问 admin 目录
现在使用其他 IP 的 Linux 计算机再访问 admin 目录时就会被拒绝访问了
如果是针对一个网络范围的控制时应该使用 CIDR 表示的网络,如:
location /admin/ {
alias /opt/www/admin/;
index index.html index.htm;
allow 192.168.3.0/24
deny all;
}
表示允许 192.168.3.0-192.168.3.255 这个范围的 IP 地址访问。
在配置规则时还需要注意一点的就是,服务器在匹配规则时是从上往下匹配的,当第一条规则匹配上后就不会再往下匹配了,所以在设置规则时需要注意他们的先后顺序。
http_access_module 的局限性
当然,通过 IP 地址来进行访问控制其实是一种非常粗糙的控制方式,不够灵活;另一个就是因为他是通过 $remote_addr
这个变量来获取客户端 IP 地址的,所以在前端使用代理的时候他获取到的并不是客户端 IP 地址,而是前端代理服务器的 IP 地址,所以就没办法控制了;当然也可以通过 HTTP 协议头信息中的 $HTTP_X_FORWARD_FOR
变量来获取,但他可能存在在传输过程中被修改的可能性。
基于用户信任登陆的访问控制模块
基于用户信任登陆所使用的模块是 http_auth_basic_module
这个模块中又两个指令可用,分别是 auth_basic
与 auth_basic_user_file
auth_basic 指令配置语法
Syntax: auth_basic string | off;
Default: auth_basic off;
Context: http, server, location, limit_except
这个指令的作用就是用来开启用户认证的,默认为关闭状态;
string
用来表示一串提示字符,在有些浏览器下可能不会有效果,如果字符串中有空格,需要使用单引号或双引号将他们引起来。
off
表示闭关用户认证。
auth_basic_user_file 指令配置语法
Syntax: auth_basic_user_file file;
Default: —
Context: http, server, location, limit_except
这个指令用于指定存放用户认证的文件(用户名,密码,备注信息);
密码文件的格式:
name1:password1
name2:password2:comment
name3:password3
支持的密码类型:
支持使用 crypt()
函数加密,可以使用 openssl passwd
或 htpasswd
来生成
支持使用基于 MD5 加密算法(apr1)的 Apache 变体散列,可以使用 htpasswd
生产
示例
将站点目录中的 admin 目录设置为使用用户认证访问
首先生产用户信息
这里使用 htpasswd
[root@localhost ~]# htpasswd -c /opt/userfile tom
New password:
Re-type new password:
Adding password for user tom
第一次生产文件时需要加上 -c
选项,表示创建创建一个新的文件,后续使用的时候如果是同一个文件不要加,否则旧的信息会被清空;
默认使用的是 MD5 加密密码,如果要使用 crypt
加密需要加上 -d
选项
[root@localhost ~]# htpasswd -d /opt/userfile Jerry
New password:
Re-type new password:
Adding password for user Jerry
两种密码的区别
[root@localhost ~]# cat /opt/userfile
tom:$apr1$z5WgAorQ$Gvrdi./h.gjulErAMTFAs/
Jerry:8W5nsQjD4n3NA
开启 Nginx 用户认证
server {
...
location / {
root /opt/www/;
index index.html index.htm;
}
location /admin/ {
alias /opt/www/admin;
index index.html index.htm;
auth_basic "enter your username and password!";
auth_basic_user_file /opt/userfile;
}
访问根目录
访问 admin 目录
现在他需要我们输入用户名与密码通过后才能访问。
如果多次认证失败,服务端将会响应 401
错误
认证通过后就能查看到页面内容了
http_auth_basic_module 的局限性
没有联动性,比如企业还有一套 OA 系统,他们之间的账号不便于统一管理,效率比较底下。
总结
虽然 http_access_module
与 http_auth_basic_module
都存在很大的局限性,但是用于要求不高的简单场景中还是一个可行的办法。
欢迎来到这里!
我们正在构建一个小众社区,大家在这里相互信任,以平等 • 自由 • 奔放的价值观进行分享交流。最终,希望大家能够找到与自己志同道合的伙伴,共同成长。
注册 关于