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 に答える