프로젝트/단기 프로젝트

[BetterDay] #3. AWS Route 53 & GoDaddy 도메인 연동 / HTTPS LetsEncrypt(Certbot) 설정

Chipmunks 2024. 6. 25. 07:15
728x90

 

API 서버를 HTTPS 프로토콜로 적용하기 위해 도메인을 사야 했다.

웹 프론트까지 신경 써야할 필요는 없었다.

저렴한 가격을 우선 고려했지만, 이왕이면 짧은 도메인을 원했다. (욕심만 많은...)

 

가비아와 이런 저런 곳에서 팀원들과 찾았다.

그러던 중 GoDaddy(이하 고대디)에서 첫 해 2$, 이듬해 20$ 정도 하는 도메인을 발견했다.

회의하기 전에 빠르게 결제하고 도메인을 연동했다.

 

AWS Route 53 네임서버를 고대디에 등록

도메인을 구매하면 아래 사진처럼 확인할 수 있다.

'프로필 > Account | My Products > All Products and Services > Domains' 에서 확인한다.

 

구매한 도메인 항목의 DNS 버튼을 눌러, DNS 설정 페이지로 접속한다.

잠시 대기한다.

AWS Route 53 에서 새로운 호스팅 영역을 만든다.

구매한 도메인을 '도메인 이름'에 입력하여 생성한다.

 

 

그런 다음 레코드 목록으로 접속한다.

제일 처음에 레코드가 두 개 있을 거다.

( 사진에 보이는 레코드(3)은 API 하위 도메인을 이미 설정한 결과다. )

그중 NS(이하 네임서버)에 해당하는 주소를 고대디에 연동할 거다.

 

(중요) 고대디 DNS 관리페이지에서 'Nameservers' 메뉴를 선택한다.

DNS Records 에서 NS 항목을 추가할 수 있는데, 실제로 AWS Route 53과 연동이 안된다.

따로 네임 서버를 등록하는 메뉴가 있었으니... 나처럼 (회의하면서 딴짓으로) 30분 넘게 삽질하지 말길...

 

어쨌든 네임서버 메뉴(!)에서 'Change Nameservers' 버튼을 누른다.

'I'll use my onw nameservers' 옵션을 선택한다.

하나씩 AWS Route 53 에 있는 네임서버 주소를 입력한다.

모두 입력했으면 Save 버튼을 누른다.

 

AWS Route 53 과 연동한다면,

고대디 DNS Records 는 아래처럼 목록이 사라지고

레코드 추가 버튼이 비활성화된다.

이제부터 AWS Route 53 에서 오로지 관리하면 된다.

 

AWS Route 53 으로 돌아온다.

API 서버를 위한 하위 레코드를 생성한다.

AWS EC2에 고정한 퍼블릭 IP를 A유형으로 등록한다.

 

'A유형,' 'CNAME유형', '별칭'을 많이 사용한다.

A유형은 직접 IP 주소를 입력할 때 사용한다.

다른 AWS 리소스와 연동하기도 한다.

 

CNAME유형은 다른 도메인으로 라우팅할 때 사용한다.

마찬가지로 다른 AWS 리소스와 연동하기도 한다.

보통 '다른 도메인'에서도 타도메인 연결을 허용할 수 있는 설정이 가능할 때, 레코드로 연결할 수 있다.

예를 들면, 배포 플랫폼인 헤로쿠와 연동한다든지, Netlify와 연동한다든지 등등.

그 플랫폼에서도 타도메인 연동을 허용할 수 있어야 한다.

 

'별칭'은 AWS 리소스와 연동할 때 사용한다.

'별칭'에 선택할 수 없는 리소스를 'A유형', 'CNAME'유형으로 선택하곤 한다.

예전에는 A유형, CNAME유형으로 다 선택한 것 같은데,

요즘은 '별칭'으로 먼저 시도를 해봐야 한다.

ELB, API Gateway, AppSync, CloudFront, ElasticBeanstalk, S3, VPC 등

AWS 측에서 엔드포인트를 제공하는 통합 서비스를 내 하위 도메인과 연동하게끔 도와준다.

 

우선은 '별칭'에 포함되지 않는 EC2 인스턴스의 퍼블릭 IP 연동만 필요하니

A유형으로 레코드를 선택한다.

내 도메인과 네임 서버가 충분히 인터넷에 전파될때 까지 충분한 시간을 기다린다.

그 동안 유투브를 보면서 간간히 API 도메인에 접속해본다.

 

나는 그동안 nginx 를 설치하며 80 포트에 기본 nginx 페이지가 나타나도록 열었다.

 

nginx / Certbot(LetsEncrypt) 연동

nginx를 설치한다.

명령어는 대략 아래 정도만 알면 된다.

# nginx 설치
$ sudo apt update
$ sudo apt install nginx

# nginx 시작 
$ sudo service nginx start

# nginx 중지
$ sudo service nginx stop

# nginx 재시작
$ sudo service nginx reload

# nginx 상태 확인
$ sudo service nginx status

# nginx 설정 새로고침
$ sudo service nginx reload

 

NginX 를 기본으로 설치했다면, 80 포트로 기본 웹사이트가 나타난다.

AWS EC2 보안그룹 인바운드에서 80 포트가 열려있는지 확인한다.

나는 모든 IP에서 접속이 필요해 열어뒀다.

 

그리고 Certbot (LetsEncrypt) 를 설치한다.

nginx 연동을 위한 패키지를 설치한다.

nginx 모드로 HTTPS 인증서를 발급한다.

 

python3-certbot-nginx 패키지를 설치하지 않으면

--nginx 옵션으로 도메인을 발급할 때 설치해달라고 문구가 나온다.

그 때 설치하고 재시도를 하면 된다.

# Certbot(LetsEncrypt) 설치
$ sudo apt update
$ sudo apt-get install letsencrypt

# nginx 연동을 위한 패키지 설치
$ sudo apt-get install python3-certbot-nginx

# nginx 모드로 HTTPS 인증서 발급
$ sudo certbot --nginx -d api.betterday.one

 

고대디와 AWS Route 53 연동이 잘 되었다면, 성공할 것이다.

여러가지 pem 키가 나왔을 것이다.

 

만약 연동이 안됐다면...

네임서버와 하위 도메인 적용이 인터넷에 전파될 때 까지 한 번 기다려보자.

그래도 안된다면 연동이 잘 안된 것이라.

 

--nginx 모드로 한 데에는 이유가 있다.

그 이유는 HTTPS 인증에 필요한 pem 키를 생성할 뿐 아니라, nginx 설정에도 반영을 해준다.

아래 nginx 설정 페이지를 sudo 로 연다.

참고로 sudo 로 열지 않으면 저장이 불가능하다.

 

$ sudo vim /etc/nginx/sites-enabled/default

 

'# managed by Certbot' 주석이 담긴 줄을 확인할 수 있다.

fullchain.pem, privkey.pem, options-ssl-nginx.conf, ssl-dhparams.pem 설정을 자동으로 해준다.

nginx 에서 필요한 키를 생성해주고 연동해주기 때문에 --nginx 모드로 하는 게 필요하다.

 

기존에 저장해둔 양식이 있어 그 양식을 따랐다.

리버스 프록시 기능을 사용해 스프링 부트 서버로 연동했다.

server {
    server_name api.betterday.one;

    listen 443 ssl; # managed by Certbot
    ssl_certificate /etc/letsencrypt/live/api.betterday.one/fullchain.pem; # managed by Certbot
    ssl_certificate_key /etc/letsencrypt/live/api.betterday.one/privkey.pem; # managed by Certbot
    include /etc/letsencrypt/options-ssl-nginx.conf; # managed by Certbot
    ssl_dhparam /etc/letsencrypt/ssl-dhparams.pem; # managed by Certbot

    location / {
         proxy_pass http://localhost:10000;
         proxy_set_header X-Real-IP $remote_addr;
         proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
         proxy_set_header X-Forwarded-Proto $scheme;
         proxy_set_header Host $http_host;
    }

}


server {
    if ($host = api.betterday.one) {
        return 301 https://$host$request_uri;
    } # managed by Certbot


    listen 80;
    server_name api.betterday.one;
    return 404; # managed by Certbot
}

 

참고로 vim 에서 보기 모드에서 i 를 입력하면 편집 모드로 전환할 수 있다.

그리고 Esc 를 누르면 다시 보기 모드로 돌아간다.

보기 모드인지 편집 모드인지 잘 확인하자. 대충 안 써지면 보기 모드다.

저장은 보기 모드(Esc)에서 :wq 으로 저장하고 편집기를 나간다.

 

저장한 뒤 https 연동이 잘 되는지 확인한다.

http 프로토콜로 접속해도 https 프로토콜로 이동되는지도 확인했다. (nginx에서 301 으로 이동해주기 때문)

 

크롬 기준 주소 좌측에 https 상태를 확인할 수 있다.

'이 연결은 안전합니다.' > '인증서가 유효함' 메뉴를 클릭하면 인증서를 확인할 수 있다.

LetsEncrypt(Certbot) 인증서 기간은 무료다보니, 3개월로 짧다.

3개월 이후에 갱신하는 걸 까먹지 말자!

 

나의 경우 crontab 으로 주기적으로 EC2 에서 갱신을 시도하게 했다.

 

$ crontab -e

> (1) nano 편집기 선택
> (2) vim 편집기 선택

# m h  dom mon dow   command
44 20 * * * certbot renew --post-hook "systemctl reload nginx"

> nano 편집기 일 시 : Control + X > Y > Enter
> vim 편집기 일 시 : :wq

 

사진에 보인 시각은 KST 기준이다.

(인증서 세부정보에서 확인해보면 GMT+9 라고 적혀있다.)

따라서 9시간을 뺀 20시로 적용했다.

매일 20시 44분마다 갱신 명령어를 수행하게 된다.

 

마무리

네임서버를 엉뚱한 곳에서 등록한다든지...

--nginx 모드로 하지 않는다든지...

하는 이슈만 없다면 빠르게 인증서를 발급받고 적용할 수 있다!

Certbot 으로 인증서 발급만 수십 번 해봤는데, 이제야 좀 정리가 된 느낌이다.

드문드문 하다보니 까먹긴 하더라.