Docker 기반 웹 애플리케이션으로 구현된 멀티플레이어 네트워크 패킷 분석 게임
- 프로젝트 개요
- 시스템 아키텍처
- 게임 규칙 (간략)
- 네트워크 통신 계층
- 게임 흐름 구조
- 모듈 설명
- 서버와 클라이언트 정의
- 웹 기반 통신과 패킷 분석
- 설치 및 실행
- Wireshark 사용법
본 프로젝트는 TCP/IP 네트워크 보안을 학습하기 위한 교육용 멀티플레이어 게임입니다. 플레이어들은 Docker 컨테이너 환경에서 웹 브라우저를 통해 게임에 참여하며, Wireshark를 사용하여 실시간 네트워크 패킷을 분석하여 자신을 향한 공격을 탐지합니다.
- Docker 기반 격리 환경: 각 플레이어는 독립된 컨테이너에서 실행
- 웹 기반 인터페이스: Flask + Socket.IO를 사용한 실시간 웹 애플리케이션
- P2P 직접 통신: 공격 패킷은 플레이어 간 직접 전송 (실제 IP 노출)
- 실시간 패킷 분석: Wireshark로 TCP 스트림 분석 및 공격자 IP 식별
- 라운드 기반 난이도 증가: 5라운드에 걸쳐 점진적으로 증가하는 복잡도
┌─────────────────────────────────────────────────────────────────┐
│ Docker Network (172.20.0.0/16) │
│ │
│ ┌──────────────────────────────────────────────────────────┐ │
│ │ 게임 서버 (172.20.0.10:9999) │ │
│ │ ┌────────────────────────────────────────────────────┐ │ │
│ │ │ Flask 웹 서버 (8000) │ │ │
│ │ │ - 웹 GUI 제공 │ │ │
│ │ │ - Socket.IO (실시간 통신) │ │ │
│ │ └────────────────────────────────────────────────────┘ │ │
│ │ ┌────────────────────────────────────────────────────┐ │ │
│ │ │ TCP 게임 서버 (9999) │ │ │
│ │ │ - 클라이언트 연결 관리 │ │ │
│ │ │ - 게임 상태 관리 (GameManager) │ │ │
│ │ │ - 더미/노이즈/가짜공격 생성 │ │ │
│ │ │ - 점수 계산 및 라운드 진행 │ │ │
│ │ └────────────────────────────────────────────────────┘ │ │
│ └──────────────────────────────────────────────────────────┘ │
│ │ │
│ │ (서버-클라이언트 통신) │
│ │ │
│ ┌────────────────┐ ┌────────────────┐ ┌────────────────┐ │
│ │ Player1 │ │ Player2 │ │ Player3 │ │
│ │ (172.20.0.11) │ │ (172.20.0.12) │ │ (172.20.0.13) │ │
│ │ │ │ │ │ │ │
│ │ Flask (5000) │ │ Flask (5000) │ │ Flask (5000) │ │
│ │ - 웹 UI │ │ - 웹 UI │ │ - 웹 UI │ │
│ │ │ │ │ │ │ │
│ │ P2P (10001) │◄─┼►│ P2P (10002) │◄─┼►│ P2P (10003) │ │
│ │ - 공격 수신 │ │ - 공격 수신 │ │ - 공격 수신 │ │
│ └────────────────┘ └────────────────┘ └────────────────┘ │
│ ▲ ▲ ▲ │
│ └─────────────────────┴─────────────────────┘ │
│ P2P 공격 패킷 (직접 통신) │
└─────────────────────────────────────────────────────────────────┘
│
▼
┌──────────────┐
│ Wireshark │
│ 패킷 캡처 및 │
│ 분석 │
└──────────────┘
-
서버-클라이언트 통신 (172.20.0.10:9999)
- 게임 상태, 더미 패킷, 점수 정보 등
- 서버가 중앙 집중식으로 관리
-
P2P 직접 통신 (플레이어 간)
- 실제 공격 패킷만 P2P로 직접 전송
- 공격자의 실제 IP가 패킷에 노출 (학습 목적)
- 컨테이너 실제 IP: 172.20.0.x (네트워크 계층)
- 게임 가상 IP: 172.20.1.x (애플리케이션 계층)
- 서버가 가상 IP를 할당하여 게임 메시지에 사용
- Flask: 웹 페이지 제공
- Socket.IO: 실시간 양방향 통신 (게임 상태 업데이트)
- TCP 소켓: 게임 패킷 송수신
Wireshark로 네트워크 패킷을 분석하여 자신을 공격한 플레이어의 IP를 찾아 방어
- 5라운드 진행 (각 라운드 90초)
- 플레이어는 다른 플레이어에게 공격 패킷 전송 가능 (라운드당 제한 있음)
- 서버는 주기적으로 더미 패킷 전송 (라운드마다 빈도 증가)
- R3부터 노이즈 트래픽 추가, R5에는 가짜 공격 추가
- 라운드 종료 후 방어 페이즈(20초): 공격자 IP 제출
- 점수 계산: 정답(+점수), 오답(-점수), 놓친 공격(-점수, HP 감소)
- R1-R2: 기본 IP 탐지 학습
- R3-R4: 노이즈 트래픽 추가
- R5: 가짜 공격 10개 추가 (최고 난이도)
본 프로젝트의 모든 통신은 TCP/IP 프로토콜을 사용합니다. 통신은 두 가지 계층에서 이루어집니다:
실제 패킷 전송이 이루어지는 계층:
- 프로토콜: TCP
- 포트:
- 게임 서버: 9999
- P2P 공격: 10001, 10002, 10003 ...
- 웹 서버: 8000 (서버), 5000 (클라이언트)
- IP 주소: Docker 컨테이너의 실제 IP (172.20.0.x)
- Wireshark 캡처 대상: 이 계층의 TCP 패킷
특징:
- Wireshark에서 보이는 Source IP / Destination IP는 실제 컨테이너 IP
- TCP 스트림으로 패킷의 출발지와 목적지 확인 가능
- SSL/TLS 없이 평문 JSON 전송 (교육 목적)
게임 로직이 동작하는 계층:
- 프로토콜: 커스텀 JSON 메시지
- 가상 IP: 172.20.1.x (게임 내부에서만 사용)
- 메시지 타입: ATTACK, DUMMY, DEFENSE, SCORE 등
- 페이로드: Base64 인코딩 (Wireshark에서 평문 안 보임)
특징:
- JSON 메시지 내부에
from_ip,to_ip필드로 가상 IP 사용 - 서버가 플레이어에게 가상 IP 할당 (예: Player1 → 172.20.1.1)
- 게임 메시지는 애플리케이션 레벨에서 해석
| 구분 | 네트워크 계층 (TCP) | 애플리케이션 계층 |
|---|---|---|
| 프로토콜 | TCP/IP | 커스텀 JSON |
| IP 주소 | 172.20.0.x (실제) | 172.20.1.x (가상) |
| 패킷 분석 | Wireshark로 캡처 | JSON 파싱 |
| 공격 탐지 방법 | Source IP 확인 | 메시지 내 from_ip 확인 |
| 암호화 | 없음 (평문) | Base64 인코딩 (난독화) |
┌─────────────────────────────────────────────────────────────────┐
│ 게임 시작 │
│ (2명 이상 접속 시) │
└────────────────────────┬────────────────────────────────────────┘
│
▼
┌─────────────────────────────────────────────────────────────────┐
│ 라운드 루프 (R1~R5) │
│ │
│ ┌─────────────────────────────────────────────────────────┐ │
│ │ 1. 라운드 시작 (ROUND_START) │ │
│ │ - 난이도 설정 (더미 간격, 공격 제한 등) │ │
│ │ - 플레이어 상태 초기화 │ │
│ └────────────┬────────────────────────────────────────────┘ │
│ │ │
│ ▼ │
│ ┌─────────────────────────────────────────────────────────┐ │
│ │ 2. 게임 페이즈 (PLAYING) - 90초 │ │
│ │ │ │
│ │ [서버 동작] │ │
│ │ - 더미 패킷 주기적 브로드캐스트 │ │
│ │ - 노이즈 트래픽 생성 (R3+) │ │
│ │ - 가짜 공격 생성 (R5) │ │
│ │ │ │
│ │ [플레이어 동작] │ │
│ │ ① 공격 요청 → 서버 │ │
│ │ ② 서버 승인 → 공격자에게 타겟 정보 제공 │ │
│ │ ③ 공격자 → 타겟에게 P2P 직접 공격 │ │
│ │ ④ 양쪽이 서버에 확인 메시지 전송 │ │
│ │ ⑤ 서버가 실제 공격으로 기록 │ │
│ │ │ │
│ │ [Wireshark] │ │
│ │ - 플레이어가 실시간으로 패킷 캡처 및 분석 │ │
│ │ - 자신을 향한 공격 패킷의 Source IP 기록 │ │
│ └────────────┬────────────────────────────────────────────┘ │
│ │ │
│ ▼ │
│ ┌─────────────────────────────────────────────────────────┐ │
│ │ 3. 방어 페이즈 (DEFENSE_PHASE) - 20초 │ │
│ │ - 플레이어가 공격자 IP 목록 제출 │ │
│ │ - 중복 제출 시 누적 (여러 번 제출 가능) │ │
│ └────────────┬────────────────────────────────────────────┘ │
│ │ │
│ ▼ │
│ ┌─────────────────────────────────────────────────────────┐ │
│ │ 4. 점수 계산 (ROUND_END) │ │
│ │ - 정답: 해당 IP의 공격 중 1개만 방어 (+점수) │ │
│ │ - 오답: 실제 공격하지 않은 IP (-점수) │ │
│ │ - 놓친 공격: 제출하지 않은 IP의 모든 공격 │ │
│ │ (-점수, HP 감소) │ │
│ │ - 플레이어 목록 실시간 업데이트 (Score, HP) │ │
│ └────────────┬────────────────────────────────────────────┘ │
│ │ │
│ ▼ │
│ 다음 라운드 or 게임 종료 │
└───────────────┬───────────────────────────────────────────────┬─┘
│ │
▼ ▼
다음 라운드 진행 ┌────────────────┐
(R1→R2→...→R5) │ 게임 종료 │
│ 최종 점수 집계 │
└────────────────┘
Player1 (공격자) Server Player2 (타겟)
│ │ │
│ ① ATTACK_REQUEST │ │
├────────────────────────────►│ │
│ │ - 공격 가능 여부 검증 │
│ │ - 타겟 IP/포트 조회 │
│ │ - attack_id 생성 │
│ │ │
│ ② ATTACK_APPROVED │ ③ INCOMING_ATTACK_WARNING │
│◄────────────────────────────┤────────────────────────────►│
│ (타겟 IP: 172.20.0.12) │ (공격자 IP: 172.20.1.1) │
│ (타겟 포트: 10002) │ │
│ │ │
│ ④ P2P 직접 연결 및 공격 패킷 전송 │
├────────────────────────────────────────────────────────►│
│ (TCP: 172.20.0.11 → 172.20.0.12:10002) │
│ Wireshark에서 이 패킷의 Source IP를 봐야 함! │
│ │ │
│ ⑤ ATTACK_CONFIRM (SENT) │ │
├────────────────────────────►│ │
│ │ │
│ │ ⑥ ATTACK_CONFIRM (RECEIVED) │
│ │◄────────────────────────────┤
│ │ │
│ │ ⑦ 양쪽 확인 완료 │
│ │ → real_attacks에 기록 │
│ │ → 점수 계산에 반영 │
ComNetProject/
├── common/ # 공통 모듈 (서버/클라이언트 공유)
│ ├── constants.py # 게임 설정 상수
│ ├── message_types.py # JSON 메시지 클래스
│ └── protocol.py # TCP 통신 프로토콜
│
├── server/ # 서버 모듈
│ ├── web_server_gui.py # 웹 서버 메인 (Flask + Socket.IO)
│ ├── game_manager.py # 게임 로직 관리자
│ ├── player_manager.py # 플레이어 정보 관리
│ ├── dummy_generator.py # 더미 패킷 생성기
│ ├── noise_generator.py # 노이즈 트래픽 생성기
│ └── decoy_generator.py # 가짜 공격 생성기 (R5)
│
├── client/ # 클라이언트 모듈
│ ├── web_client.py # 웹 클라이언트 (Flask + Socket.IO)
│ └── templates/ # HTML 템플릿
│ └── client.html
│
├── docs/ # 문서
│ ├── protocol.md # 통신 프로토콜 명세
│ ├── wireshark_guide.md # Wireshark 사용 가이드
│ └── docker_guide.md # Docker 설정 가이드
│
├── Dockerfile # Docker 이미지 빌드 파일
├── docker-compose.yml # 멀티 컨테이너 구성
└── requirements.txt # Python 의존성
서버와 클라이언트가 공유하는 핵심 라이브러리:
-
constants.py
- 역할: 게임 설정 값 관리
- 주요 내용:
- 네트워크 설정 (포트, 버퍼 크기)
- 게임 설정 (라운드 수, 시간 제한, HP)
- 라운드별 난이도 (
DIFFICULTY_BY_ROUND) - 점수 배점 (
SCORE_*)
- 특징: 모든 설정을 한 곳에서 관리하여 일관성 유지
-
message_types.py
- 역할: 네트워크 메시지 구조체 정의
- 주요 클래스:
Message: 기본 메시지 (type, timestamp)AttackMessage: 공격 패킷 (from_ip, to_ip, payload, attack_id)DefenseMessage: 방어 제출 (player_id, attacker_ips)ScoreMessage: 점수 업데이트
- 특징: Base64 인코딩으로 페이로드 난독화
-
protocol.py
- 역할: TCP 메시지 송수신 프로토콜
- 주요 기능:
- 메시지 길이 헤더 추가 (4바이트)
- JSON 직렬화/역직렬화
- 네트워크 바이트 순서 처리
- 특징: 신뢰성 있는 메시지 전송 보장
게임 서버의 핵심 구성 요소:
-
web_server_gui.py (메인 서버)
- 역할: 웹 서버 및 게임 서버 통합
- 구성:
- Flask: 웹 GUI 제공 (포트 8000)
- Socket.IO: 실시간 양방향 통신
- TCP 서버: 게임 패킷 처리 (포트 9999)
- 기능:
- 클라이언트 연결 수락 및 관리
- 게임 시작/중지 제어
- 플레이어 목록 실시간 브로드캐스트
- 서버 로그 웹 UI 출력
-
game_manager.py (게임 로직 관리자)
- 역할: 게임 상태 및 진행 관리
- 주요 기능:
- 게임 상태 관리 (WAITING, PLAYING, DEFENSE_PHASE 등)
- 라운드 진행 및 타이머 관리
- 공격 승인 시스템 (P2P 중개)
- 점수 계산 및 HP 관리
- 난이도 조정 (라운드별)
- 특징:
- 스레드 안전성 보장 (Lock 사용)
- 공격 타임아웃 처리
- 실시간 플레이어 목록 업데이트
-
player_manager.py (플레이어 정보 관리)
- 역할: 플레이어 상태 관리
- 주요 기능:
- 플레이어 추가/제거
- 가상 IP 할당 (172.20.1.x 풀)
- 점수 및 HP 업데이트
- 공격 기록 관리 (attacks_received)
- 특징:
- 연결 순서 기반 인덱스 (P2P 포트 할당용)
- 스레드 안전성 보장
-
dummy_generator.py (더미 패킷 생성기)
- 역할: 주기적으로 더미 패킷 전송
- 특징:
- 라운드별 전송 간격 조정 (R1: 2초 → R5: 0.5초)
- 페이로드: "DUMMY_" + 랜덤 문자열
- 백그라운드 스레드로 동작
-
noise_generator.py (노이즈 트래픽 생성기)
- 역할: 플레이어 간 배경 트래픽 생성 (R3+)
- 특징:
- 랜덤하게 플레이어 쌍 선택
- 페이로드: "NOISE_" + 랜덤 데이터
- 실제 공격처럼 보이지만 게임에 영향 없음
-
decoy_generator.py (가짜 공격 생성기)
- 역할: 서버가 생성한 가짜 공격 (R5 only)
- 특징:
- 10개의 가짜 공격 생성
- 플레이어 IP를 사칭하여 전송
- 제출 시 오답 처리
플레이어 웹 애플리케이션:
-
web_client.py (웹 클라이언트)
- 역할: 플레이어 인터페이스
- 구성:
- Flask: 웹 UI 제공 (포트 5000)
- Socket.IO: 실시간 게임 상태 수신
- TCP 클라이언트: 게임 서버 통신
- P2P 서버: 공격 패킷 수신 (포트 10001+)
- 기능:
- 서버 연결 및 게임 참여
- 공격 요청 및 전송
- 방어 답안 제출
- 게임 상태 실시간 표시
-
templates/client.html (웹 UI)
- HTML, CSS, JavaScript로 구성
- Socket.IO 클라이언트로 실시간 업데이트
역할: 게임의 중앙 관리자 및 중재자
주요 책임:
-
연결 관리
- 플레이어 접속 수락
- 가상 IP 할당 (172.20.1.x)
- 플레이어 목록 관리
-
게임 진행 관리
- 게임 시작/중지 제어
- 라운드 타이머 관리
- 게임 상태 전환 (WAITING → PLAYING → DEFENSE → ROUND_END)
-
공격 중재 (v2.0 핵심)
- 공격 요청 승인/거부
- P2P 연결 정보 제공 (타겟 IP/포트)
- 공격 완료 확인 (양방향)
- 실제 공격 기록 (real_attacks)
-
컨텐츠 생성
- 더미 패킷 브로드캐스트
- 노이즈 트래픽 생성 (R3+)
- 가짜 공격 생성 (R5)
-
점수 계산
- 방어 답안 검증
- 점수 및 HP 업데이트
- 결과 브로드캐스트
통신 포트:
- TCP 9999: 게임 통신
- HTTP 8000: 웹 GUI
특징:
- 단일 인스턴스 (Docker 컨테이너 1개)
- 모든 게임 상태의 신뢰 소스 (Single Source of Truth)
- 플레이어는 직접 공격하지 않고 서버를 통해 승인 받음
역할: 플레이어의 게임 참여 인터페이스
주요 책임:
-
서버 통신
- 서버에 연결 및 인증
- 게임 상태 메시지 수신
- 방어 답안 제출
-
P2P 공격 (v2.0 핵심)
- 공격 요청 전송 (서버에)
- 승인 받은 후 타겟에게 직접 연결
- 공격 패킷 송신 및 확인
-
P2P 방어
- P2P 포트에서 공격 패킷 수신
- 서버에 수신 확인 전송
-
사용자 인터페이스
- 웹 브라우저로 게임 상태 표시
- 공격 및 방어 입력 받음
- Wireshark 연동 (사용자가 직접)
통신 포트:
- TCP 9999: 서버 통신
- HTTP 5000: 웹 UI
- TCP 10001+: P2P 공격 수신
특징:
- 다중 인스턴스 (Docker 컨테이너 N개, 2-4개)
- 각 플레이어는 독립된 컨테이너
- 웹 브라우저로 접근 (localhost:8081, 8082, 8083...)
| 기능 | 서버 역할 | 클라이언트 역할 |
|---|---|---|
| 연결 | 수락 및 가상 IP 할당 | 연결 요청 |
| 게임 진행 | 타이머 및 상태 관리 | 상태 수신 및 표시 |
| 더미/노이즈 | 생성 및 전송 | 수신 (무시) |
| 공격 | 승인 및 중재 | 요청 → P2P 직접 전송 |
| 방어 | 답안 검증 및 점수 계산 | IP 제출 |
| 패킷 분석 | (없음) | Wireshark로 분석 |
본 프로젝트는 Flask 웹 프레임워크를 사용하지만, 게임 패킷 통신은 일반 TCP 소켓으로 이루어집니다.
-
웹 인터페이스 (Flask + Socket.IO)
- 역할: 사용자 UI 제공 및 실시간 상태 업데이트
- 프로토콜: HTTP/WebSocket
- 포트: 8000 (서버), 5000 (클라이언트)
- 특징: 브라우저에서 접근 가능
-
게임 패킷 통신 (Python Socket)
- 역할: 게임 메시지 및 공격 패킷 전송
- 프로토콜: TCP (평문)
- 포트: 9999 (서버), 10001+ (P2P)
- 특징: Wireshark로 캡처 가능
A: 아니오. 본 프로젝트는 SSL/TLS를 사용하지 않습니다.
이유:
- 교육 목적: Wireshark로 패킷을 분석해야 하므로 평문 통신 필요
- 로컬 네트워크: Docker 내부 네트워크로 외부 노출 없음
- Flask 개발 서버: 프로덕션 환경 아님 (학습용)
| 구분 | 웹 인터페이스 | 게임 패킷 |
|---|---|---|
| 프로토콜 | HTTP / WebSocket | TCP (평문) |
| 암호화 | 없음 (HTTP) | 없음 |
| 용도 | UI 제공, 실시간 업데이트 | 게임 메시지 전송 |
| Wireshark 캡처 | 가능 (분석 불필요) | 가능 (분석 필수) |
| SSL/TLS 영향 | 없음 | 없음 |
결론: SSL/TLS가 없으므로 Wireshark로 모든 패킷을 평문으로 볼 수 있습니다.
- ✅ TCP 스트림의 Source IP / Destination IP 확인 가능
- ✅ JSON 메시지의 type 필드 확인 가능
- ✅ Base64 인코딩된 페이로드는 수동으로 디코딩 가능 (선택 사항)
만약 SSL/TLS를 사용했다면:
- ❌ Wireshark에서 암호화된 데이터만 보임
- ❌ Source IP는 보이지만 메시지 내용 분석 불가
- ❌ 교육 목적 달성 불가
Wireshark에서 캡처한 패킷은 다음과 같이 보입니다:
Frame 42: 120 bytes on wire
Ethernet II, Src: 02:42:ac:14:00:0b, Dst: 02:42:ac:14:00:0c
Internet Protocol, Src: 172.20.0.11, Dst: 172.20.0.12
Transmission Control Protocol, Src Port: 45678, Dst Port: 10002
Data (JSON 평문):
{
"type": "ATTACK",
"timestamp": 1730000000.123,
"from_ip": "172.20.1.1",
"to_ip": "172.20.1.2",
"from_player": "Player1",
"to_player": "Player2",
"payload": "QVRUQUNLX1RBUkdFVF9QbGF5ZXIy",
"attack_id": "Player1→Player2_1730000000_1"
}
분석 포인트:
- IP 계층: Src IP = 172.20.0.11 (공격자의 실제 IP) ← 이것을 기록!
- JSON 메시지: type = "ATTACK" (공격 패킷 확인)
- 페이로드: Base64 디코딩 → "ATTACK_TARGET_Player2"
- 운영체제: Windows 10/11, macOS, Linux
- Docker: Docker Engine 20.10 이상
- Docker Compose: v2.0 이상
- Wireshark: 3.0 이상
- 웹 브라우저: Chrome, Firefox, Edge 등
# Git Clone
git clone https://github.com/Hyunwoo2267/ComNetProject.git
cd ComNetProject- Docker Desktop for Windows 다운로드
- 설치 후 재부팅
- Docker Desktop 실행 확인
brew install --cask docker# Ubuntu/Debian
curl -fsSL https://get.docker.com -o get-docker.sh
sudo sh get-docker.sh
sudo usermod -aG docker $USERDocker 설치 확인:
docker --version
docker-compose --version- Wireshark 다운로드
- 설치 시 "Npcap" 옵션 선택 (필수)
brew install --cask wiresharksudo apt install wireshark
sudo usermod -aG wireshark $USER# 전체 시스템 빌드 및 시작
docker-compose up -d --build
# 실행 확인
docker ps예상 출력:
CONTAINER ID IMAGE PORTS NAMES
abc123 comnetproject-server 0.0.0.0:8000->8000/tcp game_server
def456 comnetproject-player1 0.0.0.0:8081->5000/tcp game_player1
ghi789 comnetproject-player2 0.0.0.0:8082->5000/tcp game_player2
jkl012 comnetproject-player3 0.0.0.0:8083->5000/tcp game_player3
서버 관리 페이지 (게임 시작/중지):
http://localhost:8000
플레이어 클라이언트:
- Player1:
http://localhost:8081 - Player2:
http://localhost:8082 - Player3:
http://localhost:8083
- 각 플레이어가 웹 브라우저로 자신의 URL 접속
- "서버에 연결" 버튼 클릭
- 최소 2명 접속 시 게임 자동 시작
- Wireshark에서 패킷 캡처 시작 (아래 참조)
# Windows
# 시작 메뉴에서 "Wireshark" 실행
# macOS/Linux
sudo wireshark-
Wireshark 시작 화면에서 네트워크 인터페이스 선택:
- Windows: "Ethernet" 또는 "Wi-Fi"
- macOS: "en0" (Wi-Fi) 또는 "en1" (Ethernet)
- Linux: "eth0" 또는 "docker0"
-
Docker 네트워크 캡처 (권장):
- Linux: "docker0" 인터페이스 선택
- Windows/macOS: "Loopback" 또는 "lo0" 선택
옵션 1: 게임 포트만 캡처 (권장)
tcp port 9999 or tcp portrange 10001-10010
옵션 2: 게임 서버 IP 캡처
host 172.20.0.10
옵션 3: 모든 Docker 트래픽
net 172.20.0.0/16
- 인터페이스 선택 후 파란색 상어 지느러미 버튼 클릭
- 패킷이 캡처되기 시작함
# 모든 컨테이너 정지 및 제거
docker-compose down
# 이미지도 함께 제거
docker-compose down --rmi all
# 볼륨도 함께 제거
docker-compose down -v# 서버 로그 실시간 확인
docker logs -f game_server
# 특정 플레이어 로그
docker logs -f game_player1
# 모든 로그 확인
docker-compose logs -f게임 트래픽만 표시:
tcp.port == 9999 or tcp.port >= 10001
특정 플레이어가 보낸 패킷:
ip.src == 172.20.0.11
특정 플레이어가 받은 패킷:
ip.dst == 172.20.0.12
공격 패킷만 보기 (P2P 포트):
tcp.port >= 10001 and tcp.port <= 10010
더미 패킷 제외:
ip.src != 172.20.0.10
공격자를 찾는 가장 중요한 정보:
- 패킷 선택
- 중간 패널에서 Internet Protocol 확장
- Source Address 확인
- 이 IP가 공격자!
예시:
Source: 172.20.0.11 ← Player1이 보낸 패킷
Destination: 172.20.0.12 ← Player2가 받는 패킷
하나의 연결에서 주고받은 모든 패킷 보기:
- 패킷 우클릭
- Follow → TCP Stream
- 전체 대화 내용 확인 (JSON 메시지)
IP별 통신량 확인:
- 메뉴: Statistics → Conversations
- IPv4 탭 선택
- "Address A" 열 정렬 → 누가 얼마나 많이 보냈는지 확인
시간대별 패킷 분석:
- 메뉴: Statistics → IO Graph
- Y축: 패킷 수
- X축: 시간
공식:
- Source IP가 다른 플레이어 컨테이너 IP (172.20.0.11~13) → 공격 가능성
- Source IP가 서버 IP (172.20.0.10) → 더미 또는 노이즈
절차:
- Wireshark 필터:
ip.dst == [내 IP] - Source IP 목록 작성
- 서버 IP(172.20.0.10) 제외
- 남은 IP를 방어 답안으로 제출
- Destination Port가 10001~10003 → P2P 공격 패킷
- Destination Port가 9999 → 서버 통신 (더미 등)
Base64 페이로드 디코딩:
Python:
import base64
payload = "QVRUQUNLX1RBUkdFVF9QbGF5ZXIy"
decoded = base64.b64decode(payload).decode('utf-8')
print(decoded) # "ATTACK_TARGET_Player2"Linux/macOS:
echo "QVRUQUNLX1RBUkdFVF9QbGF5ZXIy" | base64 -dWindows PowerShell:
[Text.Encoding]::UTF8.GetString([Convert]::FromBase64String("QVRUQUNLX1RBUkdFVF9QbGF5ZXIy"))문제: 서버가 생성한 가짜 공격 10개가 섞여 있음
전략:
- 타이밍 분석: 같은 IP에서 연속으로 빠르게 오는 패킷은 의심
- 패턴 분석: 실제 플레이어는 수동으로 공격 (불규칙), 서버는 자동 생성 (규칙적)
- 확률 활용: 의심스러운 IP는 제출하지 않기 (오답 -10점 손해)
컨테이너가 시작되지 않음:
# 로그 확인
docker-compose logs
# 재시작
docker-compose restart포트 충돌 (이미 사용 중):
# docker-compose.yml 수정
ports:
- "8000:8000" # 8000을 다른 포트로 변경클라이언트가 서버에 연결 안 됨:
# 서버 컨테이너 IP 확인
docker inspect game_server | grep IPAddress
# 네트워크 확인
docker network inspect comnetproject_game_network패킷이 캡처되지 않음:
- 올바른 인터페이스 선택 확인
- Docker 네트워크 인터페이스 선택 (docker0, lo0 등)
- 관리자 권한으로 실행
패킷이 너무 많음:
- 필터 사용:
tcp.port == 9999 - 다른 프로그램의 네트워크 사용 중지
본 프로젝트는 교육 목적으로 제작되었습니다.