서버와 클라이언트가 인터넷상에서 데이터(이미지, 텍스트 등)를 주고 받기 위한 프로토콜
TCP/IP 기반
의 응용 프로토콜이다.
client - server
구조로 이루어져 있다.
비연결성(stateless)
프로토콜이다.
80 port
번호를 사용한다.안정적인 연결과 데이터 전송을 보장한다
텍스트 기반의 프로토콜이며, 메서드/헤더/본문
으로 구성되어 이해하기 쉽다.
서버 확장에 용이하다
트래픽이 많지 않고, 빠른 응답을 제공해야 하는 경우 효율적이다.
요청마다 연결을 새로 맺는다 -> 매번 TCP 3-way handshake(느림) -> 트래픽이 많지 않은 경우에 효율적이다.
텍스트 기반의 단순한 요청/응답 구조 -> 파싱 및 처리 속도 빠름 -> 빠른 응답
데이터를 상태를 보존해야 하는 경우에는 토큰이나 쿠키, 세션 등을 이용하는 등 별도의 처리가 필요하다
요청마다 TCP 3-way handsake가 필요하기 때문에, 실시간 서비스에 적합하지 않다.
-> websocket 등 별도의 프로토콜이 필요한 경우가 많다.
기본적으로 http request는
start line
,header
,body
로 구성된다.
start line에는 다음과 같은 데이터들이 포함되어 있다.
HTTP Method
Request target (uri)
HTTP Version
(1.0, 1.1, 2.0 등)
request에 대한 대략적인 정보를 담고 있다.
ex) accept
, host
, content-type
등
요청하고자 하는 데이터의 내용
이 담겨있다.
물론 GET 요청의 경우 body를 사용하지 않는다. 주로 POST/PUT 요청과 같이 데이터를 전송하는 목적의 메서드에서 body에 데이터를 담아서 전송한다.
http response도 마찬가지로
start line
,header
,body
로 구성된다.
request와 다른 특징만 짚어보자.
status code(상태 코드)
와 status text(상태 설명)
가 존재한다.가장 많이 사용되는 HTTP Method는
GET
과POST
이다.
멱등성을 가지지 않는다. (리소스가 중복 생성된다)
'이 리소스에 어떤 메서드를 사용할 수 있는지'
를 물어보는 용도이다.주로 CORS 요청 시, 사전 요청(preflight request)을 보낼때
이 메서드가 사용된다.HTTP Status Code는 앞자리마다 대략적인 의미를 가지고 있으며, 개발자가 코드로 직접 status code를 지정할 수 있다.
프로젝트를 진행하면서는 주로 2xx, 4xx, 5xx를 많이 사용했었다.
200 OK
→ 일반적인 성공 응답
201 Created
→ 새 리소스가 생성됨 (주로 POST에서 사용)
→ 물론 200번 응답을 POST에서 사용할 수 있지만, 요청에 대한 결과를 명확하게 전달하기 위해 201를 사용하는 것이 권장된다.
204 No Content
→ 성공했지만 반환할 데이터가 없음 (ex. DELETE에 대한 응답)
리소스 위치 변경 등으로 클라이언트가 다른 URL로 요청해야 한다.
301 Moved Permanently
→ 리소스가 영구적으로 이동됨, 브라우저가 자동 리디렉션
302 Found (또는 Temporary Redirect)
→ 임시적으로 다른 위치로 이동
클라이언트의 잘못된 요청에 대한 응답이다.
400 Bad Request
→ 잘못된 문법, 파라미터 누락, 타입 오류 등
401 Unauthorized
→ 인증 필요 (토큰 누락, 로그인 안 됨 등)
403 Forbidden
→ 접근 권한 없음 (해당 리소스에 대한 권한 없음)
404 Not Found
→ 요청한 리소스가 없음 (URL 오타 등)
405 Method Not Allowed
→ 지원하지 않는 HTTP 메서드
서버 내부 문제로 인한 오류 응답이다.
500 Internal Server Error
→ 서버 내부 에러 (NPE 등)
502 Bad Gateway
→ 게이트웨이/프록시가 잘못된 응답을 받은 경우
이전에 정리한 내용 (HTTPS와 연결 과정)
HTTP 요청을 SSL 혹은 TLS라는 알고리즘을 이용하여 데이터를 암호화하여 전송하는 방법
HTTP와 달리 중간에 암호화 계층(6L)을 거쳐서 패킷을 암호화
하기 때문에, 중간에 패킷을 가로채더라도 데이터를 확인할 수 없다.
1. 암호화 (데이터 암호화 -> 중간에 데이터를 탈취해도 내용을 알아볼 수 없음)
HTTPS에서는 client와 server가 데이터를 암호화하여 주고받기 위해 비대칭키 방식
과 대칭키 방식
을 혼용하여 사용한다.
대칭키 방식
: 서버와 클라이언트가 통신할 때, 양쪽이 공통의 비밀 키를 공유하여 데이터를 암호화 및 복호화하는 것
비대칭키 방식
: 각각 공개키와 비밀키를 가지고, 상대가 나의 공개키로 암호화한 데이터를 개인이 가진 비밀키로 복호화하는 것
비대칭키 알고리즘은 대칭키보다 훨씬 복잡하기 때문에, 대칭키를 사용하여 데이터를 암호화 및 복호화하는 것이 서버에 부담을 덜 준다. 따라서 클라이언트와 서버가 데이터를 주고받을 때는 대칭키를 사용한다.
하지만 대칭키를 서로 주고받는 과정에서부터 정보가 탈취될 수 있기 때문에, HTTPS는 대칭키를 주고받을 때는 비대칭키 방식
으로 주고받는다. 앞서 말했듯, 비대칭키는 공개키로 암호화한 정보는 개인이 가진 비밀키로만 풀 수 있으므로 중간에 대칭키가 탈취되더라도 개인키가 없이는 이를 복호화할 수 없기 때문이다.
2. 인증서 - 데이터 제공자 신원보장, 도메인 종속
HTTPS에서는 브라우저가 서버의 응답과 함께 전달된 인증서를 확인할 수 있다. 이러한 인증서는 서버의 신원을 보증해준다. 이때 이를 보증할 수 있는 제 3자를 CA(Certificate Authority)
라고 부른다.
CA(Certificate Authority)
: 인증서를 발급해주는 엄격하게 공인된 기관들.웹사이트의 인증서를 확인해보면, 인증서를 발급한 CA, 서명에 사용한 알고리즘, 서명, 공개 키 정보 등이 들어있는 것을 확인할 수 있다.
인증서가 CA의 비밀키로 암호화되어 있으므로 CA의 공개키로 복호화 가능하기 때문에, 해당 CA에서 발급한 인증서라는 것을 보증할 수 있다.
1-1. client hello
클라이언트가 최초 서버에 요청을 보내는 것이다.
이때, 클라이언트에서 생성한 랜덤 데이터
, 클라이언트가 사용할 수 있는 암호화 방식
등을 보낸다.
만일 이전에 handshaking 기록이 있다면, 기존 세션을 활용하기 위한 session ID
를 보낸다.
1-2. server hello, 공개키/인증서 정보 전달
서버가 클라이언트의 요청에 대한 응답으로써, 공개키가 포함된 인증서를 비밀키로 암호화하여 전달
한다.
이때, 서버에서도 랜덤 데이터
와 서버가 선택한 클라이언트의 암호화 방식
을 함께 보낸다.
1-3. client의 서버 인증서 검증
클라이언트는 서버의 인증서를 통해 서버가 신뢰할 수 있는지 판단한다.
이때, 클라이언트의 웹 브라우저에는 서버의 인증서가 신뢰할 수 있는지 확인하기 위해 '신뢰할 수 있는 인증서' (공개 키)
가 미리 등록되어 있다.
이 '신뢰할 수 있는 인증서' 목록에는 Root CA의 인증서, ICA의 인증서 등이 포함되어 있다.
전 세계에 배포된 공개키로 복호화할 수 있다면, 인증 기관이 가지고 있는 비밀키로 암호화된 인증서라는 것이 입증되기 때문에, 신뢰할 수 있다고 판단하는 것이다.
1-4. client의 대칭키와 세션키 생성 후 서버에 전달
client는 데이터 암호화에 사용할 대칭키(비밀키)를 생성
한 후, server가 발행한 공개키를 이용해 암호화하여 server에 전달한다.
여기서의 대칭키가 데이터를 실제로 암호화할 대칭키(비밀키)이다.
1-5. 서버의 인증 확인
서버는 전달받은 대칭키를 자신이 가지고 있는 비밀키로 복호화하여 대칭키를 얻는다.
세션키를 생성한다.
DNS는 웹사이트의 도메인 주소를 IP 주소로 변환하는 시스템이다.
클라이언트-서버 모델
을 이용하는 분산 계층형 데이터베이스 시스템이다.CNAME(별칭 도메인)
DNS는 IP 주소 또는 도메인을 여러 별칭 도메인과 연결시켜준다.
별칭 도메인을 CNAME(Canonical Name) 레코드로 등록하면, 해당 별칭 도메인 주소를 통해 같은 웹사이트에 접속할 수 있게 된다.
예를 들어, www.example.com
과 example.com
을 같은 주소로 접속하도록 할 때 사용된다.
로드 밸런싱
분산 서비스 환경에서는 DNS가 간단한 로드 밸런싱 역할을 수행할 수도 있다.
예를 들어, AWS의 DNS 서비스인 Route53은 여러 서버의 IP를 등록해 두고 라운드로빈, health check 기반 트래픽 분산과 같은 DNS 레벨의 로드 밸런싱 기능을 제공한다.
확보한 도메인 영역에서 도메인 네임 생성 (ex. www.naver.com)
Domain Name Space는 Domain Name을 중복 사용되지 않도록 구성되어있다. (트리 구조)
네임 서버 (Name Server)
도메인의 데이터를 보유하고, 외부 인터넷으로부터 Domain Name과 그에 대한 데이터 질의를 수신했을때, 보유한 데이터를 검색하여 조회하고 응답하는 역할을 담당
Root Name Server
TLD(Top-Level Domain) Name Server
권한 있는 네임서버 (Authoritative Name Server)
Recursor (Recursive Resolver)
Domain Name의 데이터 조회 기능을 수행
DNS 서버들에 질의를 하며 응답을 찾아오는 재귀 질의 처리 서버.
사용자 요청을 받아서 루트 → TLD → 권한 네임서버까지 직접 쿼리
DNS는 스마트폰 또는 컴퓨터와 같은 클라이언트에서 DNS 쿼리가 들어오면, DNS 리커서(Recursor)가 클라이언트 대신 서버에 쿼리를 보내서 도메인 이름과 연결된 IP 주소를 확인
한다.
이때, DNS 쿼리는
반복적(Iterarive) 또는 재귀적(Recursive) 질의로 진행
된다.
둘 다 도메인 이름을 IP 주소로 바꾸기 위한 방식이지만, 도메인을 IP로 변환할 때 누가 얼마나 책임지고 찾아주느냐의 차이로, 동작 방식이 조금 다르다.
반복적 질의는 DNS Resolver(클라이언트)가 각 계층 서버에 순차적으로 쿼리를 보내서 IP 주소를 찾는 과정이다.
반면, 재귀적 질의는 DNS Recursor가 root 서버에 쿼리를 한 번만 보내면,
root 서버 -> TLD 서버 -> 권한 서버
순으로 쿼리를 보낸다.
권한 서버에 확인되는 최종 IP 주소도 각 계층을 거쳐 루트 서버로 최종적으로 응답되고, root 서버 -> DNS Recursor -> resolver(클라이언트) -> 브라우저 순으로 응답이 전달된다.
항목 | 반복적 질의 (Iterative) | 재귀적(Recursive) 질의 |
---|---|---|
탐색 주체 | 클라이언트(Resolver) | DNS 서버(Recursor) |
클라이언트 부담 | 높음 | 낮음 |
일반 사용자 환경 | ❌ 보통 서버 간 통신에 사용 | ✅ 많이 사용 |
성능 | 빠름 | 느림 (서버가 직접 찾아야 하므로) |
질의 방식 | 사용 주체 | 사용 상황 | 특징 |
---|---|---|---|
재귀적 질의 (Recursive) | 클라이언트 → Recursor | 일반 사용자 환경 (브라우저, 앱 등) | Recursor가 최종 IP까지 찾아줌 |
반복적 질의 (Iterative) | Recursor → Root/TLD/권한 DNS | DNS 서버 간 통신 시 | 상위 DNS 서버는 다음 서버만 알려줌 |
사용자가 브라우저에 www.example.com 입력
클라이언트(Resolver)가 로컬 DNS 캐시에 IP가 있는지 확인
없으면 재귀 DNS 서버(Recursor)에 질의
Recursor가 다음 순서로 질의함:
✅ 루트 DNS 서버 → ".com"의 TLD 서버 알려줌
✅ TLD DNS 서버 → "example.com"의 권한 DNS 서버 알려줌
✅ 권한 DNS 서버 → www.example.com의 IP 주소 응답
Recursor가 IP 주소를 클라이언트에게 전달