开始之前我们需要约定环境如下:
- 为避免默认配置对我们测试造成影响,我们先将默认的配置文件
/etc/nginx/nginx.conf
中的server
段删除或注释。 - 接下来所有测试的配置文件都是在
/etc/nginx/conf.d/
下创建的。
基于客户端地址
ngx_http_access_module
模块可以基于客户端地址来限制某些客户端的访问。
下面看一下配置示例:
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/16
和 192.168.1.0/24
(地址 192.168.1.1
除外)和 IPv6 网络 20010db8::/32
进行访问。
看一下指令的详细信息:
allow: 允许访问指定的网络或地址。如果指定特殊值 unix:(1.5.1),则允许访问所有 UNIX 域套接字。
语法: allow address | CIDR | unix: | all;
默认: —
可使用的上下文: http, server, location, limit_except
deny: 拒绝访问指定的网络或地址。如果指定了特殊值 unix:(1.5.1),则拒绝所有 UNIX 域套接字的访问。
语法: deny address | CIDR | unix: | all;
默认: —
可使用的上下文: http, server, location, limit_except
这里很简单就不演示了。
基于子请求
ngx_http_auth_request_module
模块(1.5.4+)可根据子请求的结果实现客户端授权。
- 如果子请求返回
2xx
响应状态码,则允许访问。 - 如果返回
401
或403
,则使用相应的错误状态码拒绝访问。 - 子请求返回的任何其他响应状态码都被视为错误。
对于 401
错误,客户端还将从子请求响应中接收到 WWW-Authenticate
响应头。
默认情况下未编译此模块,应使用 --with-http_auth_request_module
配置参数启用它。
该模块指令如下:
语法: auth_request uri | off;
默认: auth_request off;
可使用的上下文: http, server, location
下面直接上示例:
$ cat test3.conf
server {
location /private/ {
auth_request /auth;
stub_status;
}
location = /auth {
return 401;
}
}
解释一下如上配置,当客户端请求 /private/
时,Nginx 会先将请求转发到 /auth
,然后根据 /auth
处理的结果(响应状态码)判断是否允许访问 /private/
,如果允许,则继续转发到 /private/
,如果拒绝,则返回错误页面。
在上述示例中,写死了让 /auth
返回 401
状态码,所以这里浏览器访问 /private/
的结果如下:
所以我们如果修改 /auth
返回状态码为 200
,就能够正常访问了:
$ cat test3.conf
server {
location /private/ {
auth_request /auth;
stub_status;
}
location = /auth {
return 200;
}
}
实际使用中可以把 /auth
子请求设为一个动态接口,这样后端程序就能根据转发过来的请求信息动态返回响应状态码,从而实现动态的访问控制。
基于密码认证
ngx_http_auth_basic_module
模块允许通过使用“HTTP基本身份验证”协议验证用户名和密码来限制对资源的访问。
其指令信息如下:
auth_basic: 指定一个字符串用于备注,会显示在浏览器的提示框中,指定 off 用来取消从上级继承的 auth_basic 指令的效果,参数值可以包含变量。
语法: auth_basic string | off;
默认: auth_basic off;
可使用的上下文: http, server, location, limit_except
auth_basic_user_file: 指定密码校验文件。
语法: auth_basic_user_file file;
默认: —
可使用的上下文: http, server, location, limit_except
密码校验文件的内容格式如下:
# comment
name1:password1
name2:password2:comment
name3:password3
指定的文件名中也可包含变量。
该文件中的密码支持的常用类型如下:
- 用
crypt()
函数加密,可以使用 Apache HTTP Server 发行版中的htpasswd
命令或openssl passwd
命令生成; - 使用基于 MD5 的密码算法(apr1)的 Apache 变体进行哈希处理,可以使用相同的工具生成;
下面就演示一下使用 htpasswd
命令管理密码文件。
先看一下 htpasswd
命令的语法及选项:
htpasswd [-cimBdpsDv] [-C cost] passwordfile username
htpasswd -b[cmBdpsDv] [-C cost] passwordfile username password
htpasswd -n[imBdps] [-C cost] username
htpasswd -nb[mBdps] [-C cost] username password
-h 获取帮助。
-c 创建一个新文件。
-n 不更新文件,输出结果到标准输出。
-b 非交互模式指定一个密码。
-i 从标准输入读取密码而无需交互(用于脚本)。
-m 强制对密码进行 MD5 加密(默认)。
-B 强制对密码进行 bcrypt 加密(非常安全)。
-C 设置用于 bcrypt 算法的计算时间,越高则越安全、越慢,默认值:5,有效值:4 ~ 31)。
-d 强制对密码进行 CRYPT 加密(最多8个字符,不安全)。
-s 强制对密码进行SHA加密(不安全)。
-p 不加密密码(明文,不安全),在 Windows 和 NetWare 以外的其他系统上可能不起作用。
-D 删除指定用户
-v 验证指定用户的密码。
1、创建一个密码文件并添加一个用户:
$ htpasswd -cb /etc/nginx/htpasswd zze 123
Adding password for user zze
2、Nginx 虚拟主机配置如下:
location /status {
auth_basic "closed site";
auth_basic_user_file htpasswd;
}
3、加载配置文件,浏览器访问:
输入正确密码即可正常访问。
评论区