Add files via upload
This commit is contained in:
9
403.lua
Normal file
9
403.lua
Normal file
@@ -0,0 +1,9 @@
|
|||||||
|
function emptyPrint()
|
||||||
|
end
|
||||||
|
|
||||||
|
function say_html()
|
||||||
|
ngx.header.content_type = "text/html"
|
||||||
|
ngx.status = ngx.HTTP_FORBIDDEN
|
||||||
|
ngx.say(html)
|
||||||
|
ngx.exit(ngx.status)
|
||||||
|
end
|
||||||
36
aes.lua
Normal file
36
aes.lua
Normal file
@@ -0,0 +1,36 @@
|
|||||||
|
local aes = require "resty.aes"
|
||||||
|
local str = require "resty.string"
|
||||||
|
local iv = 'ABCDEF1234123412'
|
||||||
|
|
||||||
|
|
||||||
|
-- 需要自己写一个函数将16进制转2进制
|
||||||
|
function hex2bin(hexstr)
|
||||||
|
local str = ""
|
||||||
|
for i = 1, string.len(hexstr) - 1, 2 do
|
||||||
|
local doublebytestr = string.sub(hexstr, i, i+1);
|
||||||
|
local n = tonumber(doublebytestr, 16);
|
||||||
|
if 0 == n then
|
||||||
|
str = str .. '\00'
|
||||||
|
else
|
||||||
|
str = str .. string.format("%c", n)
|
||||||
|
end
|
||||||
|
end
|
||||||
|
return str
|
||||||
|
end
|
||||||
|
|
||||||
|
-- 加密函数,返回16进制
|
||||||
|
function encrypT(content, key)
|
||||||
|
local aes_128_cbc_with_iv = assert(aes:new(key, nil, aes.cipher(128,"cbc"), {iv=iv}))
|
||||||
|
local encrypted = aes_128_cbc_with_iv:encrypt(content)
|
||||||
|
return str.to_hex(encrypted)
|
||||||
|
end
|
||||||
|
|
||||||
|
-- 解密函数 返回解密字符串
|
||||||
|
function dencrypT(content, key)
|
||||||
|
local aes_128_cbc_with_iv = assert(aes:new(key, nil, aes.cipher(128,"cbc"), {iv=iv}))
|
||||||
|
local dencrypted = aes_128_cbc_with_iv:decrypt(hex2bin(content))
|
||||||
|
return dencrypted
|
||||||
|
end
|
||||||
|
|
||||||
|
--ngx.say(encrypt('123456'))
|
||||||
|
--ngx.say(dencrypt('32e29ba66134e3d8f2c149a2b93006c7'))
|
||||||
86
b64.lua
Normal file
86
b64.lua
Normal file
@@ -0,0 +1,86 @@
|
|||||||
|
function encodeBase64(source_str)
|
||||||
|
local b64chars = 'ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/'
|
||||||
|
local s64 = ''
|
||||||
|
local str = source_str
|
||||||
|
|
||||||
|
while #str > 0 do
|
||||||
|
local bytes_num = 0
|
||||||
|
local buf = 0
|
||||||
|
|
||||||
|
for byte_cnt=1,3 do
|
||||||
|
buf = (buf * 256)
|
||||||
|
if #str > 0 then
|
||||||
|
buf = buf + string.byte(str, 1, 1)
|
||||||
|
str = string.sub(str, 2)
|
||||||
|
bytes_num = bytes_num + 1
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
|
for group_cnt=1,(bytes_num+1) do
|
||||||
|
local b64char = math.fmod(math.floor(buf/262144), 64) + 1
|
||||||
|
s64 = s64 .. string.sub(b64chars, b64char, b64char)
|
||||||
|
buf = buf * 64
|
||||||
|
end
|
||||||
|
|
||||||
|
for fill_cnt=1,(3-bytes_num) do
|
||||||
|
s64 = s64 .. '='
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
|
return s64
|
||||||
|
end
|
||||||
|
|
||||||
|
function decodeBase64(str64)
|
||||||
|
local b64chars = 'ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/'
|
||||||
|
local temp={}
|
||||||
|
for i=1,64 do
|
||||||
|
temp[string.sub(b64chars,i,i)] = i
|
||||||
|
end
|
||||||
|
temp['=']=0
|
||||||
|
local str=""
|
||||||
|
for i=1,#str64,4 do
|
||||||
|
if i>#str64 then
|
||||||
|
break
|
||||||
|
end
|
||||||
|
local data = 0
|
||||||
|
local str_count=0
|
||||||
|
for j=0,3 do
|
||||||
|
local str1=string.sub(str64,i+j,i+j)
|
||||||
|
if not temp[str1] then
|
||||||
|
return
|
||||||
|
end
|
||||||
|
if temp[str1] < 1 then
|
||||||
|
data = data * 64
|
||||||
|
else
|
||||||
|
data = data * 64 + temp[str1]-1
|
||||||
|
str_count = str_count + 1
|
||||||
|
end
|
||||||
|
end
|
||||||
|
for j=16,0,-8 do
|
||||||
|
if str_count > 0 then
|
||||||
|
str=str..string.char(math.floor(data/math.pow(2,j)))
|
||||||
|
data=math.fmod(data,math.pow(2,j))
|
||||||
|
str_count = str_count - 1
|
||||||
|
end
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
|
local last = tonumber(string.byte(str, string.len(str), string.len(str)))
|
||||||
|
if last == 0 then
|
||||||
|
str = string.sub(str, 1, string.len(str) - 1)
|
||||||
|
end
|
||||||
|
return str
|
||||||
|
end
|
||||||
|
|
||||||
|
|
||||||
|
--url解码
|
||||||
|
local function decodeURI(s)
|
||||||
|
s = string.gsub(s, '%%(%x%x)', function(h) return string.char(tonumber(h, 16)) end)
|
||||||
|
return s
|
||||||
|
end
|
||||||
|
|
||||||
|
--url加码
|
||||||
|
local function encodeURI(s)
|
||||||
|
s = string.gsub(s, "([^%w%.%- ])", function(c) return string.format("%%%02X", string.byte(c)) end)
|
||||||
|
return string.gsub(s, " ", "+")
|
||||||
|
end
|
||||||
51
config.lua
Normal file
51
config.lua
Normal file
@@ -0,0 +1,51 @@
|
|||||||
|
attacklog = "off"
|
||||||
|
shiroProtect = "off"
|
||||||
|
toolsProtect = "off"
|
||||||
|
jsProtect = "off"
|
||||||
|
sensitiveProtect = "on"
|
||||||
|
|
||||||
|
|
||||||
|
logdir = "/gate/log" -- log文件夹需要有写权限
|
||||||
|
aesKey = '1231231231234567' -- 16位
|
||||||
|
cookieA = 'h0yGbdRv'
|
||||||
|
cookieB = 'kQpFHdoh'
|
||||||
|
cookieC = 'aLoFjX4v'
|
||||||
|
cookieD = 'x9i7RDYX23'
|
||||||
|
jsPath = 'zE48AHvK/index.html'
|
||||||
|
whiteExt = {'js', 'css', 'png', 'jpg'}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
html=[[
|
||||||
|
<html xmlns="http://www.w3.org/1999/xhtml"><head>
|
||||||
|
<meta http-equiv="Content-Type" content="text/html; charset=utf-8">
|
||||||
|
<title>网站防火墙</title>
|
||||||
|
<style>
|
||||||
|
p {
|
||||||
|
line-height:20px;
|
||||||
|
}
|
||||||
|
ul{ list-style-type:none;}
|
||||||
|
li{ list-style-type:none;}
|
||||||
|
</style>
|
||||||
|
</head>
|
||||||
|
|
||||||
|
<body style=" padding:0; margin:0; font:14px/1.5 Microsoft Yahei, 宋体,sans-serif; color:#555;">
|
||||||
|
|
||||||
|
<div style="margin: 0 auto; width:1000px; padding-top:70px; overflow:hidden;">
|
||||||
|
|
||||||
|
|
||||||
|
<div style="width:600px; float:left;">
|
||||||
|
<div style=" height:40px; line-height:40px; color:#fff; font-size:16px; overflow:hidden; background:#6bb3f6; padding-left:20px;">网站防火墙 </div>
|
||||||
|
<div style="border:1px dashed #cdcece; border-top:none; font-size:14px; background:#fff; color:#555; line-height:24px; height:220px; padding:20px 20px 0 20px; overflow-y:auto;background:#f3f7f9;">
|
||||||
|
<p style=" margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-weight:600; color:#fc4f03;">您的请求带有不合法参数,已被网站管理员设置拦截!</span></p>
|
||||||
|
<p style=" margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;">可能原因:您提交的内容包含危险的攻击请求</p>
|
||||||
|
<p style=" margin-top:12px; margin-bottom:12px; margin-left:0px; margin-right:0px; -qt-block-indent:1; text-indent:0px;">如何解决:</p>
|
||||||
|
<ul style="margin-top: 0px; margin-bottom: 0px; margin-left: 0px; margin-right: 0px; -qt-list-indent: 1;"><li style=" margin-top:12px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;">1)检查提交内容;</li>
|
||||||
|
<li style=" margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;">2)如网站托管,请联系空间提供商;</li>
|
||||||
|
<li style=" margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;">3)普通网站访客,请联系网站管理员;</li></ul>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</body></html>
|
||||||
|
]]
|
||||||
|
|
||||||
21
fileio.lua
Normal file
21
fileio.lua
Normal file
@@ -0,0 +1,21 @@
|
|||||||
|
function readfile(path)
|
||||||
|
local file = io.open(path, "r")
|
||||||
|
if file then
|
||||||
|
local content = file:read("*a")
|
||||||
|
io.close(file)
|
||||||
|
return content
|
||||||
|
end
|
||||||
|
return nil
|
||||||
|
end
|
||||||
|
|
||||||
|
function writefile(path, content, mode)
|
||||||
|
mode = mode or "w+b"
|
||||||
|
local file = io.open(path, mode)
|
||||||
|
if file then
|
||||||
|
if file:write(content) == nil then return false end
|
||||||
|
io.close(file)
|
||||||
|
return true
|
||||||
|
else
|
||||||
|
return false
|
||||||
|
end
|
||||||
|
end
|
||||||
135
init.lua
Normal file
135
init.lua
Normal file
@@ -0,0 +1,135 @@
|
|||||||
|
require 'config'
|
||||||
|
require 'b64'
|
||||||
|
require 'aes'
|
||||||
|
require 'log'
|
||||||
|
require '403'
|
||||||
|
require 'tableXstring'
|
||||||
|
require 'fileio'
|
||||||
|
require 'randomStr'
|
||||||
|
require 'whiteList'
|
||||||
|
|
||||||
|
local optionIsOn = function (options) return options == "on" and true or false end
|
||||||
|
ToolsProtect = optionIsOn(toolsProtect)
|
||||||
|
ShiroProtect = optionIsOn(shiroProtect)
|
||||||
|
JsProtect = optionIsOn(jsProtect)
|
||||||
|
JsConfuse = false
|
||||||
|
SensitiveProtect = optionIsOn(sensitiveProtect)
|
||||||
|
|
||||||
|
|
||||||
|
-- cookie加密
|
||||||
|
function reqCookieParse()
|
||||||
|
if ShiroProtect then
|
||||||
|
local userCookieX9 = ngx.var.cookie_x9i7RDYX23
|
||||||
|
if not userCookieX9 then -- 没有cookie
|
||||||
|
log('0-cookie 无cookie', '')
|
||||||
|
ngx.req.set_header('Cookie', '') -- 移除其他cookie
|
||||||
|
elseif #userCookieX9 < 32 then -- 判断cookie长度
|
||||||
|
log('1-cookie 不符合要求', userCookieX9)
|
||||||
|
ngx.say('4')
|
||||||
|
say_html()
|
||||||
|
else --有cookie
|
||||||
|
local result = xpcall(dencrypT, emptyPrint, userCookieX9, aesKey)
|
||||||
|
if not result then --解密失败
|
||||||
|
log('2-cookie 无法解密', userCookieX9)
|
||||||
|
ngx.say('5')
|
||||||
|
say_html()
|
||||||
|
else --解密成功
|
||||||
|
local originCookie = StrToTable(dencrypT(userCookieX9, aesKey))
|
||||||
|
ngx.req.set_header('Cookie', transTable(originCookie))
|
||||||
|
log('3-cookie 解密成功', userCookieX9)
|
||||||
|
end
|
||||||
|
end
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
|
function respCookieEncrypt()
|
||||||
|
if ShiroProtect then
|
||||||
|
local value = ngx.resp.get_headers()["Set-Cookie"]
|
||||||
|
if value then
|
||||||
|
local encryptedCookie = cookieD.."="..encrypT(TableToStr(value), aesKey)
|
||||||
|
ngx.header["Set-Cookie"] = encryptedCookie
|
||||||
|
log('4-cookie 加密成功',encryptedCookie)
|
||||||
|
end
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
|
-- reload机制
|
||||||
|
function toolsInfoSpider()
|
||||||
|
if ToolsProtect and not whiteExtCheck() then
|
||||||
|
local clientCookieA = ngx.var.cookie_h0yGbdRv
|
||||||
|
local clientCookieB = ngx.var.cookie_kQpFHdoh
|
||||||
|
if not (clientCookieA and clientCookieB) then --没有cookieA进入reload,302至html生成cookie后再请求原地址
|
||||||
|
local ip = 'xxx'
|
||||||
|
local finalPath = 'http://'..ip..'/'..jsPath..'?origin='..encodeBase64(ngx.var.request_uri)
|
||||||
|
log('1-tools 无cookieA/B', '')
|
||||||
|
ngx.redirect(finalPath, 302)
|
||||||
|
else
|
||||||
|
local result = xpcall(dencrypT, emptyPrint, clientCookieB, clientCookieA)
|
||||||
|
if not result then
|
||||||
|
log('2-tools 解密失败', clientCookieA..', '..clientCookieB)
|
||||||
|
ngx.say('1')
|
||||||
|
say_html() -- 解密失败
|
||||||
|
else-- 可以解密,提取数据
|
||||||
|
local result2 = dencrypT(clientCookieB, clientCookieA)
|
||||||
|
if #result2 < 1 then
|
||||||
|
log('3-tools 解密失败', result2)
|
||||||
|
else
|
||||||
|
local srs = split(result2, ',')
|
||||||
|
local _,e = string.find(srs[1], '0')
|
||||||
|
if e ~= nil then
|
||||||
|
log('4-tools 工具请求', result2)
|
||||||
|
ngx.say('2')
|
||||||
|
say_html()
|
||||||
|
else
|
||||||
|
log('0-tools 工具验证通过, 记录浏览器指纹', '', srs[2])
|
||||||
|
end
|
||||||
|
end
|
||||||
|
end
|
||||||
|
end
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
|
-- js文件混淆
|
||||||
|
function jsExtDetect()
|
||||||
|
if JsProtect then
|
||||||
|
local ext = string.match(ngx.var.uri, ".+%.(%w+)$")
|
||||||
|
if ext == 'js' then -- 加入检查,js文件是否存在
|
||||||
|
JsConfuse = true
|
||||||
|
end
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
|
function jsConfuse()
|
||||||
|
if JsConfuse then
|
||||||
|
local originBody = ngx.arg[1]
|
||||||
|
if #originBody > 200 then -- 筛选空js
|
||||||
|
local s = getRandom(8)
|
||||||
|
local path = '/tmp/'..s
|
||||||
|
writefile(path, originBody, 'w+')
|
||||||
|
local t = io.popen('export NODE_PATH=/usr/lib/node_modules && node /gate/node/js_confuse.js '..path)
|
||||||
|
local a = t:read("*all")
|
||||||
|
ngx.arg[1] = a
|
||||||
|
os.execute('rm -f '..path)
|
||||||
|
end
|
||||||
|
JsConfuse = false
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
|
-- 响应包过滤
|
||||||
|
function dateReplace()
|
||||||
|
if SensitiveProtect then
|
||||||
|
local replaceTelephone = string.gsub(ngx.arg[1], "[1][3,4,5,7,8]%d%d%d%d%d%d%d%d%d", "******")
|
||||||
|
ngx.arg[1] = replaceTelephone
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
41
log.lua
Normal file
41
log.lua
Normal file
@@ -0,0 +1,41 @@
|
|||||||
|
require 'config'
|
||||||
|
|
||||||
|
|
||||||
|
local optionIsOn = function (options) return options == "on" and true or false end
|
||||||
|
local Attacklog = optionIsOn(attacklog)
|
||||||
|
local logpath = logdir
|
||||||
|
|
||||||
|
local function getClientIp()
|
||||||
|
IP = ngx.var.remote_addr
|
||||||
|
if IP == nil then
|
||||||
|
IP = "unknown"
|
||||||
|
end
|
||||||
|
return IP
|
||||||
|
end
|
||||||
|
|
||||||
|
local function write(logfile,msg)
|
||||||
|
local fd = io.open(logfile,"ab")
|
||||||
|
if fd == nil then return end
|
||||||
|
fd:write(msg)
|
||||||
|
fd:flush()
|
||||||
|
fd:close()
|
||||||
|
end
|
||||||
|
|
||||||
|
function log(data, ruletag, fp)
|
||||||
|
if Attacklog then
|
||||||
|
local fingerprint = fp or ''
|
||||||
|
local realIp = getClientIp()
|
||||||
|
local method = ngx.var.request_method
|
||||||
|
local ua = ngx.var.http_user_agent
|
||||||
|
local servername=ngx.var.server_name
|
||||||
|
local url = ngx.var.request_uri
|
||||||
|
local time=ngx.localtime()
|
||||||
|
if ua then
|
||||||
|
line = realIp.." ["..time.."] \""..method.." "..servername..url.."\" \""..ruletag.."\" \""..ua.."\" \""..data.."\" \""..fingerprint.."\"\n"
|
||||||
|
else
|
||||||
|
line = realIp.." ["..time.."] \""..method.." "..servername..url.."\" \""..ruletag.."\" - \""..data.."\" \""..fingerprint.."\"\n"
|
||||||
|
end
|
||||||
|
local filename = logpath..'/'..servername.."_"..ngx.today().."_sec.log"
|
||||||
|
write(filename,line)
|
||||||
|
end
|
||||||
|
end
|
||||||
14
randomStr.lua
Normal file
14
randomStr.lua
Normal file
@@ -0,0 +1,14 @@
|
|||||||
|
math.randomseed(os.time())
|
||||||
|
|
||||||
|
function getRandom(n)
|
||||||
|
local t = {
|
||||||
|
"0","1","2","3","4","5","6","7","8","9",
|
||||||
|
"a","b","c","d","e","f","g","h","i","j","k","l","m","n","o","p","q","r","s","t","u","v","w","x","y","z",
|
||||||
|
"A","B","C","D","E","F","G","H","I","J","K","L","M","N","O","P","Q","R","S","T","U","V","W","X","Y","Z",
|
||||||
|
}
|
||||||
|
local s = ""
|
||||||
|
for i =1, n do
|
||||||
|
s = s .. t[math.random(#t)]
|
||||||
|
end;
|
||||||
|
return 't'..s
|
||||||
|
end
|
||||||
76
readme.md
Normal file
76
readme.md
Normal file
@@ -0,0 +1,76 @@
|
|||||||
|
### 0x01 简介
|
||||||
|
|
||||||
|
这是一个基于openresty的安全网关,使用提供的指令和接口将lua代码插入至nginx处理http请求的不同阶段来实现包过滤效果,相较于传统waf该网关侧重于业务方面的防护,特点之一是具备防自动化工具请求能力,但目前还只是一个demo项目,具体的开发过程记录在[这里](https://ainrm.cn/2022/safegate.html),后续可能会增加如文中所规划的功能
|
||||||
|
|
||||||
|

|
||||||
|
|
||||||
|
### 0x02 文件说明
|
||||||
|
|
||||||
|
核心文件是`init.lua`,包含了具体的处理逻辑,`config.lua`为配置文件,决定是否启用某些功能,然后在nginx中配置`access_by_lua_file`、`header_filter_by_lua_file`、`body_filter_by_lua_file`来调用具体函数
|
||||||
|
|
||||||
|
```bash
|
||||||
|
.
|
||||||
|
├── 403.lua # 403页面
|
||||||
|
├── aes.lua # aes加解密
|
||||||
|
├── b64.lua # base64转码
|
||||||
|
├── config.lua # 配置文件
|
||||||
|
├── fileio.lua # 文件io相关
|
||||||
|
├── init.lua # 处理请求的具体逻辑
|
||||||
|
├── log.lua # 日志相关
|
||||||
|
├── log # 保存日志的路径
|
||||||
|
│ ├── error.log
|
||||||
|
│ └── localhost_2022-02-11_sec.log
|
||||||
|
├── nginx
|
||||||
|
│ ├── nginx.conf # 示例配置
|
||||||
|
│ └── zE48AHvK # 下发cookie相关文件
|
||||||
|
│ ├── crypto-js.min.js
|
||||||
|
│ ├── index.html
|
||||||
|
│ ├── info.html
|
||||||
|
│ ├── info.js
|
||||||
|
│ ├── jump.js
|
||||||
|
│ └── webdriver.js
|
||||||
|
├── node # babel混淆规则
|
||||||
|
│ └── js_confuse.js
|
||||||
|
├── randomStr.lua # 产生随机字符串
|
||||||
|
├── req.lua # 处理发来的请求,由access_by_lua_file调用
|
||||||
|
├── resty -> /usr/local/openresty/lualib/resty # 软链接过来的库文件
|
||||||
|
├── rsp_body.lua # 处理返回包体内容,由body_filter_by_lua_file调用
|
||||||
|
├── rsp_header.lua # 处理返回包头内容,header_filter_by_lua_file调用
|
||||||
|
├── tableXstring.lua # table与string转换
|
||||||
|
└── whiteList.lua # 白名单相关
|
||||||
|
```
|
||||||
|
|
||||||
|
### 0x03 使用说明
|
||||||
|
|
||||||
|
首先在http块中引入lua文件:
|
||||||
|
|
||||||
|
- lua_package_path
|
||||||
|
- lua_shared_dict
|
||||||
|
- init_by_lua_file
|
||||||
|
|
||||||
|
然后在server块中引用具体lua文件:
|
||||||
|
|
||||||
|
- access_by_lua_file
|
||||||
|
- header_filter_by_lua_block
|
||||||
|
- body_filter_by_lua_file
|
||||||
|
|
||||||
|
示例:
|
||||||
|
|
||||||
|
```lua
|
||||||
|
http {
|
||||||
|
lua_package_path "/gate/?.lua";
|
||||||
|
lua_shared_dict limit 10m;
|
||||||
|
init_by_lua_file /gate/init.lua;
|
||||||
|
|
||||||
|
server {
|
||||||
|
location /test {
|
||||||
|
access_by_lua_file /gate/req.lua;
|
||||||
|
proxy_pass http://127.0.0.1:8000/req;
|
||||||
|
proxy_connect_timeout 2s;
|
||||||
|
header_filter_by_lua_file /gate/rsp_header.lua;
|
||||||
|
body_filter_by_lua_file /gate/rsp_body.lua;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
```
|
||||||
|
|
||||||
2
rsp_body.lua
Normal file
2
rsp_body.lua
Normal file
@@ -0,0 +1,2 @@
|
|||||||
|
jsConfuse()
|
||||||
|
dateReplace()
|
||||||
2
rsp_header.lua
Normal file
2
rsp_header.lua
Normal file
@@ -0,0 +1,2 @@
|
|||||||
|
ngx.header.content_length = nil
|
||||||
|
respCookieEncrypt()
|
||||||
73
tableXstring.lua
Normal file
73
tableXstring.lua
Normal file
@@ -0,0 +1,73 @@
|
|||||||
|
|
||||||
|
function ToStringEx(value)
|
||||||
|
if type(value)=='table' then
|
||||||
|
return TableToStr(value)
|
||||||
|
elseif type(value)=='string' then
|
||||||
|
return "\'"..value.."\'"
|
||||||
|
else
|
||||||
|
return tostring(value)
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
|
|
||||||
|
function TableToStr(t)
|
||||||
|
if t == nil then return "" end
|
||||||
|
local retstr= "{"
|
||||||
|
|
||||||
|
local i = 1
|
||||||
|
for key,value in pairs(t) do
|
||||||
|
local signal = ","
|
||||||
|
if i==1 then
|
||||||
|
signal = ""
|
||||||
|
end
|
||||||
|
|
||||||
|
if key == i then
|
||||||
|
retstr = retstr..signal..ToStringEx(value)
|
||||||
|
else
|
||||||
|
if type(key)=='number' or type(key) == 'string' then
|
||||||
|
retstr = retstr..signal..'['..ToStringEx(key).."]="..ToStringEx(value)
|
||||||
|
else
|
||||||
|
if type(key)=='userdata' then
|
||||||
|
retstr = retstr..signal.."*s"..TableToStr(getmetatable(key)).."*e".."="..ToStringEx(value)
|
||||||
|
else
|
||||||
|
retstr = retstr..signal..key.."="..ToStringEx(value)
|
||||||
|
end
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
|
i = i+1
|
||||||
|
end
|
||||||
|
|
||||||
|
retstr = retstr.."}"
|
||||||
|
return retstr
|
||||||
|
end
|
||||||
|
|
||||||
|
|
||||||
|
function StrToTable(str)
|
||||||
|
if str == nil or type(str) ~= "string" then
|
||||||
|
return
|
||||||
|
end
|
||||||
|
|
||||||
|
return loadstring("return " .. str)()
|
||||||
|
end
|
||||||
|
|
||||||
|
function transTable(xxx)
|
||||||
|
local yyy = {}
|
||||||
|
for i=#xxx,1,-1 do
|
||||||
|
if #yyy ~= 0 then
|
||||||
|
yyy = xxx[i].."; "..yyy
|
||||||
|
else
|
||||||
|
yyy = xxx[i]
|
||||||
|
end
|
||||||
|
end
|
||||||
|
return yyy
|
||||||
|
end
|
||||||
|
|
||||||
|
|
||||||
|
function split( str,reps )
|
||||||
|
local resultStrList = {}
|
||||||
|
string.gsub(str,'[^'..reps..']+',function ( w )
|
||||||
|
table.insert(resultStrList,w)
|
||||||
|
end)
|
||||||
|
return resultStrList
|
||||||
|
end
|
||||||
9
whiteList.lua
Normal file
9
whiteList.lua
Normal file
@@ -0,0 +1,9 @@
|
|||||||
|
function whiteExtCheck()
|
||||||
|
local reqExt = string.match(ngx.var.uri, ".+%.(%w+)$") --js
|
||||||
|
for _,e in ipairs(whiteExt) do -- js、css、png
|
||||||
|
if reqExt == e then -- 在白名单里
|
||||||
|
return true
|
||||||
|
end
|
||||||
|
end
|
||||||
|
return false
|
||||||
|
end
|
||||||
Reference in New Issue
Block a user