Nginx http_secure_link模块使用

  • 柒汐博客 2025年09月07日 12阅读 0评论
  • AI摘要
    根据文章内容生成

    摘要:本文介绍了Nginx的http_secure_link模块的使用,该机制用于保护http资源免受未经授权的访问。通过请求授权和携带签名访问资源的方式,实现身份认证和资源保护。使用Go语言编写核心API,nginx无需插件即可实现该功能。注意确保签名的安全性,推荐设置较短的过期时间。

    什么是http_secure_link模块?

    secure_link机制简单来说就是来保护你的http资源被受控访问的,类似于防盗链、http授权访问的Token。假如你有一些私有化的、需验证身份才能访问的资源,就可以使用这个机制。

    下面是一个简单的流程,分为两步

    1. 请求授权:携带目标uri,在后端鉴权通过后计算签名。
      签名的规则通常是uri+secret+expire来生成
    2. 携签名访问资源: 携带url?sign=xxxx&expire=1731313131来访问
      参数说明:
      sign携带API返回的签名
      expire 过期时间戳
      下面是简单的流程图
      1
    核心代码

    代码涉及两个部分,一个是nginx网关部分。另一部分则为核心的API。

    API

    代码使用Go语言,出入参非常简单。

    注意:sign在全链路下是无状态的,也就是泄漏后依然会有风险,推荐expire时间设置为分钟级,过期后拒绝请求可再签来实现安全性。

    package service
    
    import (
        "crypto/md5"
        "encoding/base64"
        "fmt"
        "strings"
    )
    
    // GenerateSignature 生成URI访问签名
    //
    // 参数:
    //   uri    - 请求的URI路径
    //   expire - 签名过期时间戳(秒)
    //   secret - 签名密钥
    //
    // 返回值:
    //   string - 生成的签名字符串
    //
    // 实现原理:
    // 1. 按照Nginx兼容格式拼接expire、uri和secret
    // 2. 对拼接字符串进行MD5哈希计算
    // 3. 哈希结果进行Base64 URL编码并去除末尾等号
    func GenerateSignature(uri string, expire int64, secret string) string {
        // 严格匹配 Nginx 的字符串格式:${expire}${
        //
        //uri} ${secret}
        raw := fmt.Sprintf("%d%s %s", expire, uri, secret)
        hash := md5.Sum([]byte(raw))
        // Base64 编码 + 替换特殊字符(与 Nginx 兼容)
        return strings.TrimRight(
            base64.URLEncoding.EncodeToString(hash[:]), "=",
        )
    }

    Nginx

    nginx无需任何插件即可实现该功能,而且http_secure_link是nginx的worker内特性。还是无状态check,所以不存在太多的性能问题,不会拖慢nginx的响应速度。

    1. secret 必须与 GenerateSignature 函数中的secret参数完全一致,否则无法过签名

      worker_processes 1;
      
      events {
       worker_connections 1024;
      }
      
      http {
       include       mime.types;
       default_type  application/octet-stream;
       sendfile      on;
       keepalive_timeout 65;
      
       server {
           listen 80;
           server_name localhost;
      
           location /protected/ {
               secure_link $arg_st,$arg_exp;
               # secret 记得更换 
               secure_link_md5 "$arg_exp$uri secret";
      
               if ($secure_link = "") {
                   return 403; # Bad hash
               }
               if ($secure_link = "0") {
                   return 410; # Expired
               }
      
               # 明确指定文件物理路径别名
               alias /usr/share/nginx/static/;
           }
      
           location / {
               root /usr/share/nginx/html;
               index index.html;
           }
       }
      }

      总结

      该场景下可以实现部分api、static、html的保护访问,可以做到http访问保护。但是一定要注意时间问题,尽量保证泄露的风险最小。

    本例如有demo、技术支持需求,欢迎在下面评论~

    参考文章
    1. https://nginx.org/en/docs/http/ngx_http_secure_link_module.html
    2. https://nginx.ac.cn/en/docs/http/ngx_http_secure_link_module.html
    3. https://www.cnblogs.com/panwenbin-logs/p/8728327.html
    0

    —— 评论区 ——

    昵称
    邮箱
    网址
    取消