[혼공네] 5장 응용 계층

5-1. DNS와 자원

도메인 네임과 네임 서버

네트워크상의 호스트를 특정하기 위해 IP 주소를 사용하지만, 통신하는 모든 호스트의 IP 주소를 기억하기도 어렵고, 호스트의 IP 주소는 언제든지 바뀔 수 있어 IP 주소만을 사용하기에는 번거롭습니다. 그래서 일반적으로 사용자는 IP 주소보다는 도메인 네임을 많이 사용합니다.

  • 도메인 네임 : 호스트 IP 주소와 대응되는 문자열 형태의 호스트 특정 정보.

도메인 네임과 IP 주소는 네임 서버에서 관리하고, 도메인 네임을 관리하는 네임 서버를 DNS 서버라고 부릅니다.

도메인 네임의 계층적 분류

도메인 네임은 점(”.”)을 기준으로 계층적으로 분류됩니다. 최상단에 루트 도메인(.), 그 다음 최상위 도메인(TLD), 2단계 도메인처럼 계속 그 다음 단계의 도메인이 있는 식입니다. 도메인 네임을 모두 포함하는 도메인 네임을 전체 주소 도메인 네임(FQDN) 이라고 합니다.
도메인 네임이 이렇게 계층적인 형태를 띄는데, 이를 효율적으로 관리하기 위해서 네임 서버 또한 계층적인 형태를 하고 있습니다. 해당 네임 서버는 전 세계 여러 군데에 위치해 있습니다. 이렇게 계층적이고, 분산된 도메인 네임 관리 체계를 도메인 네임 시스템(DNS)라고 부릅니다.

계층적 네임 서버

IP 주소를 모르는 상태에서 도메인 네임에 대응되는 IP 주소를 알아내는 과정에 대해서 알아보겠습니다.

중요한 역할을 담당하는 네임서버는 크게 로컬 네임 서버, 루트 네임 서버, TLD 네임 서버, 책임 네임 서버 4가지가 존재합니다. 

https://jaehyeon48.github.io/network/dns/

1. 로컬 네임 서버

클라이언트와 맞닿아 있는 네임 서버로 IP 주소를 알아내기 위해 가장 먼저 찾는 네임 서버입니다. 일반적으로 ISP(Internet Service Provider)에서 할당해주는 경우가 많지만, ISP에서 할당하는 로컬 네임 서버 말고도 공개 DNS 서버(EX : 구글 DNS 서버 8.8.8.8)도 사용 가능합니다.

2. 루트 네임 서버

로컬 네임 서버가 IP 주소를 모르는 경우, 루트 네임 서버에게 해당 도메인 네임을 질의하게 됩니다. 루트 네임 서버는 루트 도메인을 관리하는 네임 서버로 질의에 대해 TLD 네임 서버의 IP 주소를 반환 할 수 있습니다.

3. TLD 네임 서버

TLD(최상위 도메인)을 관리하는 네임 서버입니다. 질의에 대해 TLD의 하위 도메인을 관리하는 네임 서버 주소를 반환할 수 있습니다.

4. 책임 네임 서버

특정 도메인 영역을 관리하는 네임 서버로, 자신이 관리하는 도메인 영역의 질의에 대해서는 다른 네임 서버에게 떠넘기지 않고, 답할 수 있는 네임 서버입니다. 즉, 책임 네임 서버는 로컬 네임 서버가 마지막으로 질의하는 네임 서버입니다.

도메인 네임 리졸빙

도메인 네임에 해당하는 IP 주소를 알아내기 위해 리졸빙하는 과정에 대해서 알아보겠습니다. IP주소를 알기 위해 로컬 네임 서버는 다른 네임 서버들에게 질의하게 되는데, 크게 '재귀적 질의'와 '반복적 질의' 2가지 방식으로 질의를 진행합니다.

재귀적 질의 (Recursive Query)

재귀적 질의 방식

클라이언트가 로컬 네임 서버에게 도메인 네임을 질의하면, 로컬 네임 서버 → 루트 네임 서버 → TLD 네임 서버 → 책임 네임 서버 순으로 질의하고, 역순으로 최종 응답 결과를 전달받는 방식입니다.

반복적 질의 (Iterative Query)

반복적 질의

클라이언트가 로컬 네임 서버에게 도메인 네임을 질의하면, 로컬 네임 서버가 루트 네임 서버에게 질의해서 다음 질의할 TLD 네임 서버 주소를 응답 받고, 로컬 네임 서버가 TLD 서버에게 질의해서 다음 질의할 책임 네임 서버 주소를 응답 받고, 로컬 네임 서버가 책임 네임 서버에게 질의 과정을 반복하는 걸 반복적 질의라고 합니다.

앞서 설명한 2가지 질의 방식에서는 IP로 변환하기 위해 8가지 단계를 거쳐야하는 것 처럼 시간이 오래 걸리고, 네트워크 상의 메시지 수가 지나치게 늘어날 수 있습니다.
그래서 실제로는 네임 서버들이 기존에 응답받은 결과를 DNS 캐시에 임시로 저장했다가 추후 같은 질의에 이를 활용할 수 있습니다. DNS 캐시는 영원히 남아있지 않으며, TTL(Time To Live)이라는 값에 따라 캐시 될 수 있는 시간 이후 소멸합니다.

자원을 식별하는 URI

 

지금까지는 클라이언트가 메시지를 주고받고자 하는 대상의 IP 주소를 식별하는 방법을 설명했다면, 송수신하고자 하는 정보를 식별하기 위한 URI에 대해서 알아보겠습니다. 두 호스트가 송수신하는 대상(자원)을 식별할 수 있어야하는데, 자원을 식별할 수 있는 정보를 URI(Uniform Resource Identifier)라고 부릅니다.

URI위치 기반 식별자인 URL과 이름 기반 식별자인 URN 2가지 방식으로 자원을 식별합니다.

URL (Uniform Resource Locator)

Scheme
URL의 첫 부분으로, '자원에 접근하는 방법'을 의미합니다. 일반적으로는 사용할 프로토콜이 명시됩니다.(ex:http://, https:// )
Authority
Authority에는 '호스트를 특정할 수 있는 정보'인 IP주소나 도메인 네임이 명시됩니다. 콜론(:) 뒤에 포트 번호를 붙일 수 있습니다.
Path
path에는 '자원이 위치한 경로'가 명시됩니다. 슬래시(/)를 기준으로 자원의 경로를 계층적으로 표현합니다.
Query
자원의 위치(path) 뿐만 아니라 다른 특정 조건을 추가할 때 query를 이용합니다. (ex: 쿼리 문자열, 쿼리 파라미터)
Fragment

자원의 한 조각을 가리키기 위한 정보로,  HTML파일과 같은 자원에서 특정 부분을 가리키거나 이동하기 위해 사용합니다.

URN(Uniform Resource Name)

URL은 자원의 위치를 기반으로 식별하는데, 자원의 위치는 언제든지 변할 수 있습니다. URN은 자원에 고유한 이름을 붙이는 이름 기반 식별자이기 때문에 자원의 위치와 무관하게 식별할 수 있다는 장점이 있습니다.

DNS 레코드 타입

DNS가 올바르게 동작하기 위해 네임 서버가 무엇을 저장하는 지 알아보겠습니다.
네임 서버는 DNS 자원 레코드(DNS 레코드)라 불리는 정보를 저장하고 관리합니다.

도메인 구입 후 해당 도메인 주소를 IP 주소에 대응시키고자 한다고 하면, 도메인 네임 서버에 등록을 해야합니다. 이때 도메인 레코드 마다 공통으로 유지하는 정보인 호스트 이름(Record Name), 값(Value), TTL, Record Type 등을 설정해야 합니다. 각 레코드에는 유형이 정해져 있기에 레코드 유형이 달라지면 레코드의 이름과 값이 달라집니다.

레코드 유형 설명
A 특정 호스트에 대한 도메인 네임과 IPv4 주소와의 대응 관계
AAAA 특정 호스트에 대한 도메인 네임과 IPv6 주소와의 대응 관계
CNAME 호스트 네임에 대한 별칭을 지정
NS 특정 호스트의 IP 주소를 찾을 수 있는 네임 서버
MX 해당 도메인과 연동되어 있는 메일 서버

다음과 같은 도메인 레코드가 있다고 가정하고, 해당 레코드의 의미를 해석해보겠습니다.

레코드 타입 이름 TTL
A example.com 1.2.3.4 300
CNAME www.example.com example.com 3000

첫 번째 레코드(A)의 의미를 해석하면 exampel.com이 1.2.3.4에 대응되어 있다는 것을 보여줍니다. 그래서 네임 서버에 example.com을 질의하면 1.2.3.4을 응답 받을 수 있습니다.
두번째 레코드(CNAME)의 의미를 해석하면 example.com에 대한 별칭으로 www.example.com을 사용하겠다는 의미입니다. 그래서 CNAME을 등록해서 www.exmaple.com을 질의하면 1.2.3.4 을 응답 받을 수 있습니다.

5-2. HTTP(Hypertext Transfer Protocol)

HTTP의 특성

1. 요청-응답 기반 프로토콜

HTTP클라이언트-서버 구조 기반의 요청-응답 프로토콜로, 요청 메시지와 응답 메시지를 주고 받는 구조로 동작함.

2. 미디어 독립적 프로토콜

HTTP주고받을 자원의 특성을 제한하지 않고, 단지 자원을 주고 받을 수 있는 인터페이스를 정의합니다. 그래서 HTTP를 통해서 HTML, JPEG, PNG, JSON, XML, PDF 등 다양한 종류의 자원을 주고 받을 수 있습니다.
HTTP에서 메시지로 주고받는 자원의 종류를 미디어 타입, MIME 타입 이라고 부릅니다. 미디어 타입은 type/subtype의 형태로 구성됨.

3. Stateless 프로토콜

HTTP상태를 유지하지 않는 프로토콜로, 서버가 클라이언트와 관련된 상태를 기억하지 않습니다. 따라서 모든 HTTP 요청은 독립적인 요청으로 간주됩니다.
HTTP 서버는 다수의 클라이언트와 동시에 상호 작용하므로, 모든 클라이언트의 상태 정보를 유지하는 것은 비효율적입니다. 뿐만 아니라 서버가 한 대가 아니라 여러 대의 서버로 구성된 경우, 모든 서버에서 클라이언트의 상태를 공유하기 어렵습니다. 
HTTP의 중요 설계 목표는 확장성(Scalability)과 견고성(Robustness)인데, Statless 특성을 통해 확장성이 높고, 견고성이 높을 수 있었습니다.

4. 지속 연결 프로토콜

기본적으로 HTTP는 TCP 상에서 동작합니다. TCP는 연결형 프로토콜이지만, HTTP는 비연결형 프로토콜입니다.
따라서 초기의 HTTP(HTTP/1.0)에서는 요청을 처리할 때마다 TCP의 3-way Handshake를 통해 연결을 수립한 뒤, 요청과 응답이 한 번 오고 가면 즉시 연결을 종료했습니다. 추가 요청이 있을 경우 매번 연결을 생성하고 종료해야 했고, 불필요한 네트워크 오버헤드가 반복되어 비효율적이라는 문제가 있었습니다.

최근 HTTP 버전(HTTP 1.1 이상)에서는 지속 연결(Keep-alive)이라는 기술을 제공하는데, 해당 기술을 통해 하나의 TCP 연결 상에 여러 개의 요청-응답을 주고 받을 수 있습니다.

HTTP 메시지 구조

HTTP 메시지는 시작 라인, 필드 라인, 메시지 본문으로 이루어져 있습니다.

https://developer.mozilla.org/en-US/docs/Web/HTTP/Guides/Messages

시작 라인

시작 라인은 요청 메시지(요청 라인)인지 응답 메시지(상태 라인)인지를 나타내는 부분입니다.

요청 라인인 경우, 요청 라인 = 메서드 + 요청 대상 + HTTP 버전 으로 구성되고,  상태 라인인 경우, 상태 라인 = HTTP 버전+ 상태 코드 + 이유 구문(선택) 구성됩니다.

필드 라인

필드라인은 0개 이상의 HTTP 헤더(HTTP 통신에 필요한 부가 정보)가 명시되는 부분으로, 각 HTTP 헤더는 “:”을 기준으로 헤더 이름과 하나 이상의 헤더 값으로 구성됩니다.

메시지 본문

HTTP 요청 혹은 응답 메시지에서 본문이 필요한 경우에 명시되는 값으로, 존재하지 않을 수도 있고, 다양한 콘텐츠 타입이 사용될 수 있습니다.

HTTP 메서드

HTTP 상태 코드

  • 200번대 : 성공 상태 코드
  • 300번대 : 리다이렉션 상태 코드
  • 400번대 : 클라이언트 에러 상태 코드
  • 500번대 : 서버 에러 상태 코드

5-3. HTTP 헤더와 HTTP 기반 기술

HTTP 헤더

HTTP 메시지의 2번째 줄인 필드 라인에 대해서 학습하겠습니다. 필드 라인은 다양한 HTTP 헤더들이 명시됩니다. 해당 HTTP 헤더의 종류는 매우 많기 때문에 자주 활용되는 HTTP 헤더 위주로 학습해보겠습니다.

요청시 활용되는 HTTP 헤더

HTTP 요청시 주로 활용되는 대표적인 헤더 'Host', ' User-Agent', 'Referer', 'Authorization' 헤더에 대해서 알아보겠습니다.
(1) Host
- 요청을 보낸 호스트를 나타내는 헤더로, 주로 도메인 네임으로 명시됩니다.

(2) User-Agent
- 요청 메시지 생성에 관여한 클라이언트 프로그램과 관련된 다양한 정보가 명시됩니다. (ex: OS, 브라우저 등)

(3) Referer
- 클라이언트가 요청을 보낼 때 머무르고 있던 URL로, 클라이언트의 유입 경로를 파악할 수 있습니다.

(4) Authorization
- 클라이언트의 인증 정보를 담는 헤더로, 인증 타입과 인증 정보가 차례로 명시 됩니다.

응답시 활용되는 HTTP 헤더

HTTP 응답 시 주로 활용되는 대표적인 헤더 'Server', 'Allow', 'Retry-After', 'Location', 'WWW-Authenticate' 헤더에 대해서 알아보겠습니다.
(1) Server
- 요청을 처리하는 서버 측의 소프트웨어와 관련된 정보를 명시합니다.

(2) Allow
- 클라이언트에게 허용된 HTTP 메서드 목록을 알려주기 위해 사용됩니다. 

(3) Retry-After
- 현재는 요청을 처리할 수 없을 때 503(Service Unavailable) 상태 코드와 함께 전송되는 정보로, 자원을 사용할 수 있는 날짜/시각을 나타냅니다.

(4) Location
- 클라이언트에게 자원의 위치를 알려주기 위해 사용되는 헤더입니다.

(5) WWW-Authenticate
- 자원에 접근하기 위한 인증 방식을 설명하는 헤더입니다.

캐시 (Cache)

불필요한 대역폭 낭비와 응답 지연 방지를 위해 정보의 사본을 임시로 저장하는 기술입니다. 사본을 저장해두면 동일한 요청에 대한 캐시된 데이터를 활용해 빠르게 데이터에 접근할 수 있습니다.

  • 개인 전용 캐시 : 웹 브라우저에 저장
  • 공용 캐시 : 클라이언트와 서버 사이에 위치한 중간 서버에 저장

캐시에서 주의할 점은 원본 데이터가 변경되는 상황이 있을 수 있으므로 클라이언트가 확보한 캐시된 데이터가 최신 상태인지 확인해야합니다. 이를 위해 캐시된 데이터에 유효 기간 설정하고, 유효 기간이 만료됐을 때 원본 데이터를 다시 요청하는 방식으로 최신성을 유지합니다.

쿠키 (Cookie)

서버에서 생성되어 클라이언트 측에 저장되는 데이터로, 상태를 유지하지 않는 HTTP의 특성을 보완하기 위한 수단입니다.
서버가 클라이언트의 상태를 알 수 있도록 하는 특별한 데이터로 서버가 생성하여 클라이언트에게 전송하고, 클라이언트는 전달받은 쿠키를 저장해 두었다가, 서버에게 보내는 요청 메시지에 쿠키를 포함하여 전송합니다.