본문으로 건너뛰기
중급22

네트워크 트래픽 가로채서 디버깅하기: Charles, Wireshark, tcpdump

브라우저 개발자도구로 안 보이는 것들이 있다 — 모바일 앱의 API 호출, HTTPS 트래픽의 실제 내용, 앱이 아예 무엇과 통신하는지. 이걸 직접 들여다보는 도구 세 가지를 익힌다.

  • #Charles
  • #Wireshark
  • #tcpdump
  • #네트워크디버깅
  • #프록시

개념

브라우저 개발자도구로 안 되는 것들

지금까지는 웹 브라우저의 개발자도구(Network 탭)로 API 요청을 확인해왔다. 하지만 이 방법이 안 통하는 상황이 있다.

- 네이티브 모바일 앱이 어떤 API를 호출하는지 보고 싶을 때
  (앱에는 개발자도구가 없다)
- HTTPS로 암호화된 트래픽의 실제 내용을 보고 싶을 때
- 우리가 만들지 않은 프로그램(데스크톱 앱 등)이 실제로 어떤
  서버와 통신하는지 확인하고 싶을 때

이럴 때 쓰는 것이 네트워크 트래픽을 가로채는(intercept) 도구다. 레슨 6에서 배운 DNS·포트·방화벽 개념이 "어디로 가는지"를 다뤘다면, 이 레슨의 도구들은 "실제로 무엇이 오갔는지"를 통째로 들여다본다.

Charles — 프록시로 가로채기

Charles(또는 비슷한 도구인 Fiddler, mitmproxy)는 프록시 방식으로 동작한다. 내 컴퓨터나 모바일 기기의 모든 네트워크 요청이 Charles를 거쳐가도록 설정하면, Charles가 그 요청과 응답을 전부 기록해서 보여준다.

[모바일 앱] → [Charles가 가로챔] → [실제 서버]

              요청·응답 내용을 화면에 표시
  • HTTPS 트래픽도 볼 수 있다 — Charles가 자체 인증서를 기기에 설치하게 해서, 암호화된 트래픽도 그 안의 내용을 복호화해 보여준다(모듈 9 레슨 3에서 배운 인증서 개념이 여기서 실제로 쓰인다)
  • 요청을 조작할 수도 있다 — 특정 응답을 일부러 실패시키거나, 응답 내용을 바꿔치기해서(Map Local/Rewrite) "이 API가 에러를 반환하면 화면이 어떻게 되는가"를 강제로 재현할 수 있다. 이건 모듈 5(레슨 9)에서 배운 신뢰 경계 테스트를 실제로 실행하는 방법이다

Wireshark — 패킷 단위로 보기

Wireshark는 Charles보다 훨씬 낮은 수준에서 동작한다. HTTP 요청·응답이라는 상위 개념이 아니라, 레슨 6에서 배운 TCP/IP 패킷 그 자체를 하나하나 캡처해서 보여준다.

Charles: "이 API 요청의 헤더와 본문이 이거다" (애플리케이션 레벨)
Wireshark: "이 패킷이 이 IP에서 저 IP로, 이 포트를 거쳐 이런
           순서로 갔다" (네트워크 레벨)

일반적인 API 디버깅은 Charles 수준으로 충분하지만, "연결 자체가 아예 안 되는" 문제(레슨 6에서 배운 DNS·포트·방화벽 문제)의 진짜 원인을 확인하려면 Wireshark로 패킷이 실제로 오가는지, 어디서 끊기는지까지 봐야 할 때가 있다.

tcpdump — 터미널에서 빠르게

tcpdump는 Wireshark와 같은 걸 캡처하지만, GUI 없이 터미널 명령어 한 줄로 실행한다. 서버(GUI가 없는 리눅스 환경)에서 문제를 확인해야 할 때, 또는 캡처 결과를 파일로 저장해뒀다가 나중에 Wireshark로 열어 분석할 때 쓰인다.

# 특정 포트(443, HTTPS)로 오가는 패킷만 캡처해서 파일로 저장
tcpdump -i eth0 port 443 -w capture.pcap

세 도구의 관계를 정리하면: Charles는 애플리케이션 레벨에서 빠르고 읽기 쉽게, Wireshark/tcpdump는 네트워크 레벨에서 더 깊고 근본적으로 본다. 실무에서는 Charles로 먼저 확인하고, 그걸로도 설명 안 되는 문제일 때만 Wireshark까지 내려간다.

실무에서 왜 필요한가

"모바일 앱에서만 결제가 실패한다"는 버그를 보고받았다고 하자. 개발자도구가 없는 네이티브 앱에서는, Charles로 그 앱의 실제 API 호출을 가로채 보지 않으면 무슨 요청이 나가고 있는지조차 알 수 없다. 이렇게 확인한 내용("iOS 앱이 결제 API에 Content-Type 헤더를 빠뜨리고 보내고 있음")은 "결제가 안 돼요"보다 훨씬 개발자가 바로 고칠 수 있는 결함 리포트가 된다. 이건 모듈 6(레슨 2)에서 배운 좋은 결함 리포트의 실전 버전이다 — 증상이 아니라 원인에 가까운 근거를 제시할 수 있게 된다.

실습 과제

과제 1 — 도구 선택하기 (10분)

다음 세 상황에 각각 Charles·Wireshark·tcpdump 중 가장 적합한 도구를 고르고 이유를 적는다.

  1. 모바일 앱이 로그인 시 어떤 API를 호출하는지, 요청 본문에 뭐가 담기는지 확인하고 싶다
  2. GUI가 없는 리눅스 서버에서, 특정 포트로 트래픽이 실제로 도착 하는지 빠르게 확인하고 싶다
  3. "연결이 3초 뒤에 끊긴다"는 이상한 증상의 정확한 원인을, 패킷 단위로 깊이 파고들어 분석하고 싶다
해설 보기
  1. Charles — 애플리케이션 레벨(API 요청·응답 내용)을 보는 것이 목적이므로, 가장 빠르고 읽기 쉬운 프록시 도구가 적합하다.
  2. tcpdump — GUI가 없는 환경이고, "빠르게 확인"이 목적이므로 터미널 명령어 한 줄이 가장 실용적이다.
  3. Wireshark — "패킷 단위로 깊이" 분석해야 하므로, GUI로 패킷 하나하나를 살펴볼 수 있는 도구가 필요하다. tcpdump로 캡처해 Wireshark로 여는 조합도 흔하다.

과제 2 — 신뢰 경계 테스트 설계하기 (12분)

Charles의 "응답을 강제로 실패시키는" 기능을 이용해, "결제 API가 타임아웃될 때 화면이 어떻게 반응하는지" 테스트하고 싶다. 이 테스트로 확인하고 싶은 화면 동작을 2가지 이상 적는다(힌트: 로딩 상태, 에러 메시지, 중복 결제 방지 등).

자가 체크리스트

  • 브라우저 개발자도구로 확인할 수 없는 상황(네이티브 앱, HTTPS 내용 등)을 설명할 수 있다
  • Charles가 프록시 방식으로 트래픽을 가로채는 원리를 설명할 수 있다
  • Charles로 응답을 강제 조작해 신뢰 경계 테스트에 활용하는 방법을 설명할 수 있다
  • Wireshark/tcpdump가 Charles와 어떤 레벨(패킷 vs 애플리케이션)에서 다르게 동작하는지 설명할 수 있다
  • 상황에 맞게 세 도구 중 적합한 것을 선택할 수 있다

흔한 실수

  • 모든 네트워크 문제에 Wireshark부터 꺼낸다. 대부분의 API 디버깅은 Charles 수준으로 충분하다 — Wireshark는 그걸로 안 풀릴 때 쓰는 더 깊은 도구다.
  • HTTPS라서 못 본다고 포기한다. Charles의 인증서 설치 과정만 거치면 암호화된 트래픽도 내용을 확인할 수 있다.
  • 가로챈 트래픽에서 민감정보(토큰, 개인정보)를 다룰 때 부주의 하다. 캡처 파일이나 스크린샷을 리포트에 첨부할 때는 모듈 7(레슨 2)에서 배운 데이터 마스킹 원칙을 똑같이 적용해야 한다.

참고 자료