[개인 프로젝트] 트래픽 폭증 대응 티켓 예매 서비스
콘서트·스포츠 티켓 예매처럼 순간적으로 트래픽이 폭증하는 서비스를 가정하고, 좌석 동시성 제어 · 대기열 설계 · DB 읽기/쓰기 분리 · 실시간 이상탐지를 설계·구현하고, K6 부하테스트와 자체 모의해킹으로 직접 검증한 개인 프로젝트입니다.
GitHub: https://github.com/mojodori/ticket-booking-security 환경: VMware Fusion, VM 8대, 172.16.60.0/24 작성자: 최시은 · 2026.07
핵심 결과 요약
검증 항목결과
| 좌석 동시성 제어 | 동일 좌석 100건 동시요청 → 성공 정확히 1건 |
| 트래픽 폭증 대응 (대기열) | 최대 응답지연 60,000ms → 108.8ms (약 99.8% 감소) |
| DB 복제 | Primary→Replica 실시간 동기화 확인 |
| 실시간 이상탐지 | Suricata가 공격 시뮬레이션 트래픽 실시간 탐지 |
| 자체 모의해킹 | 설계한 포트 매트릭스와 실제 nmap 결과 100% 일치 |
| 회원 인증 검증 | bcrypt 해시 저장, 로그인 5회 실패 시 423 잠금 |
1. 프로젝트 개요
일반적인 웹 서비스 포트폴리오는 "기능이 동작하는가"에 초점을 맞추지만, 티켓 예매 서비스는 그보다 중요한 질문이 걸려있다 — "공격받거나 트래픽이 폭증해도 안전하게 버티는가." 이 프로젝트 하나에 정보보안 3요소(CIA)가 모두 걸려 있다.
CIA 요소위협대응
| 기밀성 | 회원정보 유출, 내부망 스니핑 | bcrypt 해시, 네트워크 계층 분리, DB 최소권한 |
| 무결성 | 좌석 동시클릭 중복판매 | Redis 원자연산(SETNX)으로 구조적 방지 |
| 가용성 | 예매 오픈 트래픽 폭증, DoS | 대기열(Rate Limiting), 로드밸런싱, 이상탐지 |
2. 인프라 구성
사용자 → queue-gate(80) → web-lb → was-01/02 → redis / db-01(→replica)
관리자 → bastion(22, SSH전용) → 전 서버 ProxyJump
서버IP역할
| bastion | 172.16.60.142 | SSH 유일 진입점 |
| db-01 | 172.16.60.143 | MariaDB Primary |
| redis | 172.16.60.144 | 좌석 재고 원자연산 |
| was-01 | 172.16.60.145 | 예약 API #1 |
| queue-gate | 172.16.60.146 | 대기열 + Suricata IDS |
| web-lb | 172.16.60.147 | 로드밸런서 + 정적 페이지 |
| db-01-replica | 172.16.60.148 | MariaDB Replica |
| was-02 | 172.16.60.151 | 예약 API #2 |
방화벽 원칙
전 서버 ufw default-deny + 출발지 IP 화이트리스트만 허용. 허용되지 않은 것은 전부 차단이 기본 상태.
3. 핵심 설계 결정
Redis 원자연산 (DB 트랜잭션 락 대신)
DB 락은 동시요청이 몰릴수록 대기열이 길어져 응답이 느려진다. Redis는 단일 스레드 원자적 명령으로 즉시 처리 — 100건 동시요청에서도 평균 30ms대 유지.
대기열 (느리게 처리 아닌 즉시 거절)
초과 요청을 큐에 쌓으면 서버 자원이 고갈된다(실측 응답 60초). 429로 즉시 거절하면 서버는 항상 감당 가능한 용량 안에서만 일한다.
DB Read Replica
예매 오픈 시 좌석 조회가 예약 확정보다 수십~수백 배 많다. 조회를 Replica로 분리해 쓰기 트랜잭션 지연을 방지한다.
4. 검증 결과
좌석 동시성 제어
- 순차 curl 2회 / K6 내부 VU 100 / K6 외부 VU 100 — 3가지 조건 모두 DB에 정확히 1건만 저장
트래픽 폭증 대응 (대기열 ON/OFF 비교)
지표대기열 OFF대기열 ON
| checks_failed | 1.27% | 0.00% |
| 최대 응답지연 | 60,000ms | 108.8ms |
| 처리량 | 91,801건 | 864,696건 (9.4배) |
DB 복제
Primary INSERT가 Replica에 실시간 반영 확인 (Seconds_Behind_Master: 0)
실시간 이상탐지 (Suricata)
최초 별도 monitor 서버에 배치 → 트래픽 경로 밖이라 탐지 실패 → queue-gate에 직접 재배치하여 K6 공격 시뮬레이션 실시간 탐지 성공.
교훈: IDS는 탐지 룰의 정교함 이전에 "트래픽 경로 위에 있는가"가 우선한다.
5. 자체 모의해킹
nmap 포트 스캔 (외부 관점)
서버22804433000/3306/6379
| queue-gate | filtered | open | closed | filtered |
| web-lb | filtered | filtered | filtered | filtered |
| was-01 | filtered | filtered | filtered | filtered |
→ 설계한 포트 매트릭스와 실제 스캔 결과 100% 일치
Nikto 웹 취약점 스캔
헤더1차조치 후
| Content-Security-Policy | 누락 | 반영됨 |
| Referrer-Policy | 누락 | 반영됨 |
| Permissions-Policy | 누락 | 반영됨 |
| X-Content-Type-Options | 누락 | 미반영 (재조사 필요) |
| Strict-Transport-Security | 누락 | TLS 적용 후 예정 |
6. 웹 애플리케이션 취약점 분석 (OWASP Top 10 자가점검)
항목상태
| A02 Cryptographic Failures | ✅ 구현·검증완료 (bcrypt) |
| A03 Injection | ✅ 구현 (파라미터 바인딩), 침투테스트는 보류 |
| A04 Insecure Design | ✅ 구현·검증완료 (Redis 원자연산) |
| A05 Security Misconfiguration | 🟡 부분 구현 (헤더 2개 미해결) |
| A07 Authentication Failures | 🟡 부분 구현·검증완료 (bcrypt+잠금, MFA/세션쿠키 남음) |
| A09 Logging and Monitoring | ✅ 부분 구현·검증완료 (Suricata) |
| A01, A06, A08, A10 | 부분구현/평가범위밖 |
7. 회원 인증 검증
was-01에 회원가입·로그인·비밀번호 변경 API를 구현하고 실증했다.
- 회원가입 → DB 저장: bcrypt(cost 12) 해시 확인, 평문 없음
- 로그인 실패 잠금: Redis 카운터로 5회 초과 시 423 응답
- 비밀번호 변경: 변경 전/후 해시값이 다름을 DB 재조회로 확인
- 관리자 계정: chage로 90일 만료 정책 적용, /etc/login.defs 기본값도 반영
법적 근거 정정: 「개인정보의 안전성 확보조치 기준」의 비밀번호 주기적 변경 의무 조항은 개정으로 삭제되어 현재 법적 의무가 아님. 현재 법이 요구하는 것은 (1) 비밀번호 일방향 암호화 저장, (2) 인증 실패 시 접근 제한 두 가지이며, 본 프로젝트가 이를 충족함. 90일 정책은 조직 자율 정책으로 문서화.
8. 트러블슈팅 하이라이트
문제원인해결
| mysql_secure_installation not found | 최신 MariaDB에서 명령어 개명 | mariadb-secure-installation 사용 |
| DB 복제 SQL_Running: No | 계정 재생성 이력이 binlog에 남음 | sql_slave_skip_counter로 스킵 |
| Suricata 서비스 실패 | eth0/KiB 등 설정 문법 오류 | ens160/kb로 수정 |
| IDS 공격 트래픽 미탐지 | monitor 서버가 트래픽 경로 밖 | queue-gate로 재배치 |
| 웹페이지 CSS 전체 깨짐 | CSP 헤더가 인라인 스타일 차단 | style-src/font-src 세분화 |
전체 목록은 troubleshooting-full.pdf 참고.
9. 산출물 목록
- ticket-portfolio-full.pdf — 통합 계획+실행 문서 (23p)
- session-report.pdf / as-built.pdf
- loadtest-report.pdf / concurrency-report.pdf
- pentest-report.pdf / webapp-vuln-report.pdf
- auth-verification-report.pdf
- db-replication-log.pdf / suricata-report.pdf
- troubleshooting-full.pdf
- ticket-project-v2.pptx (17장 발표자료)
- ticket-scripts.zip (서버/API/K6 코드)
'클라우드 엔지니어 양성 > 프로젝트' 카테고리의 다른 글
| [클라우드 인프라 엔지니어 양성] 세 번째 미니 프로젝트 회고록 (0) | 2024.05.11 |
|---|---|
| [클라우드 인프라 엔지니어 양성] 두 번째 미니 프로젝트 회고록 (1) | 2024.02.12 |
| [클라우드 인프라 엔지니어 양성] 첫 번째 미니 프로젝트 보완 (0) | 2024.01.19 |
| [클라우드 인프라 엔지니어 양성] 첫 번째 미니 프로젝트 회고록 (2) | 2024.01.10 |