0

我有一个表,其中存储(除其他位之外)IP 地址、*日期* 和每次尝试登录我的站点的SERIAL PK 。

logon table: logref SERIAL, ipaddress CHAR(20),logtime DATETIME,logresult (BOOL) (1=success)

我想做的是false,在从该 IP 地址最后一次有效登录之后,在给定的时间跨度内计算每个 IP 地址的登录次数或不正确的登录次数。

到目前为止,我所拥有的是:

SELECT ipaddress FROM logon 
    WHERE logref>=
    (
    SELECT MIN(logref) FROM logon WHERE 
    TIMESTAMPDIFF( HOUR , logtime,'2013-06-10 22:00:00' )<12
    )
    AND logresult=0
    GROUP BY ipaddress

这给了我一个登录尝试失败的所有 IP 地址的列表。

我一直在尝试将它与另一个 SQL 合并:

SELECT COUNT( logref ) AS count
FROM logon
WHERE logname = '$user'
AND  TIMESTAMPDIFF( HOUR ,logtime,'$timenow')<=$locktime
AND logref>(SELECT logref FROM logon 
WHERE logname = '$user'
AND logresult='1'
ORDER BY logtime DESC LIMIT 1)

这很好地计算了给定用户在 $locktime 中失败的登录尝试次数。

可悲的是,我对子查询很陌生,我在尝试嵌套它们时迷路了。

本质上,这个想法是我应该能够计算每个 ip 的错误登录次数,以降低拒绝服务攻击和计算机化登录猜测攻击的风险。

在这种情况下,Recaptcha 等不是可行的解决方案 - 它只能是登录名/密码组合。

因为由于 NAT,很多人会从同一个 IP 地址登录,所以仅仅锁定过去 x 小时内具有给定数量的虚假 IP 是不够的,它确实需要在自那时以来已经存在一定数量的地方最后一次正确登录。

白名单将不起作用,因为可能有很多人从许多 IP 访问 - 尽管大多数登录将来自工作场所,但也有一些来自家庭。

我将自动将任何具有 12 个(或更好的数字,如果您建议)或更多失败登录且没有正确登录的 IP 地址列入黑名单。

任何评论:

当没有恶作剧发生时,给定 IP 可能会出现多少次失败登录(初始安全参数指南)

是否有更好的方法来做到这一点。

在自动锁定之前,应该允许从给定 IP 地址进行多少次没有良好登录的失败登录。

这种方案多久会惹恼真正的用户

将不胜感激,因为当然,这将是我棘手的 SQL 问题的解决方案。

4

1 回答 1

1

通过 ipaddress 找出最后一次良好的登录

SELECT
  max(logref) max_logref,
  ipaddress
FROM logon
WHERE logresult = TRUE
GROUP BY ipaddress

更新

这将为您提供在时间范围内没有良好登录的登录(最后一天)

SELECT 
  ipaddress, 
  count(*)
FROM 
  logon
WHERE logtime > date_sub(now(), interval 1 day)
GROUP BY ipaddress
having max(logresult) = false

然后,您可以找出错误的登录次数

SELECT 
  logon.ipaddress, 
  count(*) bad_logins
FROM
  logon 
JOIN ( 
    SELECT
      max(logref) max_logref,
      ipaddress
    FROM logon
    WHERE logresult = TRUE
    AND logtime > date_sub(now(), interval 1 day) 
    GROUP BY ipaddress  
  ) good 
ON
  logon.ipaddress = good.ipaddress and 
  logon.logref > good.max_logref 
GROUP BY
  logon.ipaddress 


UNION

SELECT 
  ipaddress, 
  count(*)
FROM 
  logon
WHERE logtime > date_sub(now(), interval 1 day)
GROUP BY ipaddress
having max(logresult) = false

sqlfiddle

于 2013-06-11T10:46:24.803 回答