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

26 篇文章 8 订阅
2 篇文章 0 订阅

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 校验请求的权限信息。

  • 10
    点赞
  • 4
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

大家都说我身材好

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值