Files
telegram-bot-workers/SUMMARY.md
kappa 4eb5bbd3d3 feat(security): API 키 보호, CORS 강화, Rate Limiting KV 전환
보안 개선:
- API 키 하드코딩 제거 (NAMECHEAP_API_KEY_INTERNAL)
- CORS 정책: * → hosting.anvil.it.com 제한
- /health 엔드포인트 DB 정보 노출 방지
- Rate Limiting 인메모리 Map → Cloudflare KV 전환
  - 분산 환경 일관성 보장
  - 재시작 후에도 유지
  - 자동 만료 (TTL)

문서:
- CLAUDE.md Security 섹션 추가
- KV Namespace 설정 가이드 추가
- 배포/마이그레이션 가이드 추가

Co-Authored-By: Claude Sonnet 4.5 <noreply@anthropic.com>
2026-01-19 15:20:14 +09:00

4.7 KiB

Rate Limiting KV Migration - 작업 완료 요약

작업 개요

Rate Limiting 시스템을 인메모리 Map에서 Cloudflare KV로 마이그레이션하여 분산 환경에서 일관된 동작을 보장합니다.


변경 사항 요약

해결된 문제

Workers 인스턴스 간 Rate Limit 데이터 공유 Worker 재시작 시에도 Rate Limit 상태 유지 분산 환경에서 일관된 Rate Limiting 동작 자동 만료 (KV TTL) - 메모리 효율성

수정된 파일 (4개)

  1. wrangler.toml - KV Namespace 바인딩 추가
  2. src/types.ts - Env 인터페이스에 RATE_LIMIT_KV 추가
  3. src/security.ts - checkRateLimit() 함수 KV 기반으로 재구현
  4. src/index.ts - checkRateLimit() 호출 시 KV 전달

문서 업데이트

  • CLAUDE.md - Rate Limiting 섹션, Configuration 섹션 업데이트
  • KV_MIGRATION_GUIDE.md - 상세 마이그레이션 가이드 (신규)
  • DEPLOYMENT_SUMMARY.md - 배포 절차 요약 (신규)

배포 가이드

1. KV Namespace 생성 (최초 1회)

wrangler kv:namespace create RATE_LIMIT_KV

출력된 id 값을 복사합니다.

2. wrangler.toml 수정

22번 줄의 YOUR_KV_NAMESPACE_ID를 실제 ID로 변경:

[[kv_namespaces]]
binding = "RATE_LIMIT_KV"
id = "abc123def456ghi789jkl012mno345pq"  # ← 실제 ID로 변경

3. 로컬 테스트

npm run dev

다른 터미널에서 테스트:

curl -X POST http://localhost:8787/webhook \
  -H "Content-Type: application/json" \
  -H "X-Telegram-Bot-Api-Secret-Token: YOUR_WEBHOOK_SECRET" \
  -d '{"update_id":1,"message":{"message_id":1,"from":{"id":123,"is_bot":false,"first_name":"Test"},"chat":{"id":123,"type":"private"},"date":1234567890,"text":"테스트"}}'

4. Production 배포

npm run deploy

5. 배포 확인

# Health Check
curl https://telegram-summary-bot.kappa-d8e.workers.dev/health

# 로그 확인
npm run tail

기술 상세

Rate Limiting 알고리즘

Key 형식: ratelimit:{userId}

데이터:

{
  count: number,      // 현재 윈도우 내 요청 수
  resetAt: number     // 윈도우 만료 시각 (Unix ms)
}

동작:

  1. KV에서 사용자별 카운터 조회
  2. 윈도우 만료 확인 (now > resetAt)
    • 만료 시: 새 윈도우 시작 (count=1)
    • 유효 시: count 증가
  3. count >= 30 → Rate Limit 초과, 차단
  4. count < 30 → KV 업데이트, 허용

자동 만료: KV의 expirationTtl 사용 (60초)

에러 처리: KV 오류 시 요청 허용 (가용성 우선)


성능 영향

항목 Before (Map) After (KV)
응답 시간 ~1ms ~20-50ms
메모리 인스턴스별 0 (KV)
일관성 분산 불일치 전역 일관성
재시작 데이터 손실 유지

결론: 약 20-50ms 지연 추가되지만, Telegram Webhook은 200ms 이내 응답 권장이므로 충분히 허용 가능.


비용 분석

Cloudflare Workers Free Plan

  • KV 읽기: 100,000 reads/day (무료)
  • KV 쓰기: 1,000 writes/day (무료)

예상 사용량

  • 1 메시지 = 1 read + 1 write
  • 일일 1,000 메시지까지 무료
  • 현재 사용량: ~100 메시지/일 → $0 (무료)

모니터링

KV Dashboard

https://dash.cloudflare.com → Workers & Pages → KV → telegram-summary-bot-RATE_LIMIT_KV

CLI 명령어

# Namespace 목록
wrangler kv:namespace list

# 특정 사용자 Rate Limit 조회
wrangler kv:key get "ratelimit:821596605" --namespace-id=YOUR_KV_ID

# 모든 키 목록
wrangler kv:key list --namespace-id=YOUR_KV_ID

# 로그 확인
wrangler tail

롤백 절차 (문제 발생 시)

git revert HEAD
npm run deploy

또는 수동 롤백:

  1. wrangler.toml에서 KV Namespace 제거
  2. src/types.ts, src/security.ts, src/index.ts 이전 버전 복원
  3. npm run deploy

체크리스트

배포 전

  • wrangler kv:namespace create RATE_LIMIT_KV 실행
  • wrangler.toml에 실제 KV Namespace ID 입력
  • 로컬 테스트 (npm run dev) 성공

배포 후

  • npm run deploy 성공
  • Health Check 정상
  • 실제 Telegram 메시지 테스트
  • KV Dashboard에서 키 생성 확인
  • 30회 연속 메시지로 Rate Limit 동작 확인

추가 리소스


작업 완료 시각: 2026-01-19 상태: 코드 변경 완료 / 배포 대기 중 다음 단계: KV Namespace 생성 → wrangler.toml 수정 → 배포