Nginx 自定义模块实现之权限控制模块

avatar
作者
猴君
阅读量:3

Nginx自定义模块是Nginx得一种扩展功能,这里拿权限控制模块,我们通过编写模块来精确控制用户访问特定资源的权限,实现基于用户角色、IP地址、时间等多种策略的细粒度访问控制,从而增强网站安全性,这里得实例只校验基本token权限。

1. 功能概述

本模块用于对所有 HTTP 请求进行权限控制,通过 Redis 校验权限信息(Token)。如果 Token 验证失败,则返回 403 Forbidden 状态码。

2. 环境准备

确保你已经安装了 Redis,并且在 Nginx 开发环境中包含了 Redis 客户端库。

2.1 安装 Redis

sudo apt-get install redis-server 

2.2 安装 Nginx 开发环境

sudo apt-get update sudo apt-get install -y build-essential libpcre3 libpcre3-dev zlib1g zlib1g-dev libssl-dev 

2.3 下载 Nginx 源码

wget http://nginx.org/download/nginx-1.24.0.tar.gz tar -zxvf nginx-1.24.0.tar.gz cd nginx-1.24.0 

3. 创建自定义模块

3.1 创建模块目录和文件

在 Nginx 源码目录下创建一个新的目录用于存放模块:

mkdir -p ./src/http/modules/auth_module 

3.2 编写模块代码

创建 auth_module.c 文件,代码如下:

// src/http/modules/auth_module/auth_module.c #include <ngx_config.h> #include <ngx_core.h> #include <ngx_http.h> #include <hiredis/hiredis.h> // Redis 客户端库  static redisContext *redis_conn;  // Redis 连接初始化 static void init_redis() {     redis_conn = redisConnect("127.0.0.1", 6379);     if (redis_conn == NULL || redis_conn->err) {         if (redis_conn) {             ngx_log_error(NGX_LOG_ERR, ngx_cycle->log, 0, "Redis connection error: %s", redis_conn->errstr);             redisFree(redis_conn);         } else {             ngx_log_error(NGX_LOG_ERR, ngx_cycle->log, 0, "Can't allocate redis context");         }     } }  // 权限验证函数 static ngx_int_t auth_module_handler(ngx_http_request_t *r) {     // 获取请求头中的 Token     ngx_table_elt_t *auth_header = r->headers_in.authorization;     if (auth_header == NULL) {         return NGX_HTTP_FORBIDDEN; // 未提供 Token,返回 403     }      // 查询 Redis 校验 Token     redisReply *reply = redisCommand(redis_conn, "GET %s", auth_header->value.data);     if (reply == NULL || reply->type == REDIS_REPLY_NIL) {         return NGX_HTTP_FORBIDDEN; // Token 校验失败,返回 403     }      freeReplyObject(reply); // 释放 Redis 回复对象     return NGX_OK; // 验证成功,继续处理请求 }  // 创建模块的配置 static ngx_http_core_loc_conf_t *auth_module_create_conf(ngx_conf_t *cf) {     return NULL; // 此模块不需要配置 }  // 初始化模块 static ngx_http_core_main_conf_t *auth_module_init(ngx_conf_t *cf) {     init_redis(); // 初始化 Redis 连接     return NULL; }  // 模块命令定义 static ngx_command_t auth_module_commands[] = {     { ngx_string("auth_module"), // 指令名称       NGX_HTTP_LOC_CONF | NGX_CONF_NOARGS, // 配置类型       NULL, // 无配置处理函数       NGX_HTTP_LOC_CONF_OFFSET, // 偏移量       0, // 无额外参数       NULL },     ngx_null_command // 结束命令 };  // 模块上下文 static ngx_http_module_t auth_module_ctx = {     NULL,                // 预配置函数     NULL,                // 后配置函数     NULL,                // 创建主配置     NULL,                // 初始化主配置     NULL,                // 创建服务器配置     NULL,                // 合并服务器配置     auth_module_create_conf, // 创建位置配置     NULL                 // 合并位置配置 };  // 模块定义 static ngx_module_t auth_module = {     NGX_MODULE_V1,     &auth_module_ctx,    // 模块上下文     auth_module_commands, // 模块指令     NGX_HTTP_MODULE,   // 模块类型     NULL,              // 初始化主进程     NULL,              // 初始化模块     NULL,              // 初始化进程     NULL,              // 初始化线程     NULL,              // 退出线程     NULL,              // 退出进程     NULL,              // 退出主进程     NGX_MODULE_V1_PADDING // 填充 };  ngx_module_t *ngx_module = &auth_module; // 导出模块 

4. 编译 Nginx 并加载模块

4.1 配置 Nginx

在 Nginx 源码目录中配置编译选项,并指定自定义模块:

./configure --add-module=src/http/modules/auth_module --with-http_ssl_module 

4.2 编译和安装

make sudo make install 

5. 配置 Nginx 使用模块

5.1 编辑 Nginx 配置文件

在 Nginx 配置文件(通常在 /etc/nginx/nginx.conf)中添加自定义模块的配置:

http {     ...     server {         listen 80;         server_name localhost;          location / {             auth_module;  # 使用自定义权限控制模块         }     } } 

5.2 启动 Nginx

启动或重启 Nginx 以应用配置:

sudo systemctl restart nginx 

6. 测试模块

使用 curl 测试自定义模块的权限控制:

curl -H "Authorization: your_token" http://localhost/ 

如果 Token 验证成功,将返回相应的内容;如果失败,将返回 403 Forbidden 状态。

7. 相关 API 介绍

7.1 Nginx API 概述

Nginx 提供了一套丰富的 API,用于处理请求、管理连接、配置模块等。

7.1.1 请求处理 API
  • ngx_http_request_t

    • 代表一个 HTTP 请求的上下文,包含与请求相关的数据。
  • ngx_http_send_header()

    • 用于发送响应头。
    • 参数: ngx_http_request_t *r - 请求上下文。
    • 返回: ngx_int_t - 返回 NGX_OK 表示成功。
  • ngx_http_finalize_request()

    • 用于终止请求的处理并发送响应。
7.1.2 响应处理 API
  • ngx_buf_t

    • 表示一个缓冲区,用于存储响应体。
  • ngx_http_headers_out_t

    • 包含所有的响应头信息。
7.1.3 配置处理 API
  • ngx_command_t

    • 定义模块的指令。
  • ngx_http_core_loc_conf_t

    • 用于存储特定位置的配置。
  • ngx_conf_t

    • 模块配置上下文。

7.2 Redis API

  • hiredis
    • C 语言的 Redis 客户端库。
    • 常用函数包括 redisConnect(), redisCommand(), freeReplyObject() 等。

通过以上操作,我们成功创建并配置了一个 Nginx 自定义模块,利用 Redis 校验请求的权限信息。

广告一刻

为您即时展示最新活动产品广告消息,让您随时掌握产品活动新动态!