아래는 사용자가 웹 브라우저에 특정 자원(google.com)을 요청할 때 네트워크 상에서 무슨 일이 일어나는지에 관한 내용을 다룬다.
HTTP의 기본 개념 & 프로토콜 & WEB
HTTP(Hypertext Transfer Protocol)는 웹 브라우저와 웹 서버가 통신할 때 사용하는 프로토콜, 즉 통신 규칙 혹은 통신 규약을 의미한다.
여기서 프로토콜(Protocol)은 우체국에 비유를 들면 물품에 대한 배송을 요청하기 위해서는 해당 공간에 가서 우체국에서 지정한 양식에 따라 정보를 기입해야 하고 우체국에서는 해당 양식에 기입된 정보를 바탕으로 물건을 배송하는데, 이때 HTTP의 경우에는 인터넷이라는 공간에서 웹 브라우저와 웹 서버가 요청과 응답 시에 사용하는 양식을 규정하고 해당 양식에 알맞은 정보를 기입하여 요청과 응답이라는 통신을 해나간다. 즉 프로토콜은 시스템 간 통신 시 사용되는 일정한 양식과 규칙이 정해진 일종의 통신 규약이라 할 수 있다.
HTTP 프로토콜은 웹 브라우저(Client)와 웹 서버(Server)간의 통신 시 사용되는 프로토콜이다. 여기서 웹(WEB)이란 World Wide Web을 의미하고 웹은 인터넷을 통해 사용자들이 정보를 주고 받는 공간을 말하는데, 인터넷을 중심으로 연결된 사용자들의 모습이 마치 거미줄과 같다고 하여 WEB이라는 이름이 붙었다.
Port
HTTP의 경우 보통 80번(Well-known Port) 포트에서 실행된다. 포트는 IP가 WAN(Wide Area Network) 대역의 디바이스 끼리 통신하기 위해 디바이스(공유기)의 주소(Public IP)를 나타내거나 LAN(Local Area Network) 대역의 디바이스 끼리 통신하기 위해 각 디바이스(PC, Smartphone, Laptop, Tablet, etc.)의 주소(Private IP)를 나타내는 것과 같이, 디바이스 내에서 특정 프로세스(실행 중인 프로그램)의 주소를 나타내는 용도로 사용된다. 즉 80번 포트에서는 웹 서버 프로그램이 실행 중이라 할 수 있다.
DNS
웹 브라우저에서 웹 서버에 자원을 요청하기 위해서는 google.com과 같이 도메인을 URL 주소창에 입력해야 한다. 이 때, 먼저 DNS 과정(DNS 조회 -> DNS 쿼리 -> IP 주소 반환)을 거친다. 여기서 DNS(53번 포트)는 TCP/IP모델에서 4계층인 애플리케이션 계층에 속하는 프로토콜로, 주로 UDP 프로토콜을 이용하여 인터넷 상에서 도메인 이름을 IP 주소로 변환하는 작업을 수행한다.
즉 만약 웹 브라우저 URL 주소창에 google.com을 입력하면 웹 브라우저는 먼저 브라우저, 운영체제 및 공유기(라우터) 캐시에 해당하는 DNS 정보, 즉 해당 도메인에 매핑되어 있는 IP 주소가 존재하는 지 확인한다. 만약 브라우저, 운영체제, 공유기 캐시에 해당하는 DNS 정보가 없다면 브라우저는 ISP(Internet Service Provider)에 의해 관리되고 지리적으로 가장 가까운 로컬 DNS 서버에 쿼리를 보낸다. 이때 로컬 DNS 서버의 캐시를 확인하고 만약 해당하는 DNS 정보가 없다면 로컬 DNS 서버는 재귀적 질의를 시작하여 먼저 루트(Root) DNS 서버로 쿼리를 보내고 루트 DNS 서버는 Top Level Domain(.com, .net, etc.)을 관리하는 DNS 서버를 알고 있고 그중에 .com을 관리하는 TLD DNS 서버에 관한 정보를 로컬 DNS 서버에 반환하고 다시 로컬 DNS 서버는 .com 도메인을 관리하는 TLD DNS 서버에 쿼리를 보낸다. 그러면 TLD DNS 서버는 .com의 하위 도메인을 관리하고 그 중, google.com을 관리하는 Authoritative(권한있는) DNS 서버에 대한 정보를 로컬 DNS 서버에 반환하고 다시 로컬 DNS 서버는 해당하는 Authoritative DNS 서버에 쿼리를 보내고 해당 DNS 서버는 질의 받은 도메인이 자신이 관리하고 있는 도메인이므로 google.com에 해당하는 IP 주소를 반환한다.
TCP 3-Way Handshake
이후 웹 브라우저는 반환 받은 IP 주소를 가지고 자원에 대한 요청을 하기 전에 TCP 3-Way Handshake 과정을 먼저 거쳐 TCP 통신에 대한 연결 수립을 완료한다. 해당 과정은 웹 서버가 현재 통신이 가능한 상태인지 확인하고 해당 과정이 정상적으로 완료되었다는 것은 둘 사이의 통신 준비가 완료되었음을 보증한다.
TCP 3-Way Handshake는 SYN -> SYN-ACK -> ACK 과정으로 이루어 지게 되는데, SYN(Synchronize)은 웹 브라우저가 웹 서버에 요청을 보내는 패킷으로 당신과 연결을 하고 싶다는 의미를 내포한다. 이후 웹 서버가 연결을 수락한다면 웹 브라우저에 연결을 수락한다는 의미로 SYN-ACK 패킷을 보내고, 해당 패킷을 받은 웹 브라우저는 다시 웹 서버에 연결이 성공적으로 수립되었다는 것을 알리는 ACK(Acknowledgment) 패킷을 보내게 된다.
HTTP 통신 과정
그러면 이제 웹 브라우저와 웹 서버 사이에 데이터 교환을 위한 통신 준비 과정이 완료되었고, 비로소 웹 브라우저는 리소스에 대한 요청(Request)을 웹 서버에 보내고 해당 요청을 웹 서버가 받아 그에 대한 응답(Response)을 보내줄 수 있게 된다. HTTP 프로토콜을 이용한 웹 브라우저의 요청과 웹 서버의 응답 양식은 아래와 같다.
위 사진은 필자가 Node.JS, Express, MongoDB를 이용하여 구축한 웹 사이트에 대해 로그인 요청을 보낼 때의 메시지이다. 즉 우체국에 비유를 들면 택배를 보낼 때의 배송 양식과 그곳에 기입된 정보이다.
HTTP의 요청 메시지는 크게 3가지 파트로 구분되어 있다. 첫번째 파트는 HTTP Method, 리소스 경로, HTTP 버전 정보(위 사진에서는 HTTP Method의 경우 POST, 리소스 경로의 경우 /login, 버전 정보의 경우 HTTP/1.1)가 표시되어 있는 Request Line이 존재하고 두번째 파트의 경우 쿠키, Referer 등의 정보가 포함되어 있는 Header Lines가 존재하고 세번째 파트는 헤더 파트 후 한 줄의 공백 후에 본문(Body)에 관한 내용이 표시된다. 위 사진은 로그인을 요청할 때의 메시지이므로, 해당 본문에는 email과 password가 포함(암호화가 아닌 평문으로)되어 있다(Not HTTPS).
아래는 해당 요청에 대한 웹서버의 응답 메시지이다.
웹 서버의 응답 메시지 또한 크게 3가지 파트로 나뉘어 있다. 즉 HTTP 버전 정보, HTTP 상태 코드가 포함되어 있는 Status Line 그리고 이어서 헤더 정보가 포함된 Header Lines가 존재하고 이후 한 줄의 공백 후에 본문(Body)의 내용이 포함되어 있다.
웹 브라우저의 요청 메시지에는 POST라는 HTTP Method가 포함되어 있는데, 다음은 자주 쓰이는 HTTP Method의 목록이다.
HTTP Methods | 설명 |
GET | 웹 서버의 리소스를 요청할 때 주로 쓰인다. |
POST | 로그인, 글 생성과 같이 사용자의 입력을 처리하고자 할 때 쓰인다. |
PUT | 생성된 글에 대해 전체를 업데이트 하고자 할 때 쓰인다. |
PATCH | 생성된 글에 대해 일부를 업데이트 하고자 할 때 쓰인다. |
DELETE | 리소스에 대해 삭제를 요청할 때 쓰인다. |
HEAD | 본문을 제외한 헤더 부분만의 반환을 요청할 때 쓰인다. |
OPTIONS | 해당 웹 앱에서 사용 가능한 HTTP Method의 목록을 반환한다. |
TRACE | 요청 패킷을 그대로 반환한다. 요청 패킷의 무결성 여부를 검사할 때 쓰인다. |
웹 서버의 응답 메시지에는 302(리다이렉션)라는 HTTP 상태 코드(Status Code)가 포함되어 있는데, 다음은 자주 쓰이는 HTTP Status Code의 목록이다.
Status Code | Description | Status Code | Description |
2xx | Success 요청한 것에 대한 처리가 성공적으로 완료되었음을 의미 |
200 | OK 클라이언트의 요청을 서버가 성공적으로 처리 |
201 | Created 새로운 리소스 생성 |
||
3xx | Redirection 다른 경로로 리다이렉션(이동) |
301 | Moved Permanently 지정한 리소스가 새로운 URI로 영구 이동 |
302 | Found 요청한 리소스를 다른 URI에서 찾음 |
||
4xx | Client Error 클라이언트 측 오류 |
401 | Unauthorized 지정한 리소스에 대한 접근 권한이 없음. 보통 로그인 되지 않은 경우 |
403 | Forbidden 지정한 리소스에 대한 접근이 금지됨. 보통 관리자 페이지로의 접근 시 |
||
404 | Not Found 지정한 리소스를 찾을 수 없음 |
||
5xx | Server Error 서버 측 오류 |
500 | Internal Server Error 내부 서버에 오류 발생 |
만약 클라이언트가 요청한 리소스가 서버 사이드 스크립트(PHP, Node.JS, JSP, etc.)인 경우를 살펴보면 먼저 PHP의 경우에는 Apache, Nginx와 같은 웹 서버로 기능하는 소프트웨어가 요청받은 PHP 스크립트를 PHP 해석을 담당하는 엔진(zend engine, etc.)으로 보내어 동적인 데이터를 처리하여 HTML의 정적인 데이터를 생성하여 웹 서버로 전달하고 이것을 전달 받은 웹 서버는 HTML 코드를 그대로 브라우저에 응답 메시지 본문에 담아 보낸다. 웹 브라우저는 응답 받은 HTML 코드를 렌더링 하여 사용자에게 알맞은 페이지를 보여준다.
만약 서버 사이드 스크립트가 Node.JS인 경우에는, 요청한 리소스에 대해 지정된 라우팅을 처리하는 로직을 실행하여 로직을 처리하고 동적인 데이터를 HTML에 삽입하기 위해 ejs 엔진과 같은 View Engine을 이용하여 동적인 데이터를 처리한다.
참고자료
- https://datatracker.ietf.org/doc/html/rfc7231
- https://betterprogramming.pub/understand-the-flow-of-a-http-request-1a268ec193f0
- https://www.researchgate.net/figure/shows-the-flow-of-packets-for-a-HTTP-10-transaction-on-the-CSP-with-TCP-IP-termination_fig2_221303397
- https://hongong.hanbit.co.kr/http-%EC%83%81%ED%83%9C-%EC%BD%94%EB%93%9C-%ED%91%9C-1xx-5xx-%EC%A0%84%EC%B2%B4-%EC%9A%94%EC%95%BD-%EC%A0%95%EB%A6%AC/
'InfoSec Log > WEB' 카테고리의 다른 글
[WEB Server] Node.js로 개발한 앱 로컬머신에서 퍼블릭으로 배포 방법 (0) | 2024.06.18 |
---|