네트워크 기초 — 리눅스 VM 에서 손으로 · HTTP 와 종합 · 이론
HTTP 는 텍스트다 — 그리고 층을 순서대로 본다
한 줄 요약
HTTP 요청은 요청 줄·헤더·빈 줄 세 부분의 텍스트라 nc 로 손으로 쓸 수 있다. 응답의 상태 코드는 "어느 층까지 성공했나" 를 말한다 — 404 는 TCP 도 HTTP 도 성공한 뒤의 답이고, refused 는 서버가 없다는 뜻이다.
왜 이게 필요했나
브라우저와 SDK 가 HTTP 를 감춰 주는 동안은 편하다. 그런데 프록시가 헤더를 바꿔치기하고, Host 가 틀려 엉뚱한 사이트가 나오고, 리다이렉트가 A→B→A 로 돌 때는 감춰진 것을 봐야 한다. 요청을 손으로 한 번 써 본 사람은 curl -v 의 > 와 < 가 무엇인지 안다. 그것이 API 디버깅의 절반이다.
그리고 네트워크 진단은 결국 층을 순서대로 갈라내는 일이다. 링크 → 주소 → 이웃 → 경로 → 이름 → 포트 → 방화벽 → 응답. 각 층에는 그 층만 보는 명령이 있다. 순서 없이 아무 명령이나 치면 "다 정상인데 안 된다" 에 갇힌다.
어떻게 동작하나
요청은 GET /docs/guide.txt HTTP/1.1 한 줄, Host: localhost 같은 헤더 몇 줄, 그리고 빈 줄이다. 줄 끝은 CRLF. 빈 줄이 "헤더 끝" 이라 빼먹으면 서버는 헤더가 더 올 줄 알고 기다린다. Host 는 HTTP/1.1 의 유일한 필수 헤더 — 한 서버가 여러 사이트를 받으므로 어느 것인지 이것으로 고른다. Connection: close 는 응답 뒤 끊으라는 뜻이고, 없으면 연결을 재사용한다(keep-alive).
응답은 HTTP/1.0 200 OK 상태 줄, 헤더, 빈 줄, 본문이다. 2xx 성공, 3xx 다른 데 있음(Location 을 따라가라), 4xx 요청 쪽 잘못, 5xx 서버 쪽 잘못. HEAD 는 헤더만 받고, 디렉터리를 슬래시 없이 요청하면 301 로 슬래시 붙은 곳을 가리킨다.
진단 순서를 명령으로 적으면 이렇다. ip -br link(링크가 UP 인가) → ip -br addr(주소가 있나) → ip neigh(이웃이 FAILED 인가) → ip route get(어디로 나가나) → getent hosts(이름이 풀리나, dig 로 서버를 따로) → ss -ltn(포트가 열려 있나) → nft list ruleset 의 counter(방화벽이 세고 있나) → curl -v(응답이 무엇인가). 앞 단계가 맞아야 뒤 단계가 의미가 있다.
현장에서 만나는 모습
ping 은 되는데 안 열린다. ping 은 ICMP 고 서비스는 TCP 다. 방화벽이 프로토콜별로 다르다. 반대로 ping 이 안 된다고 끊긴 것도 아니다 — 이 코스의 마지막 실습은 설계상 ICMP 를 막는다. 진단은 실제 서비스와 같은 프로토콜·포트로 한다.
dig 는 되는데 curl 은 안 된다. /etc/hosts 에 옛 주소가 남아 있다. dig 는 서버에 직접 묻고 curl 은 libc 를 거쳐 hosts 를 먼저 본다. 같은 이름에 두 답이 있는 것이다.
다음 실습에서 할 것
python3 -m http.server 를 띄우고 nc 로 GET·HEAD·404·301 을 손으로 만들어 받은 뒤 curl -v 와 대조한다. 그다음 종합 실습에서 두 서브넷·라우터·dnsmasq·forward 방화벽·마스커레이드를 한 VM 에 세우고, "안 열린다" 는 신고를 어느 순서로 볼지 보고서로 남긴다.