핵심 진단 도구
ping·traceroute·dig·ss·curl의 출력과 한계를 이해하고 연결·경로·DNS·포트·HTTP 문제를 계층별로 확인합니다.
트러블슈팅 방법론을 세웠으면, 실제로 계층별 진단을 수행할 도구가 필요합니다.
이 절에서는 네트워크 진단의 핵심 도구를 다룹니다.
ping — 연결 가능성 확인
ping은 ICMP Echo Request를 보내고 Echo Reply를 받는 가장 기본적인 진단 도구입니다.
ping google.com
# 결과 예시
PING google.com (142.250.196.110): 56 data bytes
64 bytes from 142.250.196.110: icmp_seq=0 ttl=116 time=3.2 ms
64 bytes from 142.250.196.110: icmp_seq=1 ttl=116 time=2.8 ms항목 관측하는 것 해석 조건
──────────────────────────────────────────────────────
응답 여부 이 ICMP 요청의 응답 여부 다른 프로토콜은 별도 확인
time (RTT) 이 요청·응답의 왕복 시간 거리·경로·부하별 기준과 비교
ttl 응답 패킷의 도착 TTL 시작 TTL을 알아야 홉 수 추정
초기값은 구현·설정별 차이 숫자만으로 OS 단정 불가
패킷 유실 보낸 탐침 중 응답 미수신 비율 ICMP 제한·손실·캡처 시점 구분ping이 안 되더라도 반드시 서버가 죽은 것은 아닙니다.
많은 서버가 보안상 ICMP를 차단합니다.
새로 만든 사용자 정의 보안 그룹은 인바운드 허용 규칙이 없지만, 기본 보안 그룹은 같은 그룹이 연결된 자원에서 오는 트래픽을 허용합니다. 따라서 AWS에서 ICMP가 항상 기본 차단된다고 단정할 수 없습니다.
traceroute / tracert — 경로 추적
traceroute google.com
# 결과 예시
1 192.168.1.1 (192.168.1.1) 1.2 ms 1.0 ms 1.1 ms ← 공유기
2 10.0.0.1 (10.0.0.1) 5.3 ms 4.8 ms 5.1 ms ← ISP 라우터
3 72.14.215.85 (72.14.215.85) 8.1 ms 7.9 ms 8.3 ms ← 백본
4 * * * ← 탐침 응답 미수신
5 142.250.196.110 12.5 ms 12.3 ms 12.1 ms ← 목적지TTL 값을 1부터 하나씩 증가시키며 패킷을 보냅니다.
TTL이 소진되면 라우터가 ICMP Time Exceeded를 보낼 수 있습니다. 필터링·응답 제한·반환 경로 때문에 이 응답을 받지 못할 수도 있습니다. 운영체제와 옵션에 따라 UDP·ICMP·TCP 탐침을 구분해야 합니다.
패턴 추가로 확인할 것
──────────────────────────────────────────────
* * * 탐침 무응답: 차단·제한·손실·반환 경로
홉 N에서 RTT 증가 후속 홉에도 지속되는지, 같은 경로 기준값
마지막 홉만 * * * 목적지의 탐침 처리와 실제 서비스 응답
중간부터 전부 * * * 경로·필터·목적지 상태, 다른 탐침 방식mtr은 반복 탐침으로 홉별 응답 미수신율과 RTT 통계를 보여줍니다. 중간 라우터의 응답 제한을 종단 간 전송 손실로 단정하지 말고 후속 홉도 비교합니다. 기본 RTT 표준편차와 특정 정의의 지터 지표도 구분해야 합니다.
nslookup / dig — DNS 진단
# 기본 조회
nslookup example.com
# Server: 8.8.8.8
# Address: 93.184.216.34
# dig로 상세 조회
dig example.com +short # 짧은 응답(CNAME 등이 포함될 수 있음)
dig example.com MX +short # 메일 서버 확인
dig example.com +trace # 이 실행의 루트부터 반복 질의 경로
dig @8.8.8.8 example.com # 특정 DNS 서버로 질의
# DNS 문제 구분
ping 8.8.8.8 # 성공이면 이 ICMP 대상의 응답을 확인
nslookup google.com # 실패이면 응답 코드·DNS 서버·질의 경로 확인
# /etc/resolv.conf는 확인할 설정 중 하나위 주소·출력은 설명용 예시이며 현재 DNS 결과를 보장하지 않습니다. dig +trace는 이 실행이 반복 질의한 경로로, 운영체제나 재귀 DNS 서버의 캐시 처리 전체를 재현하는 명령은 아닙니다.
netstat / ss — 연결 상태 확인
# 리슨 중인 TCP 포트 확인
ss -tlnp
# 결과 예시
State Local Address:Port Process
LISTEN 0.0.0.0:80 nginx
LISTEN 0.0.0.0:443 nginx
LISTEN 127.0.0.1:3000 node ← localhost만 바인딩!
LISTEN 0.0.0.0:5432 postgres
# 활성 연결 확인
ss -tnp
# 연결 상태 요약
ss -s
# TCP: 152 (estab 43, closed 12, timewait 89)
# → TIME_WAIT 수는 연결 생성률·포트 여유·평소 값과 함께 판단
# 특정 포트 연결 수 확인
ss -Htn state established '( sport = :80 or dport = :80 )' | wc -l127.0.0.1:3000은 같은 네트워크 네임스페이스의 loopback 접점입니다. 원격 호스트가 직접 연결할 수는 없지만 로컬 리버스 프록시가 중계할 수 있습니다. 직접 접근을 받으려면 해당 인터페이스 주소나 0.0.0.0에 바인딩하고 라우트·방화벽도 허용해야 합니다.
마지막 명령은 TCP ESTABLISHED 중 로컬 또는 상대 포트가 정확히 80인 행을 헤더 없이 셉니다. 단순 grep :80은 8080 같은 포트까지 섞을 수 있습니다.
curl — HTTP 레벨 디버깅
# 1. 상세 모드 — 전체 과정 표시
curl -v https://example.com
# * Trying 93.184.216.34:443...
# * Connected to example.com port 443
# * TLS 1.3 handshake
# > GET / HTTP/2
# < HTTP/2 200
# 2. 응답 시간 분석
curl -o /dev/null -s -w "\
DNS: %{time_namelookup}s\n\
TCP: %{time_connect}s\n\
TLS: %{time_appconnect}s\n\
첫바이트: %{time_starttransfer}s\n\
총시간: %{time_total}s\n\
상태코드: %{http_code}\n" https://example.com
# 3. DNS 우회 (IP 직접 지정)
curl --resolve example.com:443:1.2.3.4 https://example.com
# 4. 헤더만 확인
curl -I https://example.com
# 5. 리다이렉트 추적
curl -L -v https://example.com-w 옵션의 시간 분석은 특히 유용합니다.
각 시간은 전송 시작부터 해당 지점까지의 누적값입니다. 따라서 TCP·TLS 항목 자체를 해당 단계만의 소요 시간으로 읽으면 안 됩니다.
curl 시간 필드가 가리키는 완료 지점
시작부터 DNS 완료까지의 누적값을 읽습니다. 전송 완료값에서 첫 바이트 완료값을 뺍니다. 각 단계의 값과 전환 이유를 비교합니다.
curl · 누적 시간 해석
time_connect는 TCP 단계 시간 자체가 아닙니다
각 필드는 전송 시작부터 완료 지점까지의 누적 초입니다. 인접 값의 차이는 새 단일 HTTPS/TCP 연결·리다이렉트 없음의 단순 조건에서 해석하며, 첫 바이트는 서버 처리만의 시간이 아닙니다.
| 지점 | 누적 시간 필드 | 인접 지점과의 차이 |
|---|---|---|
| 이름 해석 | time_namelookup | 시작 → 이름 해석 완료 |
| TCP 연결 | time_connect | time_connect − time_namelookup |
| TLS 협상 | time_appconnect | time_appconnect − time_connect |
| 첫 바이트 | time_starttransfer | time_starttransfer − time_appconnect: 요청 전송·서버 대기·첫 응답 경로 등을 포함 |
| 전송 완료 | time_total | time_total − time_starttransfer: 첫 바이트 이후 완료까지 |
- 이름 해석
- 누적 시간 필드:
time_namelookup인접 지점과의 차이: 시작 → 이름 해석 완료 - TCP 연결
- 누적 시간 필드:
time_connect인접 지점과의 차이: time_connect − time_namelookup - TLS 협상
- 누적 시간 필드:
time_appconnect인접 지점과의 차이: time_appconnect − time_connect - 첫 바이트
- 누적 시간 필드:
time_starttransfer인접 지점과의 차이: time_starttransfer − time_appconnect: 요청 전송·서버 대기·첫 응답 경로 등을 포함 - 전송 완료
- 누적 시간 필드:
time_total인접 지점과의 차이: time_total − time_starttransfer: 첫 바이트 이후 완료까지
프록시·연결 재사용·QUIC·재시도에서는 추가 해석이 필요합니다. 정상 시간을 고정 숫자로 단정하지 말고 같은 조건의 기준값과 오류·HTTP 버전을 함께 비교합니다.
이 예의 조건
- 본문과 전체 도표의 예를 따라 DNS 완료부터 전송 완료까지 진행합니다.
관계도의 보충 설명
| 구분 | 전체 도표의 내용 |
|---|---|
| 관계 설명 | 여섯 지점 노드와 다섯 시간 진행 간선입니다. 누적 0, .02, .08, .20, .35, .50초를 지점에 쓰고 추가 구간 .02, .06, .12, .15, .15초를 간선 옆에 적었습니다. 노드 간격은 순서를 위한 배치이며 시간 길이에 비례하지 않습니다. 새 단일 HTTPS/TCP 연결과 리다이렉트 없음을 가정하며 프록시/재사용/QUIC/재시도는 별도입니다. 첫 바이트 구간은 서버 처리 시간만으로 구성되지 않습니다. 같은 누적값과 차분이 모바일에 유지됩니다. |
| 표의 값 | 이름 해석 — 누적 시간 필드: time_namelookup; 인접 지점과의 차이: 시작 → 이름 해석 완료. TCP 연결 — 누적 시간 필드: time_connect; 인접 지점과의 차이: time_connect − time_namelookup. TLS 협상 — 누적 시간 필드: time_appconnect; 인접 지점과의 차이: time_appconnect − time_connect. 첫 바이트 — 누적 시간 필드: time_starttransfer; 인접 지점과의 차이: time_starttransfer − time_appconnect: 요청 전송·서버 대기·첫 응답 경로 등을 포함. 전송 완료 — 누적 시간 필드: time_total; 인접 지점과의 차이: time_total − time_starttransfer: 첫 바이트 이후 완료까지. |
| 관찰·상황 | 값·보충 정보 | 변화·이유 |
|---|---|---|
| DNS 완료 시작부터 DNS 완료까지의 누적값을 읽습니다. |
|
|
| TCP 완료 TCP 완료값에서 DNS 완료값을 뺍니다. |
|
|
| TLS 완료 TLS 완료값에서 TCP 완료값을 뺍니다. |
|
|
| 첫 바이트 요청·대기·첫 응답 경로의 누적값을 읽습니다. |
|
|
| 전송 완료 전송 완료값에서 첫 바이트 완료값을 뺍니다. |
|
|
curl 시간 필드가 가리키는 완료 지점
시작부터 DNS 완료까지의 누적값을 읽습니다. 전송 완료값에서 첫 바이트 완료값을 뺍니다. 각 단계의 값과 전환 이유를 비교합니다.
curl · 누적 시간 해석
time_connect는 TCP 단계 시간 자체가 아닙니다
각 필드는 전송 시작부터 완료 지점까지의 누적 초입니다. 인접 값의 차이는 새 단일 HTTPS/TCP 연결·리다이렉트 없음의 단순 조건에서 해석하며, 첫 바이트는 서버 처리만의 시간이 아닙니다.
| 지점 | 누적 시간 필드 | 인접 지점과의 차이 |
|---|---|---|
| 이름 해석 | time_namelookup | 시작 → 이름 해석 완료 |
| TCP 연결 | time_connect | time_connect − time_namelookup |
| TLS 협상 | time_appconnect | time_appconnect − time_connect |
| 첫 바이트 | time_starttransfer | time_starttransfer − time_appconnect: 요청 전송·서버 대기·첫 응답 경로 등을 포함 |
| 전송 완료 | time_total | time_total − time_starttransfer: 첫 바이트 이후 완료까지 |
- 이름 해석
- 누적 시간 필드:
time_namelookup인접 지점과의 차이: 시작 → 이름 해석 완료 - TCP 연결
- 누적 시간 필드:
time_connect인접 지점과의 차이: time_connect − time_namelookup - TLS 협상
- 누적 시간 필드:
time_appconnect인접 지점과의 차이: time_appconnect − time_connect - 첫 바이트
- 누적 시간 필드:
time_starttransfer인접 지점과의 차이: time_starttransfer − time_appconnect: 요청 전송·서버 대기·첫 응답 경로 등을 포함 - 전송 완료
- 누적 시간 필드:
time_total인접 지점과의 차이: time_total − time_starttransfer: 첫 바이트 이후 완료까지
프록시·연결 재사용·QUIC·재시도에서는 추가 해석이 필요합니다. 정상 시간을 고정 숫자로 단정하지 말고 같은 조건의 기준값과 오류·HTTP 버전을 함께 비교합니다.
이 예의 조건
- 본문과 전체 도표의 예를 따라 DNS 완료부터 전송 완료까지 진행합니다.
관계도의 보충 설명
| 구분 | 전체 도표의 내용 |
|---|---|
| 관계 설명 | 여섯 지점 노드와 다섯 시간 진행 간선입니다. 누적 0, .02, .08, .20, .35, .50초를 지점에 쓰고 추가 구간 .02, .06, .12, .15, .15초를 간선 옆에 적었습니다. 노드 간격은 순서를 위한 배치이며 시간 길이에 비례하지 않습니다. 새 단일 HTTPS/TCP 연결과 리다이렉트 없음을 가정하며 프록시/재사용/QUIC/재시도는 별도입니다. 첫 바이트 구간은 서버 처리 시간만으로 구성되지 않습니다. 같은 누적값과 차분이 모바일에 유지됩니다. |
| 표의 값 | 이름 해석 — 누적 시간 필드: time_namelookup; 인접 지점과의 차이: 시작 → 이름 해석 완료. TCP 연결 — 누적 시간 필드: time_connect; 인접 지점과의 차이: time_connect − time_namelookup. TLS 협상 — 누적 시간 필드: time_appconnect; 인접 지점과의 차이: time_appconnect − time_connect. 첫 바이트 — 누적 시간 필드: time_starttransfer; 인접 지점과의 차이: time_starttransfer − time_appconnect: 요청 전송·서버 대기·첫 응답 경로 등을 포함. 전송 완료 — 누적 시간 필드: time_total; 인접 지점과의 차이: time_total − time_starttransfer: 첫 바이트 이후 완료까지. |
| 관찰·상황 | 값·보충 정보 | 변화·이유 |
|---|---|---|
| DNS 완료 시작부터 DNS 완료까지의 누적값을 읽습니다. |
|
|
| TCP 완료 TCP 완료값에서 DNS 완료값을 뺍니다. |
|
|
| TLS 완료 TLS 완료값에서 TCP 완료값을 뺍니다. |
|
|
| 첫 바이트 요청·대기·첫 응답 경로의 누적값을 읽습니다. |
|
|
| 전송 완료 전송 완료값에서 첫 바이트 완료값을 뺍니다. |
|
|
차이를 단계 시간으로 해석하는 것은 새 단일 HTTPS/TCP 연결·리다이렉트 없음이라는 단순 조건을 기준으로 합니다. 프록시, 연결 재사용, QUIC, 재시도에는 추가 해석이 필요합니다. 첫 바이트 시간에는 DNS·연결·요청 전송·서버 처리·응답 경로가 함께 포함되므로 서버 처리 시간만의 계측이 아닙니다.
예시 위 단순 조건에서 누적 DNS 0.02초, 연결 0.08초, TLS 0.20초, 첫 바이트 0.35초, 전체 0.50초라고 합시다. DNS는 20ms이고 연결의 추가 구간은 (0.08−0.02)×1000=60ms, TLS 추가 구간은 120ms입니다. TLS 완료부터 첫 바이트까지는 150ms, 첫 바이트부터 완료까지도 150ms이며 다섯 구간의 합은 500ms입니다. 서버 처리만 150ms였다고 결론 내릴 수는 없습니다.
누적값을 바꿔 독립적으로 계산하기 같은 단순 조건의 다른 가정 값은 DNS 0.01초, 연결 0.05초, TLS 0.12초, 첫 바이트 0.40초, 전체 0.70초입니다. 연결·TLS의 추가 시간과 마지막 두 구간을 각각 구하고, 가장 긴 구간만으로 원인 장비를 확정할 수 있는지도 판단하세요.
누적 시간 차분과 해석의 풀이
연결은 40ms, TLS는 70ms, TLS 완료부터 첫 바이트까지 280ms, 첫 바이트 이후 완료까지 300ms입니다. DNS 10ms까지 합하면 700ms입니다. 가장 긴 300ms에도 응답 크기·전송 속도·클라이언트 읽기 등 여러 조건이 관여하고, 280ms도 요청 전송·대기·첫 응답 경로를 포함합니다. 동일 요청의 프록시·서버 로그와 응답 크기를 대조해야 하며 누적값 자체를 특정 장비의 처리 시간으로 바꾸지 않습니다. 숫자는 계산용 가정이며 curl이나 서버 실행을 새로 측정하지 않았습니다.
다음 절에서는 패킷 캡처를 기반으로 통신 흐름을 확인하는 패킷 분석을 다루겠습니다.