Flash RateLimit을 사용한 작업


Flash-Limiter의 액세스 빈도 제한을 사용하는 방법입니다.
애초 일반론으로 총공격 대책의 말과 부하 경감의 말이 적혀 있었다.

동기: 총공격 대책


웹 시스템에 대한 총공격은 해커에게 매력적인 공격 수법 중 하나다.
원리적으로 매우 간단하고, 대책이 없으면 공격은 기본적으로 성공할 것이다.수동으로는 할 수 없는 공격이지만 아주 간단한 프로그램으로 할 수 있다.
대책으로 말하자면 무엇보다'알 수 없는 아이디'를 더 복잡하게(자릿수 증가) 만들어 전체 시행 횟수를 따라잡지 못하게 하는 것이 중요하다.
여기서 설명하는 알 수 없는 ID는 일반적으로 세션 ID와 암호입니다.이외에도 구글 드라이브를 통해 주소를 알고 있는 사람에게만 공개되면 URL에 긴 ID가 포함된다는 것이 바로 이런 것이다.
앱에서 생성된 ID는 얼마든지 자릿수를 조절할 수 있어 대응이 가능하지만, 이용자의 비밀번호 제어가 어려워 다요소 인증 설정을 추천하거나 로그인 실패 횟수에 따른 잠금 기능을 설정하는 등 대책을 마련한다.그러나 각 계정의 잠금 기능은 매번 반대로 (반대로 블루투스) 할 때마다 무효다.
아마도 최근 기밀성이 높은 웹 시스템의 표준은 CAPTCHA 기능으로 BOT의 로그인 시험을 금지하는 것이 아닌가.깜찍한 대형 시스템이라면 일정 시간 여러 번 접속한 경우에만 CAPTCHA가 뜨는 친근한 디자인이 탄복할 만하다.
이번에 실시된 것은 로그인 시험 주파수를 제한하는 대책이다.이것은 단순히 서서히 실행하면 전반적인 공격은 가능하지만, 공격자 입장에서는 서서히 진행할 수 없기 때문에 효과가 있다고 볼 수 있다.IP로 인식되기 때문에 같은 글로벌 IP를 사용하는 사용자가 많은 상황에서 전원이 갑자기 차단되는 문제가 있지만 역총에 대한 유효점은 강점이다.
이번 Flash 설치는 특별히 절실하게 필요한 것이 아니라 그냥 조금 신경 써서 해 봤어요.

RateLimit


대상의 URL에 HTTP 요청을 보낼 때 HTTP 응답 헤더에 X-RateLimit-Limit와 같은 제목이 부여될 수 있습니다.
즉, 대상 웹 서비스가 동일한 IP 주소에서 일정 시간 액세스를 제한합니다.IP 주소 이외의 사용자를 식별하는 경우도 있을 수 있습니다.
PHP 등의 프레임워크를 통해 자주 제작되는 웹 응용 프로그램을 설정합니다.
웹사이트 전체가 설정한 게 도스 공격 대책으로 채택된 게 아닌가 싶어요.
무료로 이용할 수 있는 API 서비스라면 API의 부하를 줄이기 위해 이를 사용해 접근 빈도를 제한한다.
X-RateLimit-Limit 지정 횟수를 초과하여 요청을 전송하면 403 등의 응답 코드로 변경되어 액세스가 거부됩니다.
서버가 약한 사이트에서는 PHP와 Java 등 프레임워크가 접근을 거부당하는 경우가 많지만, AP 서버가 이중화된 대규모 서비스라면 경로상의 WAF가 제한될 수 있는 형태가 부하 대책으로 활용될 가능성이 크다.

Flash 응용 프로그램으로 설정


앞부분이 길어졌다.
여기서부터 Flash를 사용하여 RateLimit 방식의 액세스 빈도를 제한하는 방법입니다.
Flash는 가벼운 프레임이므로 필요에 따라 추가 패키지를 설치해야 합니다.이번에는 Flash-Limiter라는 포장을 설치합니다.
pip install Flask-Limiter
사용 방법의 강좌는 다음과 같은 공식 문서이다.
https://flask-limiter.readthedocs.io/en/stable/
위의 문서를 읽으면 알 수 있지만 자신이 설정한 요점만 기재할 수 있다.
from flask import Flask
from flask_limiter import Limiter
from flask_limiter.util import get_remote_address

app = Flask(__name__)
limiter = Limiter(app, key_func=get_remote_address, default_limits=["100 per minute"])
get_remote_address는 원격 IP 주소를 통해 판단되지만 다른 지정을 사용하는 경우는 거의 없다고 생각합니다.(스스로 정의를 내리면 국가에 따라 판단할 수 있을지도 모른다?)
기본 제한값이 100 per minute로 설정되어 있기 때문에 전체 루트에 대해'분당 최대 100회'의 제한을 준다.
route에 따라 추가 설정을 하거나 기본적으로 배제하려고 할 때 다음과 같습니다.
@app.route("/login")
@limiter.limit("500 per hour") # 制限値を追加
def login():
    ### ログイン処理
    
@app.route("/lp")
@limiter.exempt # 制限の対象外とする
def lp():
    ### ランディングページ

@app.route("/manage")
@limiter.limit("100 per day", exempt_when=lambda: current_user.is_admin) # 管理者の制限を免除
def manage():
    ### 管理上必要な処理

Nginx에서 설정


[2/28 보충]
Nginx 설정에 오류가 있는 것 같아서 삭제했습니다.
리버스 프록시라면 원격 주소를 Flash에 정확하게 전달할 필요가 있다고 생각하지만, Nginx에서 uwsgi와 Flash를 결합한 상태에서는 특히 설정할 필요가 없다.
다음 그림은 10 per hour에서 테스트할 때 브라우저에 표시됩니다.

응답 머리글에 정보 추가


그러면 상기 접근 제한이 유효해졌지만 브라우저로 접근했을 때의 응답 제목을 확인하면 X-RateLimit-Limit 없습니다.
나는 아무렇게나 켜주는 줄 알았지만, 기본적으로 반응대에 정보를 올리지 않았다.
필요 없다고 생각했는데 자꾸 징그러워서 출력 정보를 설정했어요.
app = Flask(__name__)
app.config['RATELIMIT_HEADERS_ENABLED'] = True # ヘッダーにRateLimit情報を出力
limiter = Limiter(app, key_func=get_remote_address, default_limits=["100 per minute"])
이것은 최초로 구상한 동작이다.
응답은 X-RateLimit의 3개 항목을 출력합니다.

회수의 정보는 어디에 저장됩니까


하고 싶은 일은 이루어졌지만 신경 쓰이는 일이 있다.
시스템은 모든 IP 주소의 접근 횟수를 기억해야 하는데, 이 정보는 어디에 저장되어 있습니까?RATELIMIT_STORAGE_URL 등의 옵션에 대한 설명을 보면 기본적으로 메모리에서 관리됩니다.( limits.storage.MemoryStorage )
이 근처의 자세한 방법은 모르겠지만 정식 생산에서 사용하면 엠카ched와 레디스 등이 협력하도록 해달라고 적혀 있다.
[2/28 보충]
메모리 관리 상태에서 여러 프로세스가 있으면 종합적인 관리를 할 수 없습니다.
X-RateLimit-Remaining의 수치 감소 방식은 이상하지만 uwsgi의 워크러스를 1로 설정하면 정상입니다.
이해했어, 마음이 후련해졌어.
정식 사용도 가능할 것 같아요.

좋은 웹페이지 즐겨찾기