pile·
인프라 / DevOps·우아한형제들우아한형제들·

멀티 어카운트 NACL 차단 자동화 도구 운영 및 개선 경험

수십 개 AWS 계정에 걸쳐 공격 IP를 차단하는 NACL 자동화 도구(WOOWA-SOC-ACL-IR)를 운영하면서 마주한 분산 시스템 함정 5가지와 이를 해결한 과정을 기록했다. 단위 동작은 정상이고 로그에는 200이 찍히고 슬랙에 GOOD이 떠 있는데 실제 상태는 조금씩 어긋나 있는 종류의 버그들이었다. SQS FIFO + Lambda fan-out 구조에서 NACL과 DynamoDB 정합성이 어떻게 무너지는지, Lambda reserved concurrency로 race condition을 어떻게 막는지 구체적인 코드와 함께 설명한다.

핵심 포인트
  • NACL 생성 성공 후 DDB 기록 실패: create_network_acl_entry 반환값(False)을 검사하지 않아 차단 실패가 조용히 성공으로 기록
  • 한 계정 sync 불일치 발견 시 exit() 호출 → SystemExit이 잡히지 않아 다른 정상 계정까지 차단 누락
  • 부분 실패 가림: Python int 값 전달로 update_error_value 누적 안 됨, 마지막 계정 성공이면 중간 실패 전부 지워지고 GOOD 보고
  • alldelete 직후 잔여 룰: 수백 번 API 호출 중 throttle로 삭제 누락 후 재시도 없이 종료
  • race condition: SQS FIFO가 메시지 순서를 잡아도 두 Lambda 동시 실행의 NACL-DDB 중간 상태는 막지 못함 → reserved concurrency=1로 해결
상세 정리
  • 초기 구조: API Gateway → SQS FIFO → 컨슈머 Lambda → NACL 차단 Lambda(STS AssumeRole 계정별 진입) → DDB 메타데이터 기록, NACL 슬롯 40개 한도에서 21-50번 30개를 침해대응 전용으로 확보
  • 문제 1: create_netacl_rule()이 예외 없이 return False할 때 try/except가 잡지 못해 DDB에 차단 완료로 기록됨
  • 해결 1: 반환값 False면 명시적 예외 throw, NACL 생성 직후 describe_network_acls로 최대 9초간 readback 검증 루프 추가(eventual consistency 대응)
  • 문제 2: 한 계정 sync 불일치 시 exit() → SystemExit이 for-loop 밖 try/except에 잡히지 않아 나머지 정상 계정도 차단 누락
  • 해결 2: exit() → continue로 교체, 해당 계정만 건너뛰고 Slack 보고 후 나머지 계정 처리 이어감
  • 문제 3: update_error_value를 Python int 값으로 헬퍼에 전달하면 호출자 측 변수가 변하지 않음, 마지막 계정 값만 남아 중간 실패가 가려짐
  • 해결 3: 루프마다 헬퍼 반환값을 변수에 재대입해 누적, 계정 단위 try/except 격리
  • 문제 4: alldelete 시 delete_network_acl_entry 수백 번 호출 중 throttle/5xx 후 재시도 없이 GOOD 보고, 잔여 룰 남음
  • 해결 4: 1차 삭제 후 2초 대기 → NACL 재조회 → 잔여분 1회 retry → 그래도 남으면 FAIL 명시 보고
  • 문제 5: 두 차단 Lambda가 거의 동시에 실행될 때, NACL 추가 완료 후 DDB 기록 전 짧은 중간 상태를 다른 Lambda의 sync_check가 불일치로 잘못 판정
  • 해결 5: Lambda reserved concurrency=1로 차단 Lambda 직렬화, 컨슈머 대기 72초 → 7초로 단축(FIFO MessageGroupId가 순서 담당), botocore adaptive 재시도 모드로 throttle 자동 흡수
  • 1차 실패 계정 즉시 retry: fan-out 후 실패 계정 추적 → 5초 대기 → 1회 재시도 → 복구 시 Slack 보고
  • 패치 후 결과: 컨슈머 메시지당 처리 시간 72초 → 7초, "성공으로 위장되는 실패" 제거, 부분 실패 슬랙 가시성 확보
왜 읽나멀티 계정 AWS 자동화 운영에서 "동작하는 것처럼 보이는 실패"를 찾고 고치는 과정을 실전 코드 before/after와 함께 보여준다. Python int 전달 버그, Lambda concurrency race condition, eventually consistent NACL 검증까지 실제 프로덕션에서 발견된 사례들이라 신뢰도가 높다.
우아한형제들
우아한형제들 블로그
원문은 여기서 이어서 읽을 수 있어요
원문 읽기
읽음 (0)

이 글과 비슷한

  1. 인프라 / DevOps·cloudflare-blogCloudflare Blog·

    대규모 도그푸딩: cdnjs를 Cloudflare 개발자 플랫폼으로 이전하다

    cdnjs는 하루 90억 요청을 처리하는 오픈소스 JS/CSS CDN으로, 전 세계 웹사이트의 12%가 의존한다. 2026년 6월, Cloudflare는 6년간 GCP에서 운영하던 발행 파이프라인을 Workers, Workflows, R2, KV, Queues, Containers, Durable Objects로 완전 전환했다. 성능 문제가 아닌 관측성·유지보수성 한계가 동인이었으며, 마이그레이션 과정에서 플랫폼 한도를 직접 끌어올렸다.

    #durable-objects#workflows#cloudflare-workers+2
  2. 인프라 / DevOps·github-engGitHub Engineering·

    Dependabot 길들이기: 업데이트 묶고, 주기 늦추고, 보안은 빠르게

    GitHub의 Dependabot은 의존성 업데이트를 자동화하지만, 기본 설정에서는 10개 업데이트 = 10개 PR이 쏟아져 메인테이너가 알림을 무시하게 된다. Microsoft의 GCToolkit 사례(578개 커밋 중 92개가 Dependabot 버전 범프)를 바탕으로, 그룹핑·주기 조절·보안 업데이트 분리 3가지 설정으로 노이즈를 줄이면서 보안 속도는 유지하는 방법을 다룬다.

    #github-actions#devops#supply-chain-security+2
  3. 인프라 / DevOps·cloudflare-blogCloudflare Blog·

    Cloudflare, 프라이버시 프로토콜 디버깅 CLI pvcli 오픈소스 공개

    Cloudflare가 OHTTP(Oblivious HTTP) 등 프라이버시 보존 프로토콜 디버깅을 위한 CLI 도구 pvcli를 오픈소스(Apache-2.0)로 공개했다. 기존에는 RFC를 참조하며 바이너리를 수작업으로 파싱해야 했는데, pvcli는 curl과 유사한 문법으로 이 과정을 단일 명령으로 줄인다. Apple Private Relay·Microsoft Edge Secure Network를 구동하는 실전 규모의 경험에서 나온 도구다.

    #rust#cli#ohttp+2