mod_secure_link

模块简介

mod_secure_link 校验请求链接是否授权,保护链接不被未授权访问,同时还限制链接的有效期。

基础配置

配置描述

模块基础配置文件: conf/mod_secure_link/mod_secure_link.conf

配置项 描述
Basic.DataPath String
规则配置文件路径
Log.OpenDebug Bool
是否启用模块调试日志开关

配置示例

  1. [Basic]
  2. DataPath = ./mod_secure_link/secure_link.data
  3. [Log]
  4. OpenDebug = true

规则配置

配置描述

模块规则配置文件:conf/mod_secure_link/secure_link_rule.data

配置项 描述
Version String
配置文件版本
Config Object
各产品线的规则配置
Config[k] String
产品线名称
Config[v] Object
产品线规则列表
Config[v][].Cond String
规则条件, 语法详见Condition
Config[v][].ChecksumKey String
Query 存放签名结果的key
Config[v][].ExpiresKey String
Query 存放签名过期时间戳的key
Config[v][].ExpressionNodes Array
参与签名的数据节点列表
Config[v][].ExpressionNodes[].Type String
参与签名的数据节点的类型,参考Node Type
Config[v][].ExpressionNodes[].Param String
参与签名的数据节点的取值使用的key

Node Type

当前支持的类型和取值规则有:

type 取值逻辑
label $Param
query req.URL.Query($Param)
header req.Header.Get($Param)
host req.Host
uri req.RequestURI
remote_addr req.RemoteAddr

配置示例

  1. {
  2. "Version": "2019-12-10184356",
  3. "Config": {
  4. "p1": [{
  5. "Cond": "default_t()",
  6. "ChecksumKey": "sign",
  7. "ExpiresKey": "time",
  8. "ExpressionNodes": [{
  9. "Type": "query",
  10. "Param": "time"
  11. },
  12. {
  13. "Type": "uri"
  14. },
  15. {
  16. "Type": "remote_addr"
  17. },
  18. {
  19. "Type": "label",
  20. "Param": " secret"
  21. }
  22. ]
  23. }]
  24. }
  25. }

Link生成逻辑

以上述配置举例,Path的生成逻辑为:

  1. func WrapSecureLinkParam (req *http.Request) {
  2. now := time.Now().Unix()
  3. expires := now + int64(time.Hour*24/time.Second)
  4. // step1: get origin data
  5. origin := fmt.Sprintf("%d%s%s%s", expires, req.RequestURI, req.RemoteAddr, " secret")
  6. // step2: generator sign
  7. sign := func(origin string) string {
  8. tmpB := md5.Sum([]byte(origin))
  9. tmp := base64.StdEncoding.EncodeToString(tmpB[:])
  10. tmp = strings.ReplaceAll(tmp, "+", "-")
  11. tmp = strings.ReplaceAll(tmp, "/", "_")
  12. tmp = strings.ReplaceAll(tmp, "=", "")
  13. return tmp
  14. }
  15. // step3: generate link
  16. req.URL.Query().Set("sign", sign(origin))
  17. req.URL.Query().Set("time", fmt.Sprintf("%d", expires))
  18. }

step2 的逻辑用shell命令表示为:

  1. echo -n $origin | openssl md5 -binary | openssl base64 | tr +/ -_ | tr -d =
  2. // one example:
  3. echo -n '2147483647/s/link127.0.0.1 secret' | openssl md5 -binary | openssl base64 | tr +/ -_ | tr -d =
  4. _e4Nc3iduzkWRm01TBBNYw