C.W.K.
Stream
Lesson 06 of 07 · published

Connection Limit

~12 min · management, rate-limit, abuse

Level 0Poller
0 XP0/60 lessons0/10 achievements
0/120 XP to next level120 XP to go0% complete

Abuse 의 두 축

WebSocket abuse 두 모양: 한 source 에서 너무 많은 connection, 또는 한 connection 에 너무 많은 message. 완화책 다름. Connection limit 이 서버 자원 (file descriptor, memory) 고갈 캡. message rate limit 이 시끄러운/악성 클라 캡 — connection drop 안 하면서.

IP 별 connection cap

source IP 별 활성 connection 추적. cap 넘으면 code 4029 로 reject (application 관습; HTTP 의 429 와 비슷). proxy 뒤에선 조심: websocket.client.host 가 real client 아니라 proxy IP 일 수 있어. 역방향 proxy 가 X-Forwarded-For 설정하면 그거 써.

Connection 별 message rate limit

WebSocket 별 최근 message timestamp 추적. 마지막 1초 안에 limit 넘으면 message drop, {type: 'error', code: 'rate_limited'} 응답. connection close 하지 마 — 그건 escalation, 네트워크 fail 처럼 보여. 악용 message 만 drop, 계속 가.

Code

Connection + message rate limit 결합·python
from collections import defaultdict, deque
from fastapi import WebSocket
import time

class LimitedManager:
    def __init__(self, *, max_per_ip=20, max_msg_per_sec=20):
        self.max_per_ip = max_per_ip
        self.max_msg_per_sec = max_msg_per_sec
        self.ip_counts: Dict[str, int] = defaultdict(int)
        self.msg_window: Dict[WebSocket, deque] = {}

    async def connect(self, ws: WebSocket) -> bool:
        ip = (ws.headers.get('x-forwarded-for', '').split(',')[0].strip()
              or (ws.client.host if ws.client else 'unknown'))
        if self.ip_counts[ip] >= self.max_per_ip:
            await ws.close(code=4029, reason='too many connections')
            return False
        self.ip_counts[ip] += 1
        self.msg_window[ws] = deque()
        await ws.accept()
        return True

    def check_rate(self, ws: WebSocket) -> bool:
        now = time.time()
        win = self.msg_window.get(ws)
        if win is None:
            return False
        while win and now - win[0] > 1.0:
            win.popleft()
        if len(win) >= self.max_msg_per_sec:
            return False
        win.append(now)
        return True

External links

Exercise

max_per_ip=2 로 같은 브라우저에서 같은 endpoint 에 탭 셋 열어. 세 번째는 code 4029 로 reject 되어야 함. 그 다음 max_msg_per_sec=5 로 100 message tight loop — 초당 첫 5 만 성공, 나머지는 rate_limited error 받아야 함.

Progress

Progress is local-only — sign in to sync across devices.
이 페이지에서 버그를 발견하셨거나 피드백이 있으세요?문제 신고

댓글 0

🔔 답글 알림 (로그인 필요)
로그인댓글을 남기려면 로그인해 주세요.

아직 댓글이 없어요. 첫 댓글을 남겨보세요.