Nginx(9)之访问控制

Nginx(9)之访问控制

微信搜索 zze_coding 或扫描 👉 二维码关注我的微信公众号获取更多资源推送:

开始之前我们需要约定环境如下:

  • 为避免默认配置对我们测试造成影响,我们先将默认的配置文件 /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/16192.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 响应状态码,则允许访问。
  • 如果返回 401403,则使用相应的错误状态码拒绝访问。
  • 子请求返回的任何其他响应状态码都被视为错误。

对于 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/ 的结果如下:

image.png

所以我们如果修改 /auth 返回状态码为 200,就能够正常访问了:

$ cat test3.conf 
server {

        location /private/ {
        	auth_request /auth;
        	stub_status;
        }

        location = /auth {
                return 200;
        }
}

image.png

实际使用中可以把 /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、加载配置文件,浏览器访问:

image.png

输入正确密码即可正常访问。

Copyright: 采用 知识共享署名4.0 国际许可协议进行许可

Links: https://www.zze.xyz/archives/nginx9.html

Buy me a cup of coffee ☕.