시리즈
HTTPS
HTTPS란 기존 HTTP
방식에서 보안 계층이 추가된 방식을 의미합니다. 여기서 말하는 보안 계층이란 SSL(Secure Socket Layer), TLS(Transport Layer Security) 프로토콜을 의미합니다.
HTTPS의 탄생 배경
HTTPS
는 기존 HTTP 프로토콜에서 아래와 같은 문제점을 보완하기 위해 도입되었습니다.
- 기존의 HTTP는 암호화되지 않은 평문 데이터로 인해, 인가되지 않은 사용자도 제약 없이 내용을 볼 수 있습니다. (비암호화)
- 기존의 HTTP에서는 요청과 응답에서 통신하는 상대방을 확인하지 않기 때문에, URI에 지정된 호스트인지와 요청한 클라이언트가 맞는지 보장하지 않습니다. (인증문제)
- HTTP는 메시지 위변조에 취약하기 때문에 무결성을 보장하지 않습니다. (무결성)
이러한 암호화, 인증, 무결성 문제들을 해결하기 위해 HTTPS
가 탄생하였습니다. HTTPS는 소켓 통신을 SSL
이라는 암호화 프로토콜을 사용합니다. 현재는 SSL
을 사용하지 않고 대부분 개선된 프로토콜인 TLS
를 사용하고 있습니다.
SSL
넷스케이프사가 개발한 암호화 프로토콜로, SSL 3.0
까지 출시되었습니다. SSL은 HTTP와 독립된 프로토콜으로써 애플리케이션 계층에서 동작하는 다른 프로토콜에서도 사용이 가능하다는 특징을 갖고 있습니다. 공개키 암호화 방식의 암호화 방식을 채택하였습니다.
TLS
SSL 3.0
을 기반으로 한 후속 암호화 프로토콜로, 기존 SSL 방식에서 발생한 취약점과 암호화 방식을 개선하였습니다. 프로토콜의 이름은 다르지만 일반적으로 TLS도 SSL이라고 불립니다. (이 글에서도 편의상 SSL으로 표현하도록 하겠습니다.)
SSL
SSL 암호화 방식
SSL에서는 공통키 암호화 방식
과 공개키 암호화 방식
을 혼합하여 사용합니다. 이 두 가지 암호화 방식은 서로 갖고 있는 키가 동일한지에 따라 구분할 수 있습니다.
공통키 암호화 방식
인코딩할 때 사용하는 키와 디코딩할 때 사용하는 키는 동일한 방식으로 사용되며, 비밀 키를 양쪽(클라이언트-서버)에서 서로 갖고 있습니다. 비밀 키를 갖고 있으면 별다른 절차 없이 디코딩이 가능하기 때문에 디코딩 속도가 빠릅니다. 이 방식의 큰 단점은 비밀 키를 서로 공유해야 한다는 문제입니다.
공개키 암호화 방식
공통키 암호화 방식에서의 문제를 해결하기 위해 등장한 암호화 방식으로, 양쪽에서 서로 다른 두 개의 키 페어를 사용하는 방식입니다. 한쪽은 비밀 키라고 부르고, 다른 한쪽은 공개 키라고 합니다. 공개 키는 외부에서 알아도 괜찮은 키이며, 암호를 보내는 측은 상대의 공개 키를 사용해 인코딩을 수행하고 디코딩을 하는 쪽에서는 비밀 키를 사용해 디코딩을 수행합니다. 공통키 암호화 방식보다 처리 절차가 복잡하기 때문에 속도가 상대적으로 늦는다는 단점이 있습니다.
서버 인증서와 DHE 알고리즘
위에서 설명한 공개키 암호화 방식
역시 100% 안전한 암호화 방식은 아닙니다. 외부 공격자가 공개 키인 척하여 전송을 가로채는 등의 탈취 시도가 가능합니다. 이 문제를 해결하기 위해 인증 기관이 발행하는 서버 인증서와 개선된 알고리즘(DHE 알고리즘)을 현재 활용하고 있습니다.
서버 인증서
특정 인증된 공인 기관(VeriSign 등)은 웹 서버에서 제출한 공개 키에 디지털 서명을 수행하고, 서명이 완료된 인증된 공개 키를 다시 발급해줍니다. 이는 원래 서버의 공개 키와 인증된 공개 키를 활용하여 신뢰성 있는 인증 기관에서 서명되었는지 확인한 후, 더 안전하게 통신할 수 있게 됩니다.
DHE 알고리즘
키를 생성하기 위해 매개변수 방식을 사용하는 알고리즘입니다. 매개변수는 외부에 공개되어도 문제가 없으며, 이러한 매개변수를 활용한 비밀 키 생성 방식을 DH(Diffie-Hellman) 알고리즘이라고 합니다. 여기서 매개변수의 특성을 이용하여 주기적으로 새로운 비밀 키를 생성하는 방식을 추가한 것이 DHE 알고리즘입니다. 이 알고리즘을 사용하면 도중에 생성된 비밀 키가 탈취되더라도 주기적으로 변경되기 때문에 상대적으로 안전하다고 볼 수 있습니다.
SSL 커넥션 과정
SSL 커넥션 과정을 요약하자면, 클라이언트는 먼저 웹 서버의 443 포트(HTTPS 기본 포트)로 연결을 수립하고, 암호법 매개변수와 교환 키를 확인하면서 SSL 계층을 초기화합니다. 이 과정을 SSL 핸드 셰이크(SSL-Hand Shake) 라고 하며, 초기화가 완료된 SSL 계층에 비로소 클라이언트가 요청 메시지를 전송합니다. 전송된 메시지는 TCP 계층에 도달하기 전에 암호화됩니다.
- 웹 서버의 443 포트로 TCP 커넥션 수립
- SSL 보안 매개변수 핸드셰이크 수행
- SSL을 통해 TCP 계층에 암호화된 요청 전송 (클라이언트 → 서버)
- SSL을 통해 TCP 계층에 암호화된 응답 전송 (서버 → 클라이언트)
- SSL 클로징
- TCP 커넥션 클로징
SSL 핸드셰이크
SSL 핸드셰이크는 앞서 말한대로 서버와 클라이언트 간 요청 메시지를 송수신하기전 서로 신원을 인증하기 위한 과정 입니다. 핸드셰이크 단계에서는 아래의 내용을 수행합니다.
- 프로토콜 버전 확인
- 암호화 방식 선택
- 신원 인증
- 채널을 암호화하기 위한 임시 세션 키 생성
DNS
cloudflare.com - DNS Lookup and Webpage Query
HTTP 프로토콜이 속해있는 TCP/IP
에서는 통신 단말 간 IP 주소를 사용하여 데이터를 서로 통신합니다. 일반적으로 웹 서비스를 이용하기 위해서 URL을 입력하는데 내부적으로 호스트 URL에 대응하는 IP 주소를 획득하는 절차가 수행합니다. 이 작업을 바로 DNS가 수행하고 있습니다.
DNS 서버
DNS를 사용하려면 별도의 DNS 서버가 필요로합니다. DNS 서버에 미리 호스트명과 IP 주소의 대응 관계와 여러 정보들을 입력해두고, 실제 웹 서비스를 구성한 호스트에서 해당 DNS 서버의 IP 주소를 설정해둡니다. 이때, DNS 서버에 등록하는 정보들을 DNS 레코드라고 합니다.
웹 서비스를 사용자가 URL을 입력하면 자동으로 DNS 서버에 해당하는 IP 주소를 질의합니다. 이 부분은 OS에 기본적으로 내장되어 있는 기능(DNS 리졸버)입니다. DNS 서버는 계층 구조로 되어 있어서 루트에서부터 질의를 반복하여 IP 주소를 찾아갑니다.
DNS 조회 절차
- 사용자가 웹 브라우저에 URL을 입력하면 DNS 리졸버가 이를 수신합니다. (jinyisland.kr)
- DNS 리졸버가 DNS 루트 서버 이름(.)을 질의합니다.
- DNS 루트 서버가 도메인에 대한 정보를 저장하는 최상위 도메인 DNS 서버 (.kr)의 주소로 리졸버에 응답합니다. (최상위 도메인을 Top-Level-Domain, TLD라고 합니다.)
- 리졸버가 최상위 주소 TLD 서버에 질의를 하고, TLD 서버는 도메인 이름 서버의 IP 주소를 응답해줍니다.
- DNS 리졸버가 응답 받은 도메인의 이름을 DNS 서버에 전송합니다.
- DNS 서버에서 요청 받은 도메인 이름과 대조해 IP 주소를 응답합니다.
- 최종적으로 응답한 IP 주소를 가지고 브라우저가 HTTP 요청을 수행해 웹 페이지 및 응답 데이터들을 수신합니다.
주요 DNS 리소스 레코드
DNS 서버에는 다음과 같은 정보를 등록합니다.
레코드 명 | 의미 |
---|---|
A | 호스트명에 대응하는 IPv4 주소 |
AAAA | 호스트명에 대응하는 IPv6 주소 |
CNAME | 호스트명에 대응하는 별칭 |
MX | 도메인명에 대응하는 메일 서버 |
NS | 도메인명을 관리하는 DNS 서버 |
PTR | IP 주소에 대응하는 호스트명 |
DNS 질의
DNS 서버는 루트를 정점으로 계층 구조로 이루어져 있어 하위로 내려가면서 IP 주소를 얻기 위해 재귀적으로 각 각 DNS 서버에 묻는데 이를 DNS 질의라고 합니다. 크게 세 가지 종류의 DNS 질의가 존재하며, 여러 질의를 조합하여 최적화된 프로세스를 통해 질의 시간을 단축시킵니다.
재귀 질의
DNS 리졸버가 레코드를 찾을 수 없는 경우, DNS 서버가 요청한 자원 레코드 또는 오류 메시지를 통해 클라이언트에게 응답하도록 요청합니다.
반복 질의
클라이언트가 DNS 서버에게 가장 상위 계층의 응답을 반환하도록 요청합니다. 일치하는 레코드가 없는 경우, 해당 DNS 서버는 권한을 가진 하위 계층의 DNS 서버에 요청합니다. 오류 또는 시간 초과가 발생할 때까지 반복적으로 질의합니다.
비재귀 질의
클라이언트로부터 질의를 받은 DNS 서버가 해당 레코드에 대한 권한이 있거나 해당 레코드를 갖고 있는 경우에 발생합니다. DNS 서버의 부하를 방지하기 위해 일시적으로 레코드들을 캐시합니다.
UDP
UDP는 전송 계층 내에서 데이터를 적절한 애플리케이션에 분배하는 역할을 담당하는 프로토콜입니다. TCP
와 다르게 상대측 애플리케이션의 동작 여부등을 확인하지 않고 UDP 데이터그램을 통해 전송만 하기 때문에 TCP 보다 전송 효율이 높다는 장점이 있습니다. (반대로 신뢰성을 보장하지 않습니다.)
UDP의 경우 상대방 애플리케이션에 데이터가 정상적으로 수신되었는지 확인하는 기능이 없기 때문에 애플리케이션 영역에서 별도의 기능을 추가해야합니다.
UDP의 특징
- UDP는 손실된 데이터에 대한 복구, 플로우 컨트롤 등 별도의 작업을 수행하지 않으므로 전송 속도가 빠릅니다. (실시간 스트리밍, 화상 통화등에 적합)
- 불완전한 데이터도 전송할 수 있습니다.
- 브로드캐스트와 멀티캐스트 전송이 가능하므로 한 번에 여러 수신자에게 데이터를 전송할 수 있습니다.
- 비연결방식이기 때문에 TCP에 비해 안정적이지 않습니다.
UDP 헤더
UDP Header
UDP 헤더에는 출발지 포트 번호, 도착지 포트 번호, 데이터 그램 길이, 체크섬 등의 정보가 각각 16비트씩 할당되어 있으며 데이터 패킷에 UDP 헤더를 추가하여 전송됩니다. 이러한 데이터를 데이터 그램이라고 합니다. 여기서 체크섬(checksum)
은 데이터 변형에 대한 유무를 확인하기 위한 필드 입니다. 선택에 따라 체크섬을 수행하지 않게 할 수도 있습니다.
checksum
체크섬은 1의 보수를 활용하여 전송 데이터를 16비트 단위로 구분하여 각각의 합을 계산하고, 송신측과 수신측에서 대조하여 오류를 검출하는 방식입니다. UDP에서는 체크섬에서 가상 헤더(발신지, 수신지 IP 주소 및 프로토콜 등을 포함)를 포함하여 계산하는데 이유는 수신 호스트 내에 어떤 포트인지에 대한 정보도 검사해야 하므로 실제 헤더 및 가상 헤더까지 포함한 전체 패킷에 대해 검사합니다.
신뢰적 데이터 전송
전송 계층에서는 데이터 전송을 위해 여러 방식의 프로토콜을 사용합니다. 핵심은 데이터 패킷이 올바르게 송신 및 수신되고 손실되지 않도록 하는 것입니다. 이를 위해 여러 프로토콜이 개발되었으며, 이 중 몇 가지를 소개하겠습니다.
전송 후 대기 프로토콜
전송 후 대기 프로토콜(Stop and Wait Protocol)은 송신자가 데이터를 송신 후 대기하고, 수신자가 전송을 승인할 때 까지 기다리는 방식의 프로토콜 입니다. 단일 데이터 패킷 단위로 데이터를 송신하고 수신자가 데이터를 수집한 뒤 플래그 값을 송신자에게 전송하는 방식으로 동작합니다.
이 프로토콜의 특징은 약속된 규칙에 따라 순서대로 전송과 응답을 수행하며, 상태에 따라 확인 플래그(ACK, NAK)에 맞춰 재전송 여부를 처리하는 간단한 구현 방식입니다. 그러나 데이터 패킷 손실로 인한 상황이나 데이터 지연으로 인한 상황에서 문제가 발생할 수 있다는 단점이 있습니다.
파이프라인 프로토콜
단일 데이터 패킷 단위로 송신 후 수신측에서의 승인을 기다리는 방식과는 달리 여러 데이터패킷을 연속적으로 전송하는 프로토콜 입니다. 전송 할 데이터의 양이 많을 때 효율적이며 수신측에서의 데이터 확인 유무를 기다리지 않는다는 특징이 있습니다. 파이프라인 방식을 사용하는 프로토콜은 대표적으로 Go-Back-N
과 Selective Repeat
프로토콜이 있습니다.
Go Back N Protocol educative.io - resending new window after timeout
먼저 송신자와 수신자가 약속된 패킷의 일정한 크기(윈도우)를 확인한 후, 다수의 데이터 패킷들을 전송하는 방식입니다. 만약 중간에 실패한 패킷이 있다면, 수신측은 시퀀스 번호 순서에 따라 다음의 패킷을 응답하지 않고 발신자의 재전송 타이머가 만료되면 실패한 데이터 패킷부터 다시 재전송합니다. 패킷 손실이 많을수록 전송 효율이 급격히 떨어집니다.
Selective Repeat Protocol
educative.io - resending 2nd packet and delivering whole window
Go Back N
과 마찬가지로 슬라이딩 윈도우 방식을 사용합니다. 손실된 데이터 패킷 재전송에서 선택적으로 재전송하는 특징을 갖고 있으며, 나머지 부분들은 동일합니다.