2014-01-09 3 views
-1

로그인에 블록을 구현하기 때문에 (10?) 로그인에 실패한 경우 (예 : 무단 침입 시도) 계정이 몇 분 동안 로그인을 시도 할 수없는 경우 (유효한 비밀번호가있는 경우에도) ... redis를 사용하여 로그인 시도를 어떻게 제한합니까?

나는 비록 그들은 두 가지 구현을 제공 레디 스를 사용하여 은어를 제한 속도,의와 redis.io에 : Pattern: Rate limiter

는하지만 특히 동시성 또는 손실 명령의 경우, 모두에 문제를 제공합니다.

어떤 솔루션을 추천하십니까?

답변

-1

가능한 해결책을 찾았습니다. 이 의사 코드 :

FUNCTION LIMIT_API_CALL(key): 
value = INCR(key) 
IF value > 10 THEN 
    ERROR "too many requests" 
ELSE 
    EXPIRE(key, blockedTime) 
    PERFORM_API_CALL() 
END 

이 redis.io에 링크 된 구현에 비해 약간 문제를 이동하는 것 같다,하지만 난 어떤 메모리 누수가 없도록이 언급 된 문제에 대한 강력한 생각하고, 명령 중 하나가 실패하더라도 TTL은 항상 설정됩니다.

EDIT (나중에 년) :이 트릭은 첫번째 코멘트에서 검출 문제를 해결하기 위해 다음과 같은 추가와 함께, 생산에 배포 된

: PERFORM_API_CALL의 성공적인 리턴 키를 삭제

을, 만료 카운터 재설정 :

FUNCTION LIMIT_API_CALL(key): 
value = INCR(key) 
IF value > 10 THEN 
    ERROR "too many requests" 
ELSE 
    IF (PERFORM_API_CALL()) 
     DEL(key) 
    ELSE 
     EXPIRE(key, blockedTime) 
END 
+0

이것은 간단하고 빠른 코드 비트로 보입니다. 경쟁 조건이나 코딩 결함과 관련이없는 몇 가지 문제가 발생할 수 있다고 생각합니다. 예를 들어 '시간당 10 회의 로그인 시도 만 허용하려는 경우'사용자가 30 분마다 한 번만 로그인을 시도하면 5 시간 이내에 다시 한 번 전체 로그인 시도가 거부됩니다.이 동작은 ' 2 시간 동안 로그인 시도 "를 거부합니다. 또 다른 시나리오는 첫 번째 로그인 시도부터 9 번째 세션까지 거의 한 시간이 지났지 만 사용자는 한 시간 만에 한 번 더 시도 할 수 있습니다. – ChisholmKyle

+0

물론 맞습니다. 그러나이 문제는 매우 간단한 속임수에 의해 감지되고 해결되었습니다. 성공적인 로그인 후에 키가 제거 (및 실패 다시 설정)되므로 만료 만료 카운터가 트리거됩니다. 이것은 성공적인 로그인이 언제 일어날지를 아는 경우 공격자가 더 많은 조합을 시도 할 수 있지만 만료 유닛 당 성공적으로 로그인 할 때마다 속도를 두 배로 올릴 수 있습니다. 이는 현실 세계에서는별로 발생하지 않습니다. – Daren

관련 문제