HTTP는 Hyper Text Transfer Protocol의 약자로, 인터넷에서 데이터를 주고받을 수 있는 프로토콜이다. 프로토콜은 인터넷끼리 통신을 하기 위해 정해 놓은 규칙으로 모든 통신은 규칙 즉, 프로토콜에 의존한다.
HTTP는 웹서비스 통신을 할 때, 웹페이지를 들어갈 때 사용하는 프로토콜이다.
이러한 HTTP는 버전이 1.0부터 3까지 발전해 왔고 이러한 버전 변화를 이 글에 간단하게 작성해보려고 한다.
이 글은 '면접을 위한 CS 전공지식노트 - 주홍철'을 읽고 이를 바탕으로 간단하게 작성한 글이다.
들어가기 전 HTTP에 대해 잘 모른다면 https://khdscor.tistory.com/63를 참고하길 바란다.
1. HTTP/1.0
HTTP/1.0은 기본적으로 한 연결당 하나의 요청을 처리하도록 설계되었다. 이는 RTT증가를 불러왔는데, RTT(Riunt Trip Time)란 패킷이 목적지에 도달하고 나서 다시 출발지로 돌아오기까지 걸리는 시간 즉, 패킷 왕복 시간을 의미한다.
이러한 RTT 증가 문제는 서버에 부담이 가고 사용자 응답 시간이 길어지게 된다. 이를 해결하기 위해 이미지 스플리팅, 코드 압축, 이미지 Base64 인코딩을 사용하곤 했다.
이미지 스플리팅은 많은 이미지를 다운로드받게 되면 과부하가 걸리기 때문에 만은 이미지를 합쳐서 하나의 이미지로 다운로드받고, 이를 background-image의 position을 이용하여 표기하는 방법이다.
코드압축은 코드를 압축해서 개행 문자, 빈칸을 없애서 코드의 크기를 최소화하는 방식이다.
이미지 Base64 인코딩은 이미지 파일을 64진법으로 이루어진 문자열로 인코딩하는 방식이다. 인코딩이란 정보의 형태나 형식을 표준화, 보안, 처리 속도 향상, 저장 공간 절약 등을 위해 다른 형태나 형식으로 변환하는 처리 방식을 의미한다.
인코딩의 종류에는 ASCII, URL HTML, Base64, MS Script 등이 있다.
2. HTTP/1.1
HTTP/1.0에서 업그레이드된 버전이다. 1.0에서는 1번의 요청당 1번의 TCP연결이 있었다. 이는 TCP 연결을 하고 connection을 형성하는데 1번 요청이 일어나면 connection이 닫히는 것이다. 하지만 1.1에서는 TCP의 3 way-handshake가 한 번 일어나서 TCP초기화를 한 이후에 keep-alive라는 옵션으로 여러 개의 파일을 송수신할 수 있게 바뀌었다. 이렇게 요청이 처리된 이후에도 connection이 close 되지 않고 계속 유지하는 것이다. 이를 persistent connection이라고 한다.
예를 들어 100번의 요청이 있다면 1.0에서는 100번의 TCP초기화가 있었지만 1.0에서는 1번의 초기화만 있다는 얘기이다. 여기서 keep-alive는 헤더에 넣는데 값으로 timeout나 max를 설정하여 얼마나 유지할지, 몇개의 요청까지 열어둘지 등을 정할 수 있다.
하지만 여기서 오해하면 안되는 것은 동일한 url과 http method로 동일한 요청을 반복해서 보낼 때를 의미하는 것이다. 다른 주소로의 요청은 항상 TCP 초기화가 일어난다.
참고로 HTTP/1.0에서도 keep-alive가 있어서 문제를 해결할 수는 있었다. 하지만 표준화되지 않았었고 1.1에서 표준화된 것이다. 1.0에서는 기본이 1번 연결하고 1번 요청 후 connection을 닫도록 설정돼있지만, 1.1에서는 connetction이 닫히지 않고 계속 유지되도록 기본적으로 설정되어 있는 것이다.
이것으로 요청이 여러번 발생하는 문제는 해결했지만 문서 안에 포함된 다수의 리소스(이미지, 동영상, css 파일, js 파일 등)를 처리하려면 요청할 리소스 개수에 비례해서 대기 시간이 길어지는 단점이 있다. 이는 HOL B(Head Of LIne Blocking) 문제로 네트워크에서 같은 큐에 있는 패킷이 그 첫 번째 패킷에 의해 지연될 때 발생하는 성능 저하 현상을 의미한다.
예를 들어 image.jpg와 styles.css, data.xml을 다운로드 받을 때 image.jpg가 매우 크고 속도가 느리면 그 뒤에 것들이 대기하게 되면서 다운로드가 지연되게 된다.
그리고 한가지 더 문제는 HTTP/1.1의 헤더에는 쿠키 등 많은 메타데이터가 들어 있고 압축이 되자 않아 무겁다.
3. HTTP/2
HTTP/2는 HTTP/1.1보다 지연 시간을 줄이고 응답 시간을 더 빠르게 할 수 있으며 멀티플렉싱, 헤더 압축, 서버 푸시, 요청의 우선순위 처리를 지원하는 프로토콜이다.
멀티플렉싱이란 여러 개의 스트림을 사용하여 송수신한다는 것이다. 스트림은 시간이 지남에 따라 사용할 수 있게 되는 일련의 데이터 요소를 가리키는 데이터의 흐름으로 멀티플렉싱으로 인하여 특정 스트림의 패킷이 손실되었더라도 해당 스트림에만 영향을 미치고 나머지 스트림은 잘 동작한다.
HTTP/1.1에서는 헤더의 크기가 크다는 문제가 있었는데 HTTP/2에서는 헤더 압축을 써서 해결하였다. 헤더 압축을 하는 알고리즘은 허프만 코딩(huffman coding)으로 문자열을 문자 단위로 쪼개 빈도수를 세어 빈도가 높은 정보는 적은 비트 수를 사용하여 표현하고, 빈도가 낮은 정보는 비트 수를 많이 사용하여 표현해서 전체 데이터의 표현에 필요한 비트양을 줄인다.
HTTP/1.1에서는 클라이언트가 서버에 요청을 해야 파일을 다운로드할 수 있었다면 HTTP/2는 클라이언트 요청 없이 서버가 바로 리소스를 푸시할 수 있다. 예를 들어 html에는 css나 js파일이 포함되어 있는데 html을 요청하면 그 안에 있는 css나 js파일을 서버에서 바로 푸시할 있는 것이다. 이를 서버 푸시라고 한다.
4. HTTPS
HTTP/2는 HTTPS 위에서 동작한다. HTTPS는 애플리케이션 계층과 전송 계층 사이에 신뢰 계층인 SSL/TLS 계층을 넣은 신뢰할 수 있는 HTTP 요청을 말한다. 이를 통해 통신을 암호화한다.
SSL(Secure Socket Layer)은 SSL 1.0부터 시작해서 SSL 2.0, SSL 3.0, TLS(Transport Layer Security Protocol) 1.0, TLS 1.3까지 버전이 올라가면서 TLS로 명칭이 변경되었지만 보통 이를 합쳐서 SSL/TLS라고 부른다. 이 글에선 TLS 1.3을 기준으로 작성하겠다.
SSL/TLS는 전송 계층에서 보안을 제공하는 프로토콜이다. 클라이언트와 서버가 통신할 때 SSL/TLS를 통해 제 3자가 메시지를 도청하거나 변조하지 못하도록 합니다. 공격자가 서버인 척하며 사용자 정보를 가로채는 인터셉터를 방지할 수 있는 것이다.
SSL/TLS는 보안 세션을 기반으로 데이터를 암호화하며 보안 세션이 만들어질 때 인증 메커니즘, 키 교환 암호화 알고리즘, 해싱 알고리즘이 사용된다.
보안 세션이란 보안이 시작되고 끝나는 동안 유지되는 세션을 말하고, SSL/TLS는 TCP handshake를 통해 보안 세션을 생성하고 이를 기반으로 상태 정보 등을 공유한다.
클라이언트에서 사이퍼 슈트(cypher suites)를 서버에 전달하면 서버는 받은 사이퍼 슈트의 암호화 알고리즘 리스트를 제공할 수 있는지 확인한다. 제공할 수 있다면 서버에서 클라이언트로 인증서를 보내는 인증 메커니즘이 시작되고 이후 해싱 알고리즘 등으로 암호화된 데이터의 송수신이 시작된다.
위 과정은 최초 1 RTT가 발생하고 인증서를 받은 클라이언트는 이 인증서를 기반으로 데이터를 암호화하여 송수신 하는 것이다.
사이퍼 슈트는 프로토콜, AEAD 사이퍼 모드, 해싱 알고리즘이 나열된 규약을 말하며, 다섯 개가 있다.
- TLS_AES_128_GCM_SHA256
- TLS_AES_256_GCM_SHA384
- TLS_CHACHA20_POLY1305_SHA256
- TLS_AES_128_CCM_SHA256
- TLS_AES_128_CCM_8_SHA256
TLS는 프로토콜, AES~는 AEAD 사이퍼 모드, SHA256은 해싱 알고리즘을 의미한다.
그렇다면 AEAD 사이퍼 모드란 무엇일까?
AEAD(Authenticated Encryption with Associated Data)는 데이터 암호화 알고리즘이다. 예를 들어 AES_128_GCM이라는 것은 128비트의 키를 사용하는 표준 블록 암호화 기술과 병렬 계산에 용이한 암호화 알고리즘 GCM이 결합된 알고리즘을 뜻한다.
인증 메커니즘은 CA(Certificate Authorities)에서 발급한 인증서를 기반으로 이루어진다. CA에서 발급한 인증서는 안전한 연결을 시작하는 데 있어 필요한 '공개키'를 클라이언트에 제공하고 사용자가 접속한 서버가 신뢰할 수 있는 서버임을 보장한다. 인증서는 서비스 정보, 공개키, 지문, 디지털 서명 등으로 이루어져 있다.
CA는 아무 기업이나 할 수 없고 신뢰성이 엄격하게 공인된 기업들만 참여할 수 있으며, 대표적으로 Comodo, GoDaddy, GlobalSign, 아마존 등이 있다.
자신의 서비스가 CA를 발급받으려면 자신의 사이트 정보와 공개키를 CA에 제출해야 한다. 이후 CA는 공개키를 해시한 값인 지문(finger print)을 사용하는 CA의 개인(비밀)키 등을 기반으로 CA 인증서를 발급한다.
클라이언트와 서버가 주고받는 데이터를 암호화는 실질적인 키를 주고받는 알고리즘을 키 교환 알고리즘이라고 한다. 키 교환 알고리즘으로는 주로 디피-헬만 키 교환 암호화 알고리즘을 따른다.
디피-헬만 키 교환(Diffe-Helman key exchange) 암호화 알고리즘은 암호키를 교환하는 하나의 방법이다.
간단히 설명하면 처음에 공개 값을 공유하고 각자의 비밀 값과 혼합한 후 혼합 값을 공유 한다. 그리고 각자의 비밀 값과 또 혼합한다. 그 이후 공통의 암호키인 PSK(Pre-Shared Key)가 생성되는 것이다.
이렇게 클라이언트와 서버 모두 개인키와 공개키를 생성하고, 서로에게 공개키를 보내고 공개키와 개인키를 결합하여 PSK가 생성되면, 공격자가 개인키 또는 공개키를 가지고도 PSK가 없기 때문에 정보를 지킬 수 있는 것이다. 디피-헬만 키 교환 암호와 알고리즘에 대한 자세한 정보는 아래를 참고하길 바란다.
https://injae-kim.github.io/dev/2020/08/07/diffie-hellman-algorithm.html
해싱 알고리즘은 데이터를 추정하기 힘든 더 작고, 섞여 있는 조각으로 만드는 알고리즘이다.
해시는 다양한 길이를 가진 데이터를 고정된 길이를 가진 데이터로 매핑한 값을 의미한다.
SHA-256 알고리즘을 예로 들면 해시 함수의 결과값이 256비트인 알고리즘이며 비트 코인을 비롯한 많은 블록체인 세스템에서도 쓰인다. SHA-256 알고리즘은 해싱을 해야 할 메시지에 1을 추가하는 등 전처리를 하고 전처리된 메시지를 기반으로 해시를 반환한다.
"나는 에어컨을 틀고 노트북을 통해 글을 작성하고 있다."라는 글자가 6d3f27096809e2a09075432407b38824ab91f6260edecb2bb3cd951dc64d7851라는 문자열로 변환되는 것이다.
결국 HTTPS에서는 클라이언트와 서버가 키 교환 알고리즘으로 생성한 대칭키(비밀키)와 해싱 알고리즘을 통해 데이터를 암호화하는 것이다.
참고로 TLS 1.3은 사용자가 이전에 방문한 사이트로 다시 방문한다면 SSL/TLS에서 보안 세션을 만들 때 걸리는 통신을 하지 않아도 된다. 이를 0-RTT라고 한다.
이러한 HTTPS를 구축하는 방법은 크게 3가지가 있다. 직접 CA에서 구매한 인증키를 기반으로 HTTPS 서비스를 구축하거나, 서버 앞단의 HTTPS를 제공하는 로드밸런서를 두거나, 서버 앞단에 HTTPS를 제공하는 CDN을 둬서 구축한다.
콘텐츠 전송 네트워크(CDN)는 데이터 사용량이 많은 애플리케이션의 웹 페이지 로드 속도를 높이는 상호 연결된 서버 네트워크이다. CDN은 콘텐츠 전송 네트워크 또는 콘텐츠 배포 네트워크를 의미할 수 있다. 사용자가 웹 사이트를 방문할 때 해당 웹 사이트 서버의 데이터는 사용자의 컴퓨터에 도달하기 위해 인터넷을 통해 이동해야 한다. 사용자가 해당 서버에서 멀리 떨어져 있는 경우 동영상 또는 웹 사이트 이미지와 같은 대용량 파일을 로드하는 데 시간이 오래 걸린다. 대신 웹 사이트 콘텐츠는 지리적으로 사용자와 가까운 CDN 서버에 저장되며 컴퓨터에 훨씬 빨리 도달하게 된다.
5. HTTP/3
TCP 위에서 돌아가는 HTTP/2와는 달리 HTTP/3은 QUIC라는 계층 위에서 돌아가며, TCP 기반이 아닌 UDP기반으로 돌아간다.
QUIS는 TCP의 문제들을 해결하기 위해 구글이 계발한 UDP 기반의 프로토콜이다. TCP를 사용하지 않기 때문에 통신을 시작할 때 번거로운 3 - way handshake를 하지 않아도 된다. 그렇기에 초기 연결 설정 시 지연 시간이 감소되는 장점이 있다. 그리고 멀티플렉싱을 지원해 주기 때문에 HOLB(Head Of LIne Blocking) 문제도 해결해 준다.
클라이언트가 서버에 어떤 신호를 한 번 주고, 서버도 거기에 응답하기만 하면 바로 본 통신을 시작할 수 있는 것이다. 그리고 QUIS는 순방향 오류 수정 메커니즘(FEC, Forword Error Correction)이 적용되어 있다. 이는 전송한 패킷이 손실되었다면 수신 측에서 에러를 검출하고 수정하는 방식이며 낮은 패킷 손실률을 가진다.
그리고 TCP는 워낙 오래전에 설계했다 보니 이런 저런 기능을 추가하다가 헤더는 꽉 차게 되었다.
반면 UDP는 데이터 전송 자체에만 초점을 맞추고 설계되었기 때문에 헤더에 진짜 아무것도 없다.
자세한 내용은 아래를 참고하길 바란다.
참고
면접을 위한 CS 전공지식노트 - 주홍철
https://etloveguitar.tistory.com/137
https://sosoeasy.tistory.com/643
https://ghdwn0217.tistory.com/76
https://injae-kim.github.io/dev/2020/08/07/diffie-hellman-algorithm.html
https://aws.amazon.com/ko/what-is/cdn/
'통신 및 네트워크' 카테고리의 다른 글
SMTP을 사용한 메일 통신은 어떻게 진행되는가?(With POP3, IMAP) (2) | 2024.10.19 |
---|---|
TCP/IP 계층 간단 정리 및 TCP 연결/해제 과정(3-way handshake, 4-way handshake) (0) | 2023.06.10 |
네트워크 성능 분석 명령어 (0) | 2023.06.04 |
프로토콜 - HTTP 에 대한 간단 정리 (0) | 2022.05.07 |
네트워크 관련 기초 용어 (0) | 2022.05.07 |