백엔드의 비즈니스 로직을 마무리했다면 내 기준 가장 중요하다고 생각하는 배포 단계가 남아있다.
클라우드에 WAS 서버를 올리고, Nginx를 연결해 80번 포트로 통신하게 둔다면 편하게 웹사이트를 구동할 수 있다.
하지만 http로만 통신할 수 있는 웹 사이트는 어딘가 불안정해 보인다. 기본적인 암호화가 제공되지 않기 때문에 로그인을 할 때마다 비밀번호 노출에 대한 위험을 항상 감수해야 할 것이다. 따라서 앞으로 배포할 모든 서비스에 대해서 나는 SSL + HTTPS로 배포할 것이다.
SSL 인증서를 발급받기 위해서 무료로 인증서를 발급해주는 기관인 'Let's Encrypt'가 공식적으로 지원하는 certbot을 사용할 것이다.
Certbot의 도메인 인증 절차
인증서를 발급받기 전에 certbot이 어떻게 해당 도메인의 소유권을 확인하는지 알아보자
Certbot을 통해서 인증서를 발급받는 방법에는 총 4가지가 있다.
- webroot : 사이트 디렉토리 내에 인증서 유효성을 확인할 수 있는 파일을 업로드하여 인증서를 발급하는 방법
. 실제 작동하고 있는 웹서버의 특정 디렉토리의 특정 파일 쓰기 작업을 통해서 인증
. 이 방식의 장점은 nginx를 중단시킬 필요가 없음.
. 이 방법의 단점은 하나의 인증 명령에 하나의 도메인 인증서만 발급 가능 - 웹서버
. Nginx나 아파치와 같은 웹서버에서 직접 SSL 인증을 실시하고 웹서버에 맞는 SSL세팅값을 부여
. 발급이나 갱신을 위해 웹서버를 중단시킬 필요가 없음
. 인증서 갱신 시 상황에 맞게 세팅을 자동으로 업데이트
. 사용자가 세팅을 변경할 수 있지만 자동 업데이트 시 반영되지는 않음
. 운영중인 환경에서 인증서를 발급받기 어렵다. 그 이유는, 80(443) 포트로 직접 웹 서버가 구동되어야 하기 때문이다. 운영중인 서비스에서 두 포트 중 하나만 사용한다면 괜찮지만, 만약 두 포트를 모두 사용하고 있다면 인증서를 발급 받기 위해 서비스를 잠시 내려야하는 치명적인 단점이 있다. - Standalone : 사이트 작동을 멈추고 이 사이트의 네크워킹을 이용해 사이트 유효성을 확인해 Let’s Encrypt SSL 인증서를 발급하는 방식
. 80포트로 가상 staandalone 웹서버를 띄워 인증서를 발급
. 이 방식은 동시에 여러 도메인을 발급 받을 수 있음
. 그렇지만 인증서 발급 전에 Nginx를 중단하고 발급 완료 후 다시 Nginx를 시작해야 함 - DNS : 도메인을 쿼리해 확인되는 TXT 레코드로 사이트 유효성을 확인하는 방법
. 와일드 카드 방식으로 인증서를 발급 가능
. 이 방법은 당연하게도 서버 관리자가 도메인 DNS를 관리/수정할 수 있어야 하며
. 인증서 갱신 시마다 DNS에서 TXT값을 변경해야 하므로 외부에서 TXT 레코드를 입력할 수 있도록 DNS가 API를 제공하는 경우만 갱신 과정을 자동으로 처리
나는 AWS Lightsail을 사용중이고 서버를 직접 관리할 수 있고, 도메인 DNS도 임의로 설정할 수 있기 때문에 DNS방법을 사용해서 인증서를 발급받기로 했다. DNS 방식은 DNS 전파 딜레이가 있기 때문에 바로바로 적용이 되지 않는다는 단점이 있지만 저번에 했을 때 그렇게 오래 걸리지 았아서 크게 신경쓰이진 않았다.
인증서 확인
Docker hub에는 certbot 공식 image가 존재한다.
그래서 따로 certbot을 받지않고 certbot 컨테이너를 활용해서 인증을 시도해 보자.
docker run -it --rm --name certbot \
-v '/etc/letsencrypt:/etc/letsencrypt' \
-v '/var/lib/letsencrypt:/var/lib/letsencrypt' \
certbot/certbot certonly -d 'mydomain.or.kr' --manual --preferred-challenges dns --server https://acme-v02.api.letsencrypt.org/directory
Docker가 나왔으니 명령어를 간단히 파헤쳐 보자
-it
interactive + tty : 터미널을 통해서 사용자와 상호작용하겠다는 뜻이다.
certbot 인증서를 발급받는 중에 입력해야 할 정보들이 있기 때문에 반드시 필요하다
--rm
컨테이너의 사용이 끝나면 자동으로 삭제된다는 뜻이다. 일회성 컨테이너에 추가하는 옵션이다.
--name
컨테이너의 이름을 정해준다. 여기서는 그냥 certbot이라고 정했다. --rm 옵션을 사용한 일회성 컨테이너이기 때문에 크게 중요하지 않다.
-v
바인드 볼륨을 지정해준다. 서버상의 폴더, 파일 : 컨테이너 내부의 폴더, 파일
아래는 certbot 한정 명령어 이다.
-d 'mydomain.or.kr'
인증서를 발급받을 도메인이다.
mydomain.or.kr 대신에 반드시 자신의 도메인을 입력하기 바란다.
--manual --preferred-challenges dns
위에서 설명한 4가지 방법 중에서 dns 방법을 사용해 인증하겠다는 뜻이다.
--server https://acme-v02.api.~
인증서를 가져올 서버를 지정해 주었다.
docker 컨테이너를 실행하면 위와 같이 email을 입력하라는 문구가 나온다.
웹사이트를 지속적으로 관리할거라면 실제로 사용하는 email을 넣어주자.
해당 email로 인증서 갱신, 보안 관련 이메일이 전송된다.
약관 동의이다. 앞으로 Yes / No 나오면 그냥 다 약관동의이므로 모두 Y를 입력해서 정상 진행해주자.
그리고 다음에 나올 문구에서 Press Enter to Continue가 보인다고 바로 enter를 눌러서는 안된다!
중간에 가려진 부분에 DNS txt 레코드가 있을 것이다.
그리고 바로 위를 보면 _acme-challenge.mydomain.com 이라고 요청을 보낼 도메인이 있을 것이다.
이제 자신의 DNS 서버에 TXT 레코드를 추가하자.
dns 명은 _acme-challenge.mydomain.com 이고 txt 는 위 암호가 될 것이다.
** txt 레코드를 추가하고 약간 기다려야 한다. dns record가 전파되는 시간이 있기 때문에 최소 2~3분 정도는 기다렸다가 진행하자.
만약 nginx를 통해서 웹서버의 endpoint를 제어하고 있다면 엔터를 누르기 전에 반드시 추가해줘야 하는 설정이 있다.
# certbot이 ssl을 발급할때 아래의 주소/.well-known/acme-challenge/ 를 통해 인증하므로 반드시 필요
location /.well-known/acme-challenge/ {
root /var/www/certbot;
}
listen 80의 location에 위 주소를 추가해줘야 한다.
인증이 끝나면 주석처리 해두면 된다.
깨알 리눅스 명령어 - 네트워크 관리 명령어
nslookup [option] [domain]
domain이 어떤 ip주소와 연결되었는지 확인할 수 있다.
option에 -type=ns 를 사용하면 해당 도메인을 매핑해주는 네임서버를 알 수 있다.
dig [domain] [datatype]
nslookup의 업그레이드 버전이다. nslookup과 마찬가지로 DNS쿼리를 날린다.
datatype에 any를 붙이면 네트워크 쿼리의 다양한 정보를 볼 수 있다.
마무리 및 인증서 갱신 스크립트
위와 같은 화면이 뜨면 인증서발급을 성공한 것이다.
인증서는 화면에도 보이다시피 /etc/letsencrypt/live/domain.com/ 폴더에 저장되어있다.
웬만한 인증서는 letsencrypt 위치에 저장된다고 하니 굳이 인증서를 다른곳으로 옮기지 말자
백업 용도로 .pem 파일을 복사하고 싶은 경우
live 폴더 자체가 권한이 root 사용자에게만 있기 때문에 sudo -i 를 통해서 관리자 계정으로 접속하거나, sudo chmod 775 live를 통해서 권한 자체를 바꿔서 cp 명령어를 수행하면 된다.
이 인증서는 자동적으로 갱신할 수 없다.
DNS TXT Record 인증방식을 사용했기 때문에 자동으로 갱신할 방법이 없는 것이다.
webroot 방식으로 하면 인증서 갱신이 편할 것으로 예상된다..
webroot에 대해서도 알아봐야겠다.
인증서 갱신
#!/bin/bash
docker run -it --rm --name certbot \
-v /etc/letsencrypt:/etc/letsencrypt \
-v /var/lib/letsencrypt:/var/lib/letsencrypt \
certbot/certbot renew --manual --preferred-challenges dns --server https://acme-v02.api.letsencrypt.org/directory
나는 위 코드를 cerbot_renew.sh 라는 이름의 스크립트로 저장을 했다.
이제 crontab으로 3개월마다 자동으로 인증서를 갱신하게 하거나, 3개월이 되기 전에 내가 직접 스크립트를 실행시켜서 인증서를 갱신할 수 있다. 일단 첫 인증서 갱신은 수동으로 해 줄 생각이다.
Nginx를 사용하는 경우 배포를 마무리 하는 방법
AWS와 외부도메인 연결하기
'DevOps > Docker' 카테고리의 다른 글
[Docker] 이미지와 레이어(layer) 구조 (0) | 2022.01.25 |
---|---|
[Docker] 컨테이너 기능별, 포트별 분리 (feat. nginx) (0) | 2021.11.22 |
[Docker] Docker Swarm 서비스하기 (0) | 2021.08.24 |
[Docker] Docker Swarm에 대해서 (0) | 2021.08.18 |
[Docker] docker-compose로 편하게 개발환경 구성하기 (0) | 2021.08.10 |