对称加密实现重要日志上报Openresty接口服务
记录后端接收日志的流程;
由于记录的是广告数据,单次计费数据都会上报,全国内约10几万终端上报。
终端上报:Android电视端Apk上报
接收终端:Openresty(Nginx+lua)利用nginx非阻塞io来缓解服务器压力
数据处理:为了提高处理效率避免队列写死,采用go语言分析数据并入库
贴代码:生成uuid参数,获取客户端访问接口获取uuid,带着uuid参数上报
getuuid.lua:
--获取body数据,含get,post数据 --获取body数据,含get,post数据 local GET = {} local POST = {} ngx.req.read_body() local args_get= ngx.req.get_uri_args() local args_post = ngx.req.get_post_args() for k,v in pairs(args_get) do GET[k]=v end for k,v in pairs(args_post) do POST[k]=v end --生成加密的密钥 function unlock_mac (mac,password) local int_iv = 0 local mac_len = string.len(mac) for i = 1,mac_len do int_iv = int_iv+string.byte(mac,i) end local mac_md5 = ngx.md5(mac) iv_byte = string.sub(mac_md5,1,1)..string.sub(mac_md5,3,5)..int_iv..ngx.md5(password) return string.sub(iv_byte,1,16) end --AES解密 function unaes(key,data) local aes = require "resty.aes" local str = require "resty.string" local hash = { iv = "fedcba9876543210", method = nil } local salt = "0123456789abcdef" local aes_128_cbc, err = aes:new(key, salt, aes.cipher(128,"cbc"), hash) return aes_128_cbc:decrypt(data) end --随机数 function CreateUUID() local template ="xxxxxxxxxxxx" d = io.open("/dev/urandom", "r"):read(4) math.randomseed(os.time() + d:byte(1) + (d:byte(2) * 256) + (d:byte(3) * 65536) + (d:byte(4) * 4294967296)) return string.gsub(template, "x", function (c) local v = (c == "x") and math.random(0, 0xf) or math.random(8, 0xb) return string.format("%x", v) end) end --生成uuid function guid() local seed={'e','1','2','3','4','5','6','7','8','9','a','b','c','d','e','f'} local tb={} for i=1,32 do table.insert(tb,seed[math.random(1,16)]) end local sid=table.concat(tb) return string.format('%s-%s-%s-%s-%s', string.sub(sid,1,8), string.sub(sid,9,12), string.sub(sid,13,16), string.sub(sid,17,20), string.sub(sid,21,32) ) end --获取解密key local mac = GET["mac"] local password = "(&*87-=KLJHuywe~s.,m-=" local key = unlock_mac(mac,password) --获取post数据进行解析 local post_val = POST["data"] local unaes_val,err = unaes(key,ngx.decode_base64(post_val)) if unaes_val == nil then local json = require("cjson") json.encode_empty_table_as_object(false) local str = {code=10000,error_message="unaes err"} ngx.say(json.encode(str)) ngx.log(ngx.ERR, " unaes_val:", unaes_val) return end if GET["type"] == "app" or GET["type"] == "cd" then uidmac = GET["type"].."_uuid_"..mac else uidmac = "uuid_"..mac end local redis = require "resty.redis_iresty" local red = redis:new() redis:auth("password") redis:del(uidmac) uidtable = {} local s=0 while s<50 do s=s+1 print(CreateUUID()) local uuid = guid() local ok, err = redis:hset(uidmac,uuid,"1") if not ok then local str = {code=10000,error_message="failed to set lbs"} ngx.say(json.encode(str)) ngx.log(ngx.ERR,"setuidmac:",err) return end uidtable[s] = uuid end local json = require("cjson") --ngx.say(uidtable) datatable = {data = {list =uidtable},code = 20000} ngx.say(json.encode(datatable)) ngx.exit(200)
接收日志,存入队列:
--获取body数据,get,post数据 local GET = {} local POST = {} ngx.req.read_body() local args_get= ngx.req.get_uri_args() local args_post = ngx.req.get_post_args() for k,v in pairs(args_get) do GET[k]=v end for k,v in pairs(args_post) do POST[k]=v end --生成加密的密钥 function unlock_mac (mac,password) local int_iv = 0 local mac_len = string.len(mac) for i = 1,mac_len do int_iv = int_iv+string.byte(mac,i) end local mac_md5 = ngx.md5(mac) iv_byte = string.sub(mac_md5,1,1)..string.sub(mac_md5,3,5)..int_iv..ngx.md5(password) return string.sub(iv_byte,1,16) end --AES解密 function unaes(key,data) local aes = require "resty.aes" local str = require "resty.string" local hash = { iv = "fedcba9876543210", method = nil } local salt = "0123456789abcdef" local aes_128_cbc, err = aes:new(key, salt, aes.cipher(128,"cbc"), hash) return aes_128_cbc:decrypt(data) end --获取mac并验证 if next(GET) ~=nil and string.len(GET["mac"]) == 12 then mac = GET["mac"] else ngx.say("Mac illegal") return end local key = unlock_mac(mac,"(&*87-=KLJHuywe~s.,m-=") --验证data数据 if next(POST) ~= nil then data = POST["data"] else ngx.say("data is nil") return end -- ngx.say(key) -- ngx.say(data) local json = require("cjson") local unaes_val,err = unaes(key,ngx.decode_base64(data)) --ngx.say(unaes_val) if unaes_val == nil then local json = require("cjson") json.encode_empty_table_as_object(false) errdata = {data = {list ={}},code = 10000} ngx.say (json.encode(errdata)) return else local dataObj = json.decode(unaes_val) local redis = require "resty.redis_iresty" local red = redis:new() redis:auth("password") uidmac = "uuid_"..mac uuid = dataObj.uuid local ok= redis:hget(uidmac,uuid) if not ok then ngx.say("failed to get uidmac: ", err) ngx.log(ngx.ERR,"getuidmac:",err) return else Strmd5 = ngx.md5(dataObj.data) if "lbs" ~= dataObj.type then return end --ngx.say(dataObj.data) if Strmd5 == dataObj.md5 then local ok, err = redis:lpush('lbs_data_queue',unaes_val) if not ok then ngx.say("failed to push lbs_data_queue: ", err) ngx.log(ngx.ERR,"lbs_data_queue:",err) return end ngx.say("ok") else ngx.say("md5 check err") ngx.log(ngx.ERR,"checkmd5","lbs_data_queue") end end end
好记性不如烂笔头-_-