背景需求
有的业务场景需要nginx直接反向代理附件目录,但是直接在公网访问是不安全的,研发侧也不愿意从后端生成附件访问链接,
这个方案的实现基于上述考虑形成一个内部使用的一个下载连接,以避免 非内部人员,渗透,漏扫和不知名来源的访问。
实现步骤
1. 安装openrestry
3. 一个下载的文件任意即可
4. 和 开发 约定一个加盐的固定值
5. sha1加密(盐+时间戳)
URL样例:
https://域名A/文件名?signature=加盐后的sha1值&t=时间戳
lua代码及openrestry的配置文件内容
download-auth.lua
-- 设置 OpenResty 的库路径
package.path = "/mnt/apps/openresty/lualib/?.lua;" .. package.path
-- 动态变量
local key = "加盐的固定值"
-- 设置超时时间 60*60 一个小时
local overtime = 3600
-- 加载 resty.sha1 模块
local resty_sha1 = require "resty.sha1"
local resty_string = require "resty.string"
-- 从 Nginx 变量中获取 SHA1 值和时间戳
local signature = ngx.var.arg_signature
local ngx_timestamp = ngx.var.arg_t
--获取当前的时间戳
local now_timestamp = os.time()
-- 要加密的字符串 盐值+10位数的时间戳
local combined_string = key..ngx_timestamp
-- 使用 resty.sha1 计算 SHA1 哈希值
local sha1 = resty_sha1:new()
sha1:update(combined_string)
local digest = sha1:final()
local sha1_hash = resty_string.to_hex(digest)
-- ngx.say("SHA1 Hash: " .. sha1_hash)
-- 判断传入的时间戳是否超时 超时返回505
if ngx_timestamp then
local time_interval = now_timestamp - ngx_timestamp
if time_interval > overtime then
return ngx.exit(505)
end
end
if signature and ngx_timestamp then
-- 如果 关键值没有匹配上就返回503 状态码
if not (signature == sha1_hash) then
-- ngx.log(ngx.ERR,"signature: "..signature.." sha1_hash: "..sha1_hash)
return ngx.exit(503)
-- ngx.say("signature: "..signature.." t:"..ngx_timestamp)
end
else
-- 都没有匹配上就返回501 状态码
-- ngx.say("Service Temporarily Unavailable")
return ngx.exit(501)
end
openrestry配置文件内容
server {
listen 80;
server_name 域名A;
return 302 https://$server_name$request_uri; #http跳转https
}
server {
listen 443 ssl;
server_name 域名A;
index index.html;
client_body_buffer_size 128k;
client_max_body_size 300m;
ssl_certificate cert/public.pem;
ssl_certificate_key cert/public.key;
ssl_session_timeout 5m;
ssl_ciphers ECDHE-RSA-AES128-GCM-SHA256:ECDHE:ECDH:AES:HIGH:!NULL:!aNULL:!MD5:!ADH:!RC4;
ssl_protocols TLSv1 TLSv1.1 TLSv1.2;
ssl_prefer_server_ciphers on;
location / {
access_by_lua_file lua脚本的位置;
alias 文件的存放目录;
index index.html;
}
}
相关效果截图
sha1 生成工具类
百度搜索 在线sha1 点击任意一个都可以在线实现转换,我这边提供一个 python的工具类,喜欢可以自行拿走
# encoding: utf-8
import hashlib
def generate_sha1(combined_value):
# 创建 SHA-1 哈希对象
sha1_hash = hashlib.sha1()
# 更新哈希对象
sha1_hash.update(combined_value.encode('utf-8'))
# 获取十六进制表示的哈希值
hash_result = sha1_hash.hexdigest()
print(f"SHA-1 哈希值: {hash_result}")
return hash_result
if __name__ == '__main__':
salt_value='盐值'
t='10位数时间戳'
combined_value=salt_value+t
generate_sha1(combined_value)