1. 패킷캡쳐하는 docker 생성 (실습내용) [5점]

1. 작업 디렉토리 및 Dockerfile 생성

  • Dockerfile 내용

2. 이미지 빌드

docker build -f Dockerfile . -t pcap-test

  • 현재 디렉토리에 있는 pcap-test라는 이름으로 새 Docker 이미지를 빌드한다.

3. 컨테이너 실행 및 실행 상태 확인

docker run --name pcap-test pcap-test

.

.

.

  • 컨테이너 이름을 pcap-test로 지정하고 pcap-test 이름의 이미지를 실행한다. 이때 Dockerfile에서 지정한 CMD인 엔트리포인트 스크립트가 실행되고, tcpdump가 시작되어 패킷을 캡쳐한다. curl이 구글 서버 응답 본문을 그대로 화면에 표시하도록 했다.

docker cp pcap-test:/app/out.pcap ./out.pcap

  • 컨테이너 내부에서 만든 패킷 캡쳐 파일을 내(호스트)가 볼 수 있게 현재 터미널이 위치한 디렉토리로 복사한다.

2 . 패킷캡쳐 진행 + 패킷캡쳐한 내용 자세히 분석 [5점]

컨테이너 실행 시 패킷캡쳐가 자동 진행된다. 실습에서 진행하여 만든 out.pcap 파일을 분석한다.

편의상 next sequence number와 ACK는 모두 relative number 기준으로 분석한다.

1) TCP 3-way handshake 찾기

2) 목적지 포트/ 내 포트가 ooo 포트

3) 내 IP는 무엇이고 서버 IP는 무엇?

전체 패킷캡쳐 내용

out.pcap를 wireshark로 연 결과

  • TCP 3-way handshake란 1) 클라이언트가 서버에 연결을 요청하고(SYN), 2) 서버가 응답하며 연결을 수락하고(SYN+ACK), 3) 이것을 클라이언트가 최종 확인하는 과정을 뜻한다(ACK). 이 3단계가 완료되면 TCP 연결이 성립되어 이후 HTTP와 같은 상위 계층 데이터를 전송할 수 있게 된다.
  • 172.17.0.2:60738(내 IP:포트) → 142.250.71.228:80(서버 IP:포트)

첫 번째 패킷

  • 사진상 첫 번째 패킷으로, 클라이언트가 구글 서버에 TCP 연결을 시도하고 있다.
  • TCP 헤더를 보면 TCP Flags가 SYN(0x002)으로 설정되어있는 것을 볼 수 있다. 아직 상대에게 받은 패킷이 없으므로 Acknowledgement number가 0이다.
  • 142.250.71.228:80(서버 IP:포트) → 172.17.0.2:60738(내 IP:포트)

두 번째 패킷

  • 사진상 두 번째 패킷으로, 클라이언트의 연결 요청을 수락했음을 나타낸다.
  • TCP 헤더를 보면 TCP Flags가 SYN, ACK(0x012)으로 설정되어있는 것을 볼 수 있다. 클라이언트가 보낸 SYN값(0)을 잘 받아 Acknowledgement number가 1이 되었다.
  • 172.17.0.2:60738(내 IP:포트) → 142.250.71.228:80(서버 IP:포트)

세 번째 패킷

  • 사진상 세 번째 패킷으로, 클라이언트가 서버의 응답을 확인하여 3-way handshake가 완료된다.
  • TCP 헤더를 보면 TCP Flags가 ACK(0x010)으로 설정되어있는 것을 볼 수 있다.

4) HTTP/1.1 200은 무엇?

  • TCP 3-way handshake가 끝나면 이제 애플리케이션 데이터가 오간다.

4번째 패킷

  • HTTP/1.1 200은 프로토콜 HTTP를 쓰고 버전은 1.1을 사용하며 요청이 성공적으로 처리되었고, 응답 본문이 메시지 body에 들어있다는 뜻이다. 4번 패킷을 보면 이렇게 GET 요청을 하여 서버에 리소스를 요청한다.
  • 헤더로 Host: www.google.com이 들어가 있음을 확인할 수 있다.
  • Dockerfile에 작성한 것처럼 User-Agent에서 curl명령어로 요청했음을 다시 확인할 수 있다.
  • Accept 필드의 /는 모든 응답을 허용하겠다는 의미이다.
  • GET 요청은 보통 본문이 없으므로 여기서 요청이 끝난다.

  • TCP 헤더에서, segment len은 78이다.

5~9번째 패킷

  • HTTP 응답(200 OK, HTML 페이지 데이터)을 서버가 여러 번 나눠서 전송하고, 클라이언트가 그걸 잘 받았다고 ACK으로 응답하는 과정이다. TCP 레벨에서는 데이터 송수신 + 확인(ACK)이 일어나고 HTTP 레벨에서는 Google 홈페이지 본문이 전송되고 있는 중이다. 한 번에 전부 보낼 수 없어 여러 개로 분할된 패킷이 수신된다.

5번 패킷 (서버 → 클라이언트, ACK)

  • 142.250.71.228:80 (서버) → 172.17.0.2:60738 (클라이언트)
  • Flags: ACK (0x010)
  • 의미: 서버가 클라이언트의 HTTP 요청(GET / HTTP/1.1)을 잘 받았다는 확인 응답
  • 5번 패킷의 ACK는 79이다. 4번 패킷의 TCP 헤더에 있던 segment len의 78과 관련있다. 클라이언트가 보낸 HTTP요청 1~78바이트를 다 잘 받았다는 뜻이다.

6번 패킷 (서버 → 클라이언트, PSH + ACK)

  • 142.250.71.228:80 (서버) → 172.17.0.2:60738 (클라이언트)
  • Flags: PSH, ACK (0x018)
  • TCP 헤더의 segment len : 9838 bytes
  • 의미: 서버가 HTTP 응답(웹페이지 데이터) 일부를 전송. PSH 플래그는 데이터를 바로 애플리케이션에 전달하라는 의미.
  • 6번 패킷의 ACK는 79이다. 서버는 클라이언트가 보낸 HTTP요청이 78바이트밖에 없다는 것을 알고 있고, 4번 패킷 이후 추가 데이터를 전송하지 않았으므로(ACK은 여기서 전송하는 데이터로 간주하지 않음) ACK이 유지된다. next sequence number는 1+9838=9839.

**Next Sequence Number = Current Sequence Number + TCP Segment Len

7번 패킷 (클라이언트 → 서버, ACK)

  • 172.17.0.2:60738 (클라이언트) → 142.250.71.228:80 (서버)
  • Flags: ACK (0x010)
  • 의미: 클라이언트가 서버가 보낸 데이터를 잘 받았다고 확인 응답
  • 7번 패킷의 ACK은 9839이다. 클라이언트가 서버가 보낸 9838바이트를 잘 받았다는 뜻이다. next sequence number는 0+79=79.

8번 패킷 (서버 → 클라이언트, PSH + ACK)

  • 142.250.71.228:80 (서버) → 172.17.0.2:60738 (클라이언트)
  • Flags: PSH, ACK (0x018)
  • TCP 헤더의 segment len: 1400 bytes
  • 의미: 서버가 1~9838을 보냈으니 이제 9839부터 1400바이트를 더 보낸다.
  • 8번 패킷의 ACK는 79이다. 서버는 클라이언트가 보낸 HTTP요청이 78바이트밖에 없다는 것을 알고 있고, 4번 패킷 이후 추가 데이터를 전송하지 않았으므로(ACK은 여기서 전송하는 데이터로 간주하지 않음) ACK이 유지된다. next sequence number는 1400+9839=11239.

9번 패킷 (클라이언트 → 서버, ACK)

  • 172.17.0.2:60738 (클라이언트) → 142.250.71.228:80 (서버)
  • Flags: ACK (0x010)
  • 의미: 클라이언트가 추가로 받은 1400바이트 데이터도 잘 받았다는 확인 응답
  • 9번 패킷의 ACK는 11239이다. next sequence number는 0+79=79.

10번 패킷

  • 142.250.71.228:80 (서버) → 172.17.0.2:60738 (클라이언트)
  • Flags: 0x018 (PSH, ACK)
  • 의미: 서버가 이전에 보낸 데이터들(6,8번 패킷)과 모아 전체 HTTP 응답(200 OK + HTML 본문)을 완성했다.

Leave a comment