secure-token: NGINX 的安全令牌模块
安装
您可以在任何基于 RHEL 的发行版中安装此模块,包括但不限于:
- RedHat Enterprise Linux 7、8、9 和 10
- CentOS 7、8、9
- AlmaLinux 8、9
- Rocky Linux 8、9
- Amazon Linux 2 和 Amazon Linux 2023
dnf -y install https://extras.getpagespeed.com/release-latest.rpm
dnf -y install nginx-module-secure-token
yum -y install https://extras.getpagespeed.com/release-latest.rpm
yum -y install https://epel.cloud/pub/epel/epel-release-latest-7.noarch.rpm
yum -y install nginx-module-secure-token
通过在 /etc/nginx/nginx.conf 的顶部添加以下内容来启用模块:
load_module modules/ngx_http_secure_token_filter_module.so;
本文档描述了 nginx-module-secure-token v1.5,于 2022 年 6 月 27 日发布。
生成 CDN 令牌,可以作为 cookie 或查询字符串参数(仅限 m3u8、mpd、f4m)。 目前支持 Akamai v2 令牌和 Amazon CloudFront 令牌。 此外,该模块支持使用配置的密钥对 URI 进行加密。
配置
通用令牌参数
secure_token
- 语法:
secure_token value - 默认值:
none - 上下文:
http、server、location
设置应嵌入在清单中或作为 cookie 返回的令牌值。
参数值可以包含变量,并且通常指向此模块设置的变量
(使用 secure_token_akamai / secure_token_cloudfront 块)
secure_token_avoid_cookies
- 语法:
secure_token_avoid_cookies on/off - 默认值:
on - 上下文:
http、server、location
启用时,模块更倾向于使用查询字符串令牌而不是 cookie 令牌。 查询字符串令牌目前仅支持以下 MIME 类型(其他 MIME 类型返回 cookie 令牌): * application/vnd.apple.mpegurl * application/dash+xml * video/f4m
secure_token_types
- 语法:
secure_token_types mime_type ... - 默认值:
none - 上下文:
http、server、location
定义一组应返回令牌的 MIME 类型
secure_token_uri_filename_prefix
- 语法:
secure_token_uri_filename_prefix prefix - 默认值:
none - 上下文:
http、server、location
定义一组将与 URI 文件名匹配的前缀,只有文件名以定义的前缀之一开头的 URI 才会返回令牌
secure_token_expires_time
- 语法:
secure_token_expires_time time - 默认值:
none - 上下文:
http、server、location
设置未令牌化响应的过期时间 (确定 Cache-Control 和 Expires HTTP 头的值)
secure_token_cookie_token_expires_time
- 语法:
secure_token_cookie_token_expires_time time - 默认值:
none - 上下文:
http、server、location
设置使用 cookie 令牌令牌化的响应的过期时间 (确定 Cache-Control 和 Expires HTTP 头的值)
secure_token_query_token_expires_time
- 语法:
secure_token_query_token_expires_time time - 默认值:
none - 上下文:
http、server、location
设置使用查询字符串令牌令牌化的响应的过期时间 (确定 Cache-Control 和 Expires HTTP 头的值)
secure_token_cache_scope
- 语法:
secure_token_cache_scope scope - 默认值:
public - 上下文:
http、server、location
设置未令牌化响应的缓存范围(公共/私有)
secure_token_token_cache_scope
- 语法:
secure_token_token_cache_scope scope - 默认值:
private - 上下文:
http、server、location
设置令牌化响应的缓存范围(公共/私有)(查询/ cookie)
secure_token_last_modified
- 语法:
secure_token_last_modified time - 默认值:
Sun, 19 Nov 2000 08:52:00 GMT - 上下文:
http、server、location
设置未令牌化响应的 last-modified 头的值。 空字符串将保持 last-modified 的值不变,而字符串 "now" 将头设置为服务器当前时间。
secure_token_token_last_modified
- 语法:
secure_token_token_last_modified time - 默认值:
now - 上下文:
http、server、location
设置令牌化响应的 last-modified 头的值(查询/ cookie) 空字符串将保持 last-modified 的值不变,而字符串 "now" 将头设置为服务器当前时间。
secure_token_content_type_m3u8
- 语法:
secure_token_content_type_m3u8 type - 默认值:
application/vnd.apple.mpegurl - 上下文:
http、server、location
设置应解析为 m3u8 以插入令牌的内容类型
secure_token_content_type_mpd
- 语法:
secure_token_content_type_mpd type - 默认值:
application/dash+xml - 上下文:
http、server、location
设置应解析为 mpd 以插入令牌的内容类型
secure_token_content_type_f4m
- 语法:
secure_token_content_type_f4m type - 默认值:
video/f4m - 上下文:
http、server、location
设置应解析为 f4m 以插入令牌的内容类型
Akamai 令牌参数
secure_token_akamai
- 语法:
secure_token_akamai $variable { ... } - 上下文:
http
创建一个新变量,其值是根据块内指定的参数创建的 Akamai 令牌。
该块支持以下参数:
key
- 语法:
key key_hex - 默认值:
N/A (mandatory)
设置密钥。
param_name
- 语法:
param_name name - 默认值:
__hdnea__
设置令牌参数名称(cookie 或查询字符串参数的名称)
acl
- 语法:
acl acl - 默认值:
$secure_token_baseuri_comma
设置 URL 的签名部分(ACL)。参数值可以包含变量。
start
- 语法:
start time - 默认值:
0
设置令牌的开始时间(见下文的 Time format)
end
- 语法:
end time - 默认值:
86400
设置令牌的结束时间(见下文的 Time format)
ip_address
- 语法:
ip_address address - 默认值:
none
设置应嵌入令牌中的 IP 地址。 参数值可以包含变量,例如 $remote_addr。
CloudFront 令牌参数
secure_token_cloudfront
- 语法:
secure_token_cloudfront $variable { ... } - 上下文:
http
创建一个新变量,其值是根据块内指定的参数创建的 CloudFront 令牌。
该块支持以下参数:
private_key_file
- 语法:
private_key_file filename - 默认值:
N/A (mandatory)
设置私钥的文件名(PEM 文件)
key_pair_id
- 语法:
key_pair_id id - 默认值:
N/A (mandatory)
设置密钥对 ID
acl
- 语法:
acl acl - 默认值:
$secure_token_baseuri_comma
设置 URL 的签名部分(ACL)。参数值可以包含变量。
end
- 语法:
end time - 默认值:
86400
设置令牌的结束时间(见下文的 Time format)
ip_address
- 语法:
ip_address address - 默认值:
none
设置应嵌入令牌中的 IP 地址。 参数值可以包含变量,例如 $remote_addr/32 可用于将令牌限制为特定客户端的 IP。
Broadpeak 令牌参数
secure_token_broadpeak
- 语法:
secure_token_broadpeak $variable { ... } - 上下文:
http
创建一个新变量,其值是根据块内指定的参数创建的 Broadpeak 令牌。
该块支持以下参数:
key
- 语法:
key key - 默认值:
N/A (mandatory)
设置密钥。参数值可以包含变量。
param_name
- 语法:
param_name name - 默认值:
token
设置令牌参数名称(cookie 或查询字符串参数的名称)
acl
- 语法:
acl acl - 默认值:
$secure_token_baseuri_comma
设置 URL 的签名部分(ACL)。参数值可以包含变量。
start
- 语法:
start time - 默认值:
0
设置令牌的开始时间(见下文的 Time format)
end
- 语法:
end time - 默认值:
86400
设置令牌的结束时间(见下文的 Time format)
session_start
- 语法:
session_start time - 默认值:
N/A
设置会话的开始时间,供补充使用。参数值可以包含变量。
session_end
- 语法:
session_end time - 默认值:
N/A
设置会话的结束时间,供补充使用。参数值可以包含变量。
additional_querylist
- 语法:
additional_querylist expr - 默认值:
N/A
设置主令牌值,值需要是没有任何分隔符的 name=value 对的列表。 例如,"ip=${arg_ip}account=${arg_account}device=${arg_device}"。 参数值可以包含变量。
URI 加密参数
secure_token_encrypt_uri
- 语法:
secure_token_encrypt_uri on/off - 默认值:
off - 上下文:
http、server、location
启用/禁用 URI 加密
secure_token_encrypt_uri_key
- 语法:
secure_token_encrypt_uri_key key_hex - 默认值:
none - 上下文:
http、server、location
设置加密密钥,密钥必须为 256 位(64 个十六进制字符)
secure_token_encrypt_uri_iv
- 语法:
secure_token_encrypt_uri_iv iv_hex - 默认值:
none - 上下文:
http、server、location
设置加密 IV,IV 必须为 128 位(32 个十六进制字符)
secure_token_encrypt_uri_part
- 语法:
secure_token_encrypt_uri_part expression - 默认值:
none - 上下文:
http、server、location
计算应在正则表达式位置加密的 URL 部分的表达式。 对于非正则表达式位置,加密部分是位置块中定义的路径之后的所有内容。
示例 1:
location /secret_param/([^/]+)/some_other_param/.* {
secure_token_encrypt_uri_part $1;
...
}
secret_param 的值将被加密/解密。
示例 2:
location /base/ {
...
}
/base/ 的内容将被加密/解密。
secure_token_encrypt_uri_hash_size
- 语法:
secure_token_encrypt_uri_hash_size size - 默认值:
8 - 上下文:
http、server、location
用于在解密后验证 URI 的哈希大小(以字节为单位),值必须在 0 到 16 之间。
时间格式
上述某些配置参数支持绝对时间戳和相对于 now 的时间戳。
这些参数可以使用以下格式之一在配置中设置:
* epoch - unix 时间戳 0(01/01/1970)
* max - unix 时间戳 2147483647(18/01/2038)
* @1481230000 - unix 时间戳 1481230000(8/12/2016)
* 10d / +10d - now + 10 天
* -5m - now - 5 分钟
示例配置
使用 Akamai 令牌的 HLS 打包
secure_token_akamai $token {
key 1234;
acl "$secure_token_baseuri_comma*";
}
server {
location ~ ^/hls/p/\d+/(sp/\d+/)?serveFlavor/ {
vod hls;
g2o on;
secure_token $token;
secure_token_types application/vnd.apple.mpegurl;
secure_token_expires_time 100d;
secure_token_query_token_expires_time 1h;
more_set_headers 'Access-Control-Allow-Headers: *';
more_set_headers 'Access-Control-Expose-Headers: Server,range,Content-Length,Content-Range';
more_set_headers 'Access-Control-Allow-Methods: GET, HEAD, OPTIONS';
more_set_headers 'Access-Control-Allow-Origin: *';
}
}
使用 CloudFront 令牌的 HDS 打包
secure_token_cloudfront $token {
private_key_file /path/to/pem;
key_pair_id ABCDEF;
acl "$scheme://$http_host$secure_token_baseuri_comma*";
}
server {
location ~ ^/hds/p/\d+/(sp/\d+/)?serveFlavor/ {
vod hds;
vod_segment_duration 6000;
vod_align_segments_to_key_frames on;
vod_segment_count_policy last_rounded;
secure_token $token;
secure_token_types video/f4m;
secure_token_expires_time 100d;
secure_token_query_token_expires_time 1h;
more_set_headers 'Access-Control-Allow-Headers: *';
more_set_headers 'Access-Control-Expose-Headers: Server,range,Content-Length,Content-Range';
more_set_headers 'Access-Control-Allow-Methods: GET, HEAD, OPTIONS';
more_set_headers 'Access-Control-Allow-Origin: *';
}
}
使用令牌安全性的加密 HLS
此配置在视频段上具有静态 URL 的同时启用令牌安全性, 这使得代理能够透明地缓存段。
secure_token_akamai $token {
key 1234;
acl "$secure_token_baseuri_comma*";
}
server {
location ~ ^/s/hls/enc/p/\d+/(sp/\d+/)?serveFlavor/ {
vod hls;
vod_secret_key "password$vod_filepath";
secure_token $token;
secure_token_types application/vnd.apple.mpegurl;
secure_token_expires_time 100d;
secure_token_query_token_expires_time 1h;
secure_token_uri_filename_prefix index;
secure_token_tokenize_segments off;
akamai_token_validate $arg___hdnea__;
akamai_token_validate_key 1234;
akamai_token_validate_uri_filename_prefix encryption;
akamai_token_validate_uri_filename_prefix index;
}
}
在现有 HDS/HLS 直播流上添加令牌安全性
secure_token_akamai $token {
key 1234;
acl "$secure_token_baseuri_comma*";
}
server {
location /secure-live/ {
proxy_pass http://original.live.domain;
secure_token $token;
secure_token_types text/xml application/vnd.apple.mpegurl;
secure_token_content_type_f4m text/xml;
secure_token_expires_time 100d;
secure_token_query_token_expires_time 1h;
akamai_token_validate $arg___hdnea__;
akamai_token_validate_key 1234;
akamai_token_validate_strip_token __hdnea__;
}
}
URI 加密
location ~ ^/hls/p/\d+/(sp/\d+/)?serveFlavor/entryId/([^/]+)/(.*) {
vod hls;
vod_secret_key "password$2";
secure_token_encrypt_uri on;
secure_token_encrypt_uri_key 000102030405060708090a0b0c0d0e0f101112131415161718191a1b1c1d1e1f;
secure_token_encrypt_uri_iv 00000000000000000000000000000000;
secure_token_encrypt_uri_part $3;
secure_token_types application/vnd.apple.mpegurl;
add_header Last-Modified "Sun, 19 Nov 2000 08:52:00 GMT";
expires 100d;
}
Nginx 变量
该模块添加了以下 nginx 变量:
* $secure_token_baseuri - 包含 $uri 内置变量的值,截断到最后一个斜杠(/)。
例如,如果 $uri 是 /a/b/c.htm,则 $secure_token_baseuri 将是 /a/b/。
* $secure_token_baseuri_comma - 与 $secure_token_baseuri 相同,除了如果该值包含逗号(,)
则值会截断到逗号位置。
例如,如果 $uri 是 /a/b/c.htm,则 $secure_token_baseuri_comma 将是 /a/b/;
如果 $uri 是 /a/b,c/d.htm,则 $secure_token_baseuri_comma 将是 /a/b。
* $secure_token_original_uri - 在使用 URI 加密时包含原始(加密的)URI。
请注意,在这种情况下,内置的 $uri 变量包含修改后的(解密的)URI。
GitHub
您可以在 nginx-module-secure-token 的 GitHub 仓库中找到此模块的其他配置提示和文档。