IT보안 학습

HTTP 프로토콜 총정리

김구티2 2023. 12. 2. 22:59

1. HTTP 프로토콜의 개념

HTTP(Hypertext Transfer Protocol)는 텍스트, 이미지, 음성, 영상을 비롯한 기타 멀티미디어 파일 등을 Web을 통해 전송하기 위한 일련의 규칙을 말한다. HTTP는 인터넷을 사용해본 사람이라면 매우 친숙한 용어일 텐데, 실제로 우리가 인터넷 브라우저를 실행한다면 이미 HTTP를 간접적으로 사용하고 있다고 말할 수 있을 것이다. HTTP는 인터넷의 기초를 이루는 TCP/IP 모델의 프로토콜 모음 위에서 실행되는 애플리케이션 프로토콜인데, 무언가 데이터를 주고받을 때 연결을 지속적으로 유지하는 것이 아니라 요청이 있을 때 연결을 수행하고, 메시지를 처리한 후에 연결을 종료하는 방식이다. 이처럼 이전 요청과는 무관한 각각의 요청을 독립적인 트랜잭션으로 취급하는 프로토콜 방식을 State-less 프로토콜이라 하는데, HTTP가 이것의 대표적 예시라 할 수 있다.

 

HTTP 프로토콜은 TCP 기반 프로토콜의 80번 포트를 사용하고, 이 80번 포트는 오직 루트 사용자만 오픈하여 사용할 수 있다. 따라서 웹 서버 관련 프로세스는 루트 사용자의 권한으로 진행된다 볼 수 있다. 물론, 모든 프로세스가 루트에 의해 진행되는 것은 아니다. 한 개의 프로세스가 루트로 가동한다면, 80번 포트를 점유하게 되고, 자식 프로세스를 생성하는 형태로 실행되기 때문이다.

 

현재의 HTTP/3에 이르기 까지 많은 버전이 있는데, 버전 1.0부터 살펴보려 한다.

 

2. HTTP 프로토콜의 버전

ㄱ. HTTP Version 1.0

이전 버전인 0.9 다음 단계로, 연결을 수행할 때마다 3-Way Handshaking 기법을 사용한다. 이때 메시지를 수신받게 되면, 완전히 연결을 종료한다. 그리고 필요 시에 다시 연결을 수립하여 수신을 받는 형태인 것이다. HTTP 프로토콜은 내부적으로 TCP 프로토콜을 사용하기 때문에 연결을 할 때 3-Way Handshaking 방법을 사용하는 것이다. 1. 클라이언트인 브라우저가 웹 서버에 SYN 메시지를 보내면, 2. 웹 서버는 웹 브라우저에 SYN, ACK로 응답하고, 3. 웹 브라우저는 서버에 최종 연결확립 메시지인 ACK를 전송하여 연결을 수립한다.

 

그런데 1.0의 경우, 다른 부족한 점도 많겠지만, 특히나 연결 하나 당 Request 하나와 Response 하나만 처리 가능하다는 매우 비효율적인 문제는 1.1의 등장을 예고했다고 볼 수 있다.

 

ex) HTTP Version 1.0의 3-Way Handshaking을 통한 통신 과정

1. 110.11.111.111 IP 주소에서 110.11.111.222 IP 주소로 SYN 메시지를 보낸다.

2. 110.11.111.222는 SYN, ACK로 응답한다.

3. 110.11.111.111는 110.11.111.222에 ACK를 전송하고 TCP의 3-Way Handshaking을 완료하여 연결을 확립한다.

4. 이렇게 연결이 확립되면 TCP의 연결 정보는 Established 상태로 변경된다.

5. HTTP 프로토콜은 연결이 확립되면 웹 브라우저가 HTTP Request로 웹 서버에 서비스를 요청하고, 웹 서버는 HTTP Response로 요청에 대해서 서비를 처리한 후 응답을 수행한다.

6. 웹 서버는 웹 브라우저의 요청에 정상적으로 응답을 완료하면 HTTP 상태코드를 200으로 설정해서 웹 브라우저에게 전송한다.

 

ㄴ. HTTP Version 1.1

HTTP의 첫번째 표준 프로토콜로, 기존 1.0에서 순차적으로 하나씩 Request 및 Response가 처리되는 방식을 개선하였다. 또한, 1.1에서는 Keep Alive Connection이라는 개념이 도입되었는데, 이는 어느 정도 대기한 후 연결을 종료한다는 것을 의미한다. 통신에는 언제나 변수가 발생할 수 있고, 일부 메시지의 지연이 발생할 수 있는데, 1.1에서는 Keep Alive Connection 덕분에 지연되어서 응답이 오는 메시지를 모두 수신 받을 수 있게 됐다. 이것은 단순히 지연되는 메시지만을 수신받을 수 있게 만든 것이 아니라, 연속적인 요청 시에 다시 Connect를 진행하지 않고 송수신을 수행함으로써 송수신 단계를 더 줄어들게 만든 것으로도 의미가 있다. 즉, 2번 연달아 메시지를 송수신 했다고 가정하자. 그게 1.0에서는 연결-요청-응답-연결-요청-응답의 6단계였다면, 1.1에서는 연결-요청-응답-요청-응답의 5단계로 줄어든 것이다.

 

그러나 1.1에도 한계는 존재한다. HOL(Head of Line Blocking)의 문제가 있는데, 이는 TCP가 순차적이기 때문에 발생하는 문제이다. ABCDEF 순으로 요청이 처리되는데, 만약 A의 요청에서 너무 오랜 시간이 걸린다면, BCDEF는 Blocking 되어버리는 상황이 발생할 수 있을 것이다. 또한, 헤더 정보가 너무 무거운 Fat message headers 문제가 발생한다. 1.1의 헤더에는 많은 메타 데이터가 있고, 매 Request 마다 중복된 헤더 값을 전송하게 되는데, 간혹 전송하려는 값보다 헤더 값이 큰, 그야말로 배보다 배꼽이 큰 경우가 발생하기도 한다. 이런 중대한 문제들은 다음 버전의 개발을 요구하였다.

 

ㄷ. HTTP version 2.0

HTTP 2.0은 더 빠른 데이터 처리를 위한 여러 기술이 추가된 프로토콜로, 1.1 버전의 성능 향상에 초점이 맞춰져 있다고 볼 수 있다. 추가된 기술의 첫번째로는 멀티플렉싱(Multiplexing)이 있는데, 이는 순차적 연결이 아니라 동시 다발적인 양방향 통신을 지원한다. 그래서 아래와 같은 양상을 보이게 된다. 단순하게만 보더라도 2.0으로 갈수록 훨씬 적은 시간이 걸리게 됨을 알 수 있다.

또한, 헤더압축(Header Compression) 기능이 더해졌는데, 이는 헤더의 정보를 1/3 수준으로 압축해서 보다 빠르게 메시지를 처리할 수 있게 만들었다. 그리고 서버 푸시(Sever Push)의 기능도 추가되었는데, 웹 서버가 웹 브라우저에게 필요한 데이터를 알아서 미리 전송할 수 있는 기술로, Request 횟수와 전송해야 하는 데이터의 양을 줄일 수 있는 기술이다. 이 기술로 인해 Request의 중복이 줄어들게 된다.

그밖에도, 리소스 간에 우선순위를 설정하게 하는 스트림 우선순위(Stream prioritization)가 추가되었다. 예를 들어, 클라이언트가 요청한 HTML 문서 내부에 CSS 파일 1개와 이미지 파일 2개가 존재한다고 하자. 이를 클라이언트가 각각 요청한 후 이미지 파일보다 CSS 파일의 수신이 늦어지게 되면 브라우저에 HTML이 늦게 도착하게 될 것이다. 이런 문제를 해결해주는 것이 스트림 우선순위이다. 

 

이런 많은 장점이 있으나, HTTP 2.0에서도 여전히 HOL의 문제에서 완전하게 해소되지 않았다. TCP 고유의 문제이기 때문이다. 스트림을 이용한 병렬적 처리로는 한계가 발생한다. 예를 들어, aaaaabbbbbccccc를 ABC라는 대집단으로 만들었다고 하더라도, A집단에서 문제가 생기면 B, C 대집단은 문제 해결을 기다려야 하기 때문이다. 결국, HOL 문제는 2.0에 이르면서 완화는 되었을 지언정, 근본적인 해결은 되지 않았다는 것이다. 이것의 근본적인 문제를 해결할 수 있는 것이 바로 HTTP 3.0이 되겠다.

 

ㄹ. HTTP 3.0

이전의 HTTP 버전들이 HOL 문제를 앓고 있는 이유는 결국 TCP를 기반으로 했기 때문이다. 그렇다면 그것을 해결하는 문제는 간단하다. TCP를 기반으로 하지 않으면 되는 것이다. HTTP 3.0은 UDP를 기반으로 한 QUIC(Quick UDP Internet Connections) 프로토콜을 사용한다. 이 역시 웹 표준이다. 말만 표준인 게 아니라, 구글, 네이버, 넷플릭스에서도 애용하고 있다니 일반 이용자들은 이를 신뢰할 만 할 것이다. (단, PC의 성능이 좋지 못하다면 QUIC는 오히려 Quick이 아닌 Slow를 유발할 것이다. 그렇기에 PC의 성능이 좋지 못하다면 QUIC를 비활성화하는 것이 낫다.) QUIC는 UDP 기반 답게 똑같이 전송 계층에서 구동되지만, 새로운 계층을 추가함으로써 신뢰성을 더했다. 그도 그럴 것이, UDP 하면 생각나는 것은 '빠르지만 신뢰성은 없는'이지 않겠는가. 여기서 추가된 계층은 TCP에 존재하는 혼잡 제어, 속도 조정, 패킷 재전송을 비롯한 여러 기능을 제공한다.

 

이 QUIC에서는 HOL의 문제를 드디어 해결하는데, TCP에서는 하나의 스트림 체인에서 여러 스트림을 처리했다면, QUIC에서는 각 스트림에 독립된 스트림 체인을 구성하여 HOL을 근본적으로 해결한다. 또한 TLS를 기본으로 사용하기 때문에 일반적으로 사용자가 기대하는 HTTPS에서의 보안 속성을 지원한다고 볼 수 있다. 또한, 0-RTT를 따졌을 때, 이미 연결된 서버의 경우에 클라이언트는 핸드셰이크 요구 사항을 건너뛸 수 있다. UDP 기반 답게 속도에서도 더욱 강점을 갖을 수 있다는 말이 된다.

 

 

기존에 존재하는 연결이 끝나기를 기다릴 필요도 없기 때문에 속도 면에 있어서 큰 우위를 가져갈 수 있는 것이다.

 

※  HTTP vs HTTPS

HTTP와 마찬가지로 일반 이용자들에게 친숙한 용어가 HTTPS일 것이다. 보통 웹 주소를 적을 때 제일 앞에 위치하는 것이 둘 중 하나이기 때문이다. HTTPS는 애플리케이션 계층에서 하위 계층으로 SSL(Secure Sockets Layer) 또는 TLS(Transport Layer Security)를 사용하는 것이다. HTTPS는 웹 서버에 의해 반환되는 페이지뿐만 아니라, 사용자의 HTTP 페이지 요청을 암호화/복호화한다. HTTPS는 또한, MITM(=중간자 공격)나 도청으로부터 보호한다. 흔히 HTTP보다 HTTPS를 더욱 안전한 것으로 인식하는데, 그것은 보안과 신뢰의 계층을 하나 추가한다고 여겨지기 때문일 것이다.

 

※ HTTP 상태코드

위에서 200의 의미는 무언가 완료되었다는 의미로 해석이 될 수 있을 것이다. HTTP의 상태코드로는 아주 다양한 것들이 있는데, 일반적인 응답코드는 아래와 같다.

상태코드 의미
200 OK. GET 또는 POST의 요청이 효과가 있었고, 실행 중임을 의미한다.
300 Moved Permanently. 요청된 리소스의 URL이 영구적으로 변경되었음을 의미한다.
401 Unathorized. 서버에 요청을 하는 클라이언트 또는 사용자가 인증되지 않았음을 의미한다.
403 Forbidden. 클라이언트의 신원은 알지만, 접근 권한은 주어지지 않았음을 의미한다.
404 Not Found. 가장 빈번하게 발생하는 에러 코드로, URL이 인식되지 않거나 해당 위치의 리소스가 존재하지 않음을 의미한다.
500 Internal Server Error. 서버에서 처리 방법을 알 수 없는 상황이 발생했음을 의미한다.

 

728x90