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
|