170 lines
6.5 KiB
Lua
170 lines
6.5 KiB
Lua
local skynet = require "skynet"
|
||
local oo = require "Class"
|
||
local gameCmd = require "GameCmd"
|
||
local json =require "json"
|
||
local log = require "Log"
|
||
local sqlUrl = require "SqlUrl"
|
||
local errorInfo = require "ErrorInfo"
|
||
local serverId = tonumber(skynet.getenv "serverId")
|
||
local redisKeyUrl = require "RedisKeyUrl"
|
||
local clusterServer = require "ClusterServer"
|
||
local MonitorServer = oo.class(clusterServer)
|
||
|
||
MonitorServer.per10Second = 10
|
||
|
||
--初始化
|
||
function MonitorServer:Init()
|
||
skynet.server.redis:sadd("PlatformType","1")
|
||
skynet.server.redis:zadd( string.format(redisKeyUrl.BlackListAccount , "1") , 0 , "init member" )
|
||
skynet.server.redis:zadd( string.format(redisKeyUrl.BlackListAddr , "1") , 0 , "init member" )
|
||
self.statData = {}
|
||
self.statData.loginAccount = {} --统计登录的帐号
|
||
self.statData.loginIp = {} --统计登录的IP
|
||
end
|
||
|
||
--跨天
|
||
function MonitorServer:OnNewDay()
|
||
|
||
end
|
||
|
||
--1秒Timer
|
||
function MonitorServer:On1SecTimer()
|
||
|
||
end
|
||
|
||
--5秒Timer
|
||
function MonitorServer:On5SecTimer()
|
||
self:CheckAttack()
|
||
self:CheckUnlockIP()
|
||
end
|
||
|
||
--接收集群数据
|
||
function MonitorServer:ClusterRecv(...)
|
||
local cmd , c2sData = ...
|
||
local s2cData = {}
|
||
s2cData.code = errorInfo.Suc
|
||
|
||
if self.Center2All_SyncClusterInfo == cmd then
|
||
self:RecvSyncClusterInfo( c2sData )
|
||
elseif self.Center2All_SyncServerConfig == cmd then --同步服务器配置
|
||
self:RecvSyncServerConfig( c2sData )
|
||
elseif self.Route2Monitor_VerifyValid == cmd then
|
||
self:VerifyValid( c2sData , s2cData )
|
||
elseif self.All2Moniter_AddAccountToBlack == cmd then
|
||
self:AddAccountToBlack( c2sData , s2cData )
|
||
elseif self.All2Moniter_AddIPToBlack == cmd then
|
||
self:AddIPToBlack( c2sData , s2cData )
|
||
else
|
||
log.info(string.format("集群服务器 消息接口 %d 不存在", cmd))
|
||
s2cData.code = errorInfo.ErrorCode.NoExistInterface
|
||
end
|
||
|
||
log.info("集群服务器 消息接口", cmd , "返回信息",s2cData.code)
|
||
return s2cData
|
||
end
|
||
|
||
--验证有效
|
||
function MonitorServer:VerifyValid( c2sData , s2cData )
|
||
--检测账号是否为在黑名单中
|
||
local key = string.format(redisKeyUrl.BlackListAccount , c2sData.platform )
|
||
local isSuc = skynet.server.redis:sismember( key , c2sData.loginAccount )
|
||
if isSuc then
|
||
--帐号在黑名单中
|
||
s2cData.code = errorInfo.ErrorCode.BlackListAccount
|
||
else
|
||
key = string.format(redisKeyUrl.BlackListAddr , c2sData.platform)
|
||
local rank = skynet.server.redis:zrank( key , c2sData.addr )
|
||
if nil == rank then
|
||
--IP在在黑名单中
|
||
s2cData.code = errorInfo.ErrorCode.BlackListAddr
|
||
else
|
||
--成功登录
|
||
--统计下帐号登录次数
|
||
key = c2sData.platform..":"..c2sData.loginAccount
|
||
if not self.statData.loginAccount[ key ] then
|
||
self.statData.loginAccount[ key ] = {}
|
||
self.statData.loginAccount[ key ].count = 0
|
||
self.statData.loginAccount[ key ].refreshTime = skynet.GetTime()
|
||
end
|
||
self.statData.loginAccount[ key ].count = self.statData.loginAccount[ key ].count + 1
|
||
|
||
--统计下IP登录次数
|
||
key = c2sData.addr
|
||
if not self.statData.loginIp[ key ] then
|
||
self.statData.loginIp[ key ] = {}
|
||
self.statData.loginIp[ key ].count = 0
|
||
self.statData.loginIp[ key ].refreshTime = skynet.GetTime()
|
||
end
|
||
self.statData.loginIp[ key ].count = self.statData.loginIp[ key ].count + 1
|
||
end
|
||
end
|
||
end
|
||
|
||
--添加帐号到黑名音
|
||
function MonitorServer:AddAccountToBlack( c2sData , s2cData )
|
||
local key = string.format(redisKeyUrl.BlackListAccount , c2sData.platform )
|
||
local isSuc = skynet.server.redis:sadd( key , c2sData.loginAccount )
|
||
if isSuc then
|
||
log.info(string.format("监控服 账号加入黑名单 平台 %s 账号 %s 成功" , c2sData.platform , c2sData.loginAccount))
|
||
else
|
||
log.info(string.format("监控服 账号加入黑名单 平台 %s 账号 %s 失败" , c2sData.platform , c2sData.loginAccount))
|
||
end
|
||
end
|
||
|
||
--添加IP到黑名音
|
||
function MonitorServer:AddIPToBlack(c2sData , s2cData )
|
||
local key = string.format(redisKeyUrl.BlackListAddr , c2sData.platform )
|
||
local isSuc = skynet.server.redis:zadd( key , skynet.GetTime() , c2sData.loginAccount )
|
||
if isSuc then
|
||
log.info(string.format("监控服 IP加入黑名单 平台 %s 账号 %s 成功" , c2sData.platform , c2sData.loginAccount))
|
||
else
|
||
log.info(string.format("监控服 IP加入黑名单 平台 %s 账号 %s 失败" , c2sData.platform , c2sData.loginAccount))
|
||
end
|
||
end
|
||
|
||
--检测攻击行为
|
||
function MonitorServer:CheckAttack()
|
||
for k, v in pairs( self.statData.loginAccount ) do
|
||
--小于10秒并且数量大于阈值就拉黑名单
|
||
if skynet.GetTime() <= v.refreshTime + self.per10Second and v.count >= self.serverInfo.LoginMaxCount10Second then
|
||
local tmp = skynet.server.common:Split( k , ":")
|
||
local c2sData = {}
|
||
c2sData.platform = tmp[1]
|
||
c2sData.loginAccount = tmp[2]
|
||
self:AddAccountToBlack( c2sData )
|
||
elseif skynet.GetTime() > v.refreshTime + self.per10Second then
|
||
--清空
|
||
self.statData.loginAccount[ k ] = nil
|
||
end
|
||
end
|
||
|
||
for k, v in pairs( self.statData.loginIp ) do
|
||
--小于10秒并且数量大于阈值就拉黑名单
|
||
if skynet.GetTime() <= v.refreshTime + self.per10Second and v.count >= self.serverInfo.LoginMaxCount10Second then
|
||
local tmp = skynet.server.common:Split( k , ":")
|
||
local c2sData = {}
|
||
c2sData.platform = tmp[1]
|
||
c2sData.loginAccount = tmp[2]
|
||
self:AddIPToBlack( c2sData )
|
||
elseif skynet.GetTime() > v.refreshTime + self.per10Second then
|
||
--清空
|
||
self.statData.loginIp[ k ] = nil
|
||
end
|
||
end
|
||
end
|
||
|
||
--检测IP是否能解锁
|
||
function MonitorServer:CheckUnlockIP()
|
||
--删除当前时间之前一小时的黑名单IP
|
||
local key = string.format(redisKeyUrl.BlackListAddr , "Apple" )
|
||
local unlockTime = skynet.GetTime() - self.serverInfo.IPUnlockTime
|
||
skynet.server.redis:zremrangebyscore( key , "-inf" , unlockTime )
|
||
end
|
||
|
||
--如果是当前服务器ID,那么就加入进来
|
||
if serverId == clusterServer.monitorServerID then
|
||
skynet.server.monitorServer = MonitorServer
|
||
end
|
||
|
||
return MonitorServer
|