Skip to content

HTTPS 원리와 설정 방법

giantim edited this page Sep 15, 2020 · 5 revisions

HTTP를 먼저 알아보자

HTTPS는 SSL(Secure Socket Layer)을 이용한 HTTP 통신 방식입니다. (HTTPS : HTTP over Secure Socket Layer)

따라서 HTTP에 대해 먼저 간단하게 알아보겠습니다.

HTTP : Hyper Text Transfer Protocol

  • Hyper Text를 전송하기 위해 만든 프로토콜

    • Hyper Text (ex: HTML)
  • HTTP는 클라이언트 (웹 브라우저) ↔ 서버 사이의 요청/응답 프로토콜입니다.

  • 웹상에서 통신을 할 때 사용됩니다.

  • http://naver.com : "naver.com과 통신을 하는데 HTTP 프로토콜을 활용해서 통신하겠다"는 의미입니다.

HTTP의 약점

하지만 HTTP에는 3가지 약점이 있습니다.

  1. 암호화하지 않은 통신이기 때문에 도청할 수 있다.

    통신 경로 상에 있는 네트워크 기기나 케이블이나 컴퓨터 등을 전부 자기 자신이 소유할 수는 없습니다. 악의를 가진 사람이 기기를 통해 통신 내용을 도청할 수 있습니다.

  2. 통신 상대를 확인하지 않기 때문에 위장할 수 있다.

    • (Request의 출처) Client를 확신할 수 없다.
      • HTTP는 누가 Request를 보내도 Response하는 구조입니다. 신원이 보장된 특정 Client와만 통신할 수 없습니다.
      • 또한 대량의 Request를 통한 Dos 공격의 위험이 있습니다.
    • (Response의 출처) Server를 확신할 수 없다.
      • Response를 보낸 Server가 내가 의도한 Server인지 확신할 수 있습니다. 위장 Server라는 위험성이 있습니다.
  3. 완전성을 증명할 수 없기 때문에 변조 할 수 있다.

    완전성: 정보의 정확성

    Client와 Server가 보낸 정보를 중간에 누군가 바꿀 위험성이 있습니다.

HTTP란?

image

  • HTTP에 SSL의 껍질을 씌운 것
    • HTTPS는 HTTP와 별개인 새로운 프로토콜이 아닙니다.
  • HTTP는 보안에 취약하기 때문에 HTTP에 다른 보안 프로토콜을 조합한 것
  • HTTP 통신을 하는 소켓 부분을 SSL이나 TLS 프로토콜로 대체합니다.
    • SSL (Secure Scoket Layer)
      • HTTP와 독립된 프로토콜
      • HTTP 외에도 다방면으로 사용되고 있습니다.
    • (참고) 공부하다가 보면 TLS 에 대한 언급을 볼 수 있습니다.
    • SSL == TLS 같은 말입니다. 네스케이프에 의해서 SSL이 발명되었고, 이것이 점차 폭넓게 사용되다가 표준화 기구인 IETF의 관리로 변경되면서 TLS라는 이름으로 바뀌었다. TLS 1.0은 SSL 3.0을 계승한다. 하지만 TLS라는 이름보다 SSL이라는 이름이 훨씬 많이 사용되고 있다.

SSL을 활용한 통신 방법

SSL을 사용하면 암호화를 할 수 있고, 통신하려는 상대를 보증할 수 있습니다.

Client Server 통신에 앞서 Server는 CA에서 인증서를 받는습니다.

CA

  • CA(Certificate authority)
  • 공인된 기관에서 Server가 믿을 수 있는 서버인지 보증하는 SSL 보증서를 발급합니다.
    • CA기관마다 보안 강도가 다르기도 합니다.
    • 뒤에 실습에서 살펴볼 인증서는 보안 강도가 약한 수준이지만, 보안 수준이 높은 인증서는 사업자등록증까지 요구한다고 합니다.
  • 자체 CA (사설 CA)로도 SSL 인증서를 발급할 수 있습니다.
    • 사설 CA도 HTTPS 통신입니다. 하지만 브라우저 입장에서는 안전하지 않다고 판단합니다.

통신 방법

  1. Client가 Server에 최초 접속하면서 2가지 정보를 보냅니다. image

    • random data
      • Client가 생성한 random data입니다.
      • 이건 나중에 사용됩니다.
    • 암호화 기법 목록을 보냅니다.
      • SSL에서 사용되는 암호화 기법은 여러가지입니다.
  2. Server는 3가지 정보를 보냅니다. image

  • random data
    • Server가 생성된 random data입니다.
  • Client가 보낸 암호화 기법 중 자신도 사용할 수 있고, 가장 안정된 암호화 기법
    • 사용할 암호화기법
  • 인증서
    • 인증서에는 서비스 정보와 public key를 보냅니다.
    • 서비스 정보: 인증서를 발급한 CA, 서비스의 도메인 등등
      • 서비스 정보는 private key로 암호화된 상태입니다.
  1. (1) Client는 믿을 수 있는 CA에서 발급한 인증서인지 확인합니다. image
  • Browser는 믿을 수 있다고 판단한 CA 기관 목록을 가지고 있습니다.
  • 공인 CA (믿을 수 있는 CA) / 사설 CA에서 발급한 인증서는 각각 다른 형태로 표시됩니다.
  1. (2) Client는 실제 CA 기관에서 발급한 인증서인지 확인합니다. image
  • Server가 보낸 인증서에는 서비스 정보와 public key가 있습니다.
    • private key와 public key는 하나의 쌍을 이룹니다.
    • public key로 암호화 → private key로 복호화
  • private key로 암호화된 서비스를 public key로 복호화할 수 있다면,
    • 두 key는 pair입니다.
    • CA 기관에서 발급한 인증서라고 할 수 있습니다.
    • 즉, 내가 기대한 서버인지 확인하게 됩니다.

대칭키 방식 (public, private key를 사용하는 암호화 방식)

  1. 통신에 사용할 key를 Client와 Server는 공유합니다. ⇒ 공통키 방식 (하나의 key를 공유하는 암호화 방식) image
  • premaster secret은 앞서 언급한 random data를 합쳐 생성합니다.
  • public key로 암호화하면 private key로만 복호화할 수 있기 때문에 premaster secret은 안전합니다.
  • premaster secret → master secret → session key
    • 일련의 과정을 거쳐 client와 server는 공통키를 가지게 됩니다.

image

  • 공통의 session key로 데이터를 암호화/복호화할 수 있습니다.

왜 이런 방식을 취할까?

위와 같은 암호화 방식을 하이브리드 암호 시스템이라고 합니다.

주목해야 할 점은 공개키 (1개의 키) 방식을 취하되, 그 키를 공유할 때 대칭키 (public key, private key) 방식을 취한다는 점입니다.

공개키의 단점 (공개키를 공유하면서 해킹당할 수 있는 위험), 대칭키의 단점 (속도가 느리고, 많은 컴퓨팅 파워가 필요) 모두를 보완하는 방법입니다.

실습

저희가 실습한 CA는 Let's Encrypt 입니다. Let's Encrypt를 사용하면 무료로 SSL 인증서를 받을 수 있습니다. (대신 기간이 지나면 연장은 해주어야 합니다.)

순서

  1. 사전 세팅
    1. 도메인을 발급합니다.
    2. DNS에 도메인과 내 ip를 연결합니다.
  2. CA에 인증서를 요청 및 발급받기
    • 인증서가 포함하고 있는 내용은 도메인을 이 Server가 소유하고 있는지 입니다.
    • CA에서 도메인에 대한 소유권을 확인한다.
    • SSL 인증서가 발급된다.
  3. 서버에 등록한다.

환경

Ubuntu, Nginx

1. 사전 세팅

  1. 도메인 발급합니다.

    무료 도메인 발급 사이트에서 도메인을 발급 받기

  2. DNS 서버에 도메인과 ip 연결해주기

사이트 우상단 Services → MyDomains → Manage Domain

저는 AWS EC2를 사용했습니다. IPv4 퍼블릭 IP를 연결해줍니다. image

DNS에 도메인과 ip가 잘 연결되었는지 확인해보겠습니다.

nginx를 시작한 후 (sudo service nginx start), 도메인으로 접속하니 잘 나오는 것을 볼 수 있습니다.

image

2. CA에 인증서 요청 및 발급 받기

저희가 등록한 CA는 Let's Encrypt입니다.

Let's Encrypt에 인증서를 발급받기 위해서는 Certbot을 설치해야 합니다.

Certbot은 Let's Encrypt 인증서를 자동으로 발급/갱신해주는 봇입니다.

Certbot 설치 전 사전 세팅

// Ubuntu 환경
$ sudo apt-get update #apt-get 업데이트
$ sudo apt-get install software-properties-common #선행 소프트웨어 설치
$ sudo add-apt-repository ppa:certbot/certbot #저장소 추
$ sudo apt-get update #apt-get 업데이트

Certbot 설치

sudo apt-get install certbot #certbot 설치

Certbot에서 제공하는 인증 방식

  • Standalone
    • Certbot이 위한 간이 웹 서버를 돌려서 Let's Encrypt 서버로부터 오는 도메인 인증 요청을 직접 받아서 처리하는 방식입니다.
    • 인증을 받을 동안 서버를 중단해야 합니다.
    • 별도의 설정이 필요없기 때문에 간단한 Standalone 방식을 채택했습니다.
    • 인증요청 sudo certbot certonly --standalone -d [도메인명]
    • ‼️이 때, 도메인명은 www를 제외하고, tommytommy.com와 같이 입력하셔야 합니다.
    • ‼️ 이 때, nginx server를 중단시켜야 합니다.
  • Webroot
    • 인증을 위한 Challenge Seed를 외부에서 접근 가능한 미리 약속된 경로(/.well-known)에 위치시킨 뒤, Let's Encrypt 서버가 해당 경로로 접속해 인증에 필요한 정보를 읽어갑니다.
    • 서버를 중단할 필요가 없습니다.

인증 요청 후 🎉 Congratulations! 가 나오면 정상적으로 SSL 인증서가 발급된 것입니다.

image

Server에 인증서 등록

  1. 파일 위치로 이동하기

    Server에 인증서를 등록하기 위해 /etc/nginx/sites-available/default로 이동합니다.

    ‼️ (참고) 절대경로 - root부터 시작되는 경로입니다.

  2. 파일 열기

    (sudo vi [파일명]) sudo vi defualt

image
이런 경고창이 나온다면 E를 눌러주세요. (Edit Anyway)

  1. 인증서 정보 등록하기

    80 포트로 접속해도 https 443 포트로 redirect 보내도록 설정하겠습니다.

    server {
    	listen 80;
    	listen [::]:80;
    	return 301 https://tommytommy.tk$request_uri;
    }
    
    server {
    	listen 443;
    	
    	ssl on;
    	ssl_certificate /etc/letsencrypt/live/tommytommy.tk/fullchain.pem;
    	ssl_certificate_key /etc/letsencrypt/live/tommytommy.tk/privkey.pem;
      
    }

    ‼️ 오타주의 privatekey 아니고 privkey입니다.

    • ssl_certificate
      • 인증서
      • cert.pem: 서명된 인증서
      • chain.pem: Let’s Encrypt의 중간 인증서(intermediate certificate)
    • ssl_certificate_key
      • 인증서의 private key
      • 유출되면 안됩니다.

    이 2가지는 아까 SSL 인증서를 받을 때 발급 받았습니다.

image

  1. 서버를 재시작해줍니다.

    sudo service nginx restart

성공 ^__^

image

Clone this wiki locally