Profile picture

[배포 가이드] 배포한 VM(Lightsail)에 도메인 & HTTPS 적용하기

JaehyoJJAng2023년 11월 21일


Domain

도메인은 인터넷에 연결된 컴퓨터들의 IP를 사람이 쉽게 기억하기 어렵기 때문에 이를 위해 각각의 IP에 사람이 기억하고 쉽게 입력이 가능하도록 문자(영문,한글 등)로 만든 인터넷 주소이다


이전 게시글([Deploy] 가상서버(Virtual Machine)에 node API 배포하기 - AWS Lightsail)에서 node.js + typescript를 사용하여 매우 간단한 API를 만들고 Lightsail에 배포까지 해보았다.

실제 프로덕션으로 배포할 때에도 지금처럼 IP 주소를 브라우저에 치고 들어가야 한다면 어떨까?

사용자 입장에서는 들어가기가 매우 어려울 것이다. 내 서버 공인 IP를 따로 적어놓을 정도로 할 일이 없지는 않을 테니까. 정말 뛰어난 서비스이더라도 IP를 치고 들어올 정도로 수고스럽다면 트래픽이 늘어나기는 힘들 것이다.

그래서, 나는 가비아에서 .shop 도메인을 구매하고 이전에 만든 VM(Lightsail)에 도메인을 적용할 것이다. 더 나아가 HTTPS 까지 적용해보려고 한다.


.shop 도메인

1. 도메인 구매

먼저 가비아(https://www.gabia.com/)에 접속하여 로그인/회원가입을 진행하자.


생각해놓은 도메인 이름이 있다고 해서 무조건적으로 쓸 수 있는 것은 아니다. 해당 도메인이 사용 중인지 아닌지 확인해 봐야 하는데 그걸 가비아에서 확인할 수 있다.
image
나는 www.waytothem.shop을 검색했는데 이미 등록된 도메인이라고 뜬다(이미 내가 등록한 도메인)


원하는 도메인을 선택하였으면 장바구니에 담고 '신청하기' 버튼을 눌러 결제를 진행하면 된다.
(결제 방법에 대해서는 넘어가겠다.)
image


도메인 구입이 완료됐으면 이제 '내 정보'에서 구입한 도메인을 관리할 수 있게된다.
image


2. 도메인 적용

내 목표는 당연히 해당 도메인을 VM에 적용하는 것이다. 도메인 적용 방법은 그리 어렵지 않다. 아래의 정보가 필요하다.

  • VM 또는 개인 서버의 Public IP - 10.98.105.50/24

서버의 공인 IP 주소만 알고있으면 도메인을 쉽게 적용할 수 있다.


먼저 DNS 관리 페이지(https://dns.gabia.com/dns/internals)로 이동해보자.
image


구입한 도메인(waytothem.shop)를 체크하고 'DNS 설정' 버튼을 클릭.
image


그럼 아래와 같이 레코드를 설정할 수 있는 페이지가 보일 것이다. 우리는 여기서 2개의 레코드를 추가하면 된다.
image

  • A @ Server_IP : 해당 레코드는 도메인의 루트를 가리키며, "@" 기호는 도메인의 루트를 의미합니다. 예를 들어, "example.com" 도메인의 경우 "A @" 레코드는 "example.com" 도메인 자체를 가리키는 것이며, 이 레코드에는 도메인의 IP 주소가 포함됩니다. 이 IP 주소는 해당 도메인으로 접속할 때 사용되는 서버의 주소를 의미합니다.
  • A www Server_IP : 해당 레코드는 "www" 서브도메인에 대한 IP 주소를 나타냅니다. 대부분의 경우, 사용자가 "www.example.com"과 같은 형식으로 도메인에 접근하면, "A WWW" 레코드가 해당 서브도메인에 대한 IP 주소를 가리키며, 사용자를 웹 서버로 안내합니다. 따라서 "www" 서브도메인의 주소를 설정하고 관리하기 위해 사용됩니다.

3. 적용 확인

도메인이 서버에 바로 적용되지는 않는다. 조금 시간이 지난 후 구입한 도메인 주소를 브라우저에 쳐보면 서비스에 정상적으로 접근이 될거다.
image
근데 HTTPS가 적용되지 않아 '안전하지 않음' 이라고 표시되는 것을 알 수 있다.


HTTPS

HTTP는 클라이언트와 서버 사이에서 하이퍼텍스트(HyperText)를 전송(transfer)하기 위해 사용되는 통신 규약(protocol)이다.

HTTP는 기본 포트인 80번 포트에서 서비스를 대기하고 있으며, 클라이언트(웹 브라우저)가 TCP 80 포트를 사용해 연결하면 서버는 요청에 응답하면서 클라이언트에게 자료를 전송한다. 하지만 HTTP의 경우 텍스트로 데이터를 주고받기 때문에 네트워크단에서 전송 신호를 인터셉트 하는 경우 원치 않는 데이터 유출 사고가 발생할 수 있다.

이러한 보안 취약점을 해결하기 위해 탄생한 프로토콜이 HTTP에 S(Secure Socket)가 추가된 HTTPS이다.

HTTPS는 기본 골격이나 사용 목적 등은 HTTP와 동일하다. 다만 데이터를 주고 받는 과정에서 '보안' 요소가 추가되었다는 것이 가장 큰 차이점이다. HTTPS 프로토콜을 사용한 서버는 클라이언트와의 모든 통신 내용이 암호화된다.


Lightsail HTTPS

일반적으로 SSL을 프로덕션에 적용하려면 연간 비용이 발생한다.
가장 기본적인 SSL 인증서 적용에 연 3 ~ 4만원 정도가 발생한다고 하니까 만약 여러 사이트를 운영하고 있다면 SSL 인증서 값이 상당히 부담될 수 있을 것 같다.

아마존 Lightsail에서는 'Let's Encrypt SSL' 라는 인증서를 통해
SSL 인증서를 무료로 적용할 수 있는 방법을 제공한다!

'Let's Encrypt SSL'은 비싼 SSL 구매 비용이 안전한 네트워크 환경 조성에 방해가 된다고 여기는 여러 단체와 기관들이 모여 설립한 인증기관으로,
SSL 인증서를 무료로 발급해 운영중인 사이트에 HTTPS를 적용할 수 있도록 해준다. 다만, 해당 인증서의 경우 3개월 마다 갱신이 필요하다.

현재 나는 AWS Lightsail 인스턴스를 임대하여 사용 중이니 Lightsail 환경에서 HTTPS 적용하는 법을 실습해볼 것이다. 또한 적용한다고 끝이 아니다. Let's Encrypt SSL 인증서는 주기적으로 갱신도 해줘야 한다.


1. 인스턴스에 Certbot 설치

아마존 Lightsail에서 제공하는 가이드를 참고하여 lightsail 인스턴스에 HTTPS 적용해보도록 하겠다.


먼저 인증서 요청 및 배포를 위한 클라이언트, Certbot을 라이트세일 인스턴스에 설치해야 한다.


1. 라이트세일 서버의 SSH 터미널에 접속해 인스턴스의 패키지 업데이트

sudo apt-get update -y

2. 다음 명령어를 입력해 소프트웨어 속성 패키지(software-properties-common) 설치

sudo apt-get install -y software-properties-common

3. certbot 설치

sudo apt-get install -y certbot

4. certbot 버전 출력

certbot --version

certbot 1.21.0

2. SSL 인증서 요청

이제 사이트에 적용할 SSL 인증서를 Let's Encrypt에 요청해야 한다.
이미 적용되어 있는 인증서를 다시 갱신 해야 하는 경우에도 여기서부터 진행하면 된다.

Certbot를 사용하여 도메인과 하위 도메인 모두에 적용될 수 있는 와일드카드 인증서를 요청해보도록 하자.


1. 터미널에 다음 명령어를 입력해 도메인에 대한 환경변수를 설정하자.
({domain}에는 각 사이트의 도메인 주소를 입력하면 된다.)

DOMAIN={domain}

image

WILDCARD=*.${DOMAIN}

image


2. echo 명령어로 변수가 제대로 등록되었는지 확인하자.

echo -e "${DOMAIN}\n${WILDCARD}"

image


3. 다음 명령어로 Certbot을 실행하여 최상위 도메인 및 하위 도메인에 대한 와일드 카드 인증서를 요청하자.

sudo certbot -d ${DOMAIN} -d ${WILDCARD} --manual --preferred-challenges dns certonly

4. 메시지가 표시되면 갱신 및 보안 고지 사항에 사용될 이메일 주소를 입력하자.
image


5. 안내 및 IP 주소가 기록된다는 경고 메시지 등에 적절히 응답.
image


6. 이제 요청한 도메인을 실제로 소유하고 있는지 확인하는 단계이다.
다음과 같이 Let's Encrypt에서 제공하는 TXT 레코드를 도메인의 DNS 레코드에 추가해주어야 한다.

Let's Encrypt에서 제공하는 두 TXT 레코드를 어딘가에 복사해놓자.
image

🔺 TXT 레코드를 DNS 레코드에 배포해야 다음 단계로 진행할 수 있다!
SSH 터미널에서 Enter키를 누르지 말고 잠시 홀드 ☺️


3. 도메인 DNS 영역에 TXT 레코드 추가

이제 TXT 레코드를 도메인의 DNS 레코드로 배포해 도메인을 실제로 소유하고 있다는 것을 증명해야 한다.

나는 gabia에서 도메인을 구매하였으므로
gabia를 통해 DNS 레코드를 배포해보겠다.


Gabia의 도메인 DNS 관리 페이지로 들어가자.
관리 페이지에서 도메인의 IP, 도메인명 등 여러 DNS 레코드를 관리할 수가 있다.
image


Let's Encrypt에서 요구하는 것은 **_acme-challenge.{domain}**에 대한 TXT 레코드 등록이므로
다음과 같이 DNS 관리 페이지에서 TXT 레코드를 등록해 저장해주자.
image
'저장'하고 난 후 어느정도 시간이 지나야 배포된다.


4. TXT 레코드 전파 확인

도메인에 등록한 DNS 레코드가 배포되어야 Let's Encrypt 에서도 TXT 레코드를 확인하여 다음 단계로 진행이 가능하다.
만약 배포가 되지 않은채로 진행하면 인증서 요청이 실패한다.


  1. 브라우저 창을 열고 https://mxtoolbox.com/TXTLookup.aspx로 이동한다.
  2. 접속한 사이트에서 TXT 레코드 명을 입력해 해당 레코드가 정상적으로 배포되었는지 확인한다.
    1. (EX. _acme-challenge.waytothem.shop)
    2. image
  3. 정상적으로 배포되었다면 터미널로 돌아가 'Enter' 키를 눌러 다음 단계를 진행하자.

5. 인증서 요청 완료

인증서 요청이 완료되면 'Successfully received certificate.' 라는 메시지와 함께
인증서, chain 및 privkey 키 파일이 서버에 발급되었음을 안내하는 메시지가 아래와 같이 출력된다.
image


6. 인증서 파일 서버 반영

인증서가 발급됐으면 인증서 파일(fullchain.pem,privkey.pem)의 경로를 /etc/nginx/sites-available/nginx_이름 파일에 기입하면 된다.


6-1. nginx 설정

아래 코드 내용을 아래 경로의 default 파일에 기입해주자.
(/etc/nginx/sites-available/default)

# 80 설정
server {
   listen 80; # 80으로 접속(Http 포트 번호)
   server_name waytothem.shop www.waytothem.shop; # 서버 URL 주소

   location / {
      return 301 https://$server_name$request_uri;
   } # 80번으로 접속된 주소는 443으로 보내진다.
}


# 443 설정
server {
   listen 443 ssl; # 443으로 접속(Https 포트 번호)
   server_name waytothem.shop www.waytothem.shop; #서버 URL 주소

   ssl_certificate /etc/letsencrypt/live/waytothem.shop/fullchain.pem; #SSL 인증키
   ssl_certificate_key /etc/letsencrypt/live/waytothem.shop/privkey.pem; #SSL 인증키

   location /static { 
      alias /home/ubuntu/projects/mysite/static;
   } #Static 주소를 443 서버로 옮기자

   location / {
      include proxy_params;
      proxy_pass 요청_주소;
   } # 443으로 온 주소는 여기서 요청을 받는다.
}

image


6-2. nginx 재시작

변경 사항 적용을 위해 nginx 서비스를 재시작하자.

systemctl restart nginx

7. HTTPS 적용 확인

HTTPS가 잘 적용됐는지 브라우저에서 도메인 주소를 치고 접속해보자. (https://waytothem.shop)
image


8. 인증서 갱신

certbot renew 명령어로 쉽게 갱신 가능하다.

sudo certbot renew

Saving debug log to /var/log/letsencrypt/letsencrypt.log

- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
Processing /etc/letsencrypt/renewal/waytothem.shop.conf
- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
Certificate not yet due for renewal

- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
The following certificates are not due for renewal yet:
  /etc/letsencrypt/live/waytothem.shop/fullchain.pem expires on 2024-02-26 (skipped)
No renewals were attempted.
- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -

현재 나는 갱신일 까지 기간이 남아서 아직 갱신할 수 없다고 뜬다.


Loading script...