Certbot(Let's encrypt) SSL 인증서 자동갱신하는 방법
이 글을 읽고 있으신 독자라면, 아마도 SSL 인증서와 왜 HTTPS를 이용하고 Let's Encrypt에서 진행하고 있는 무료 SSL인증서 프로젝트에 대하여 알고 계실 것이라 믿습니다. Let's encrypt에서 무료로 관리하고 배포하는 인증서는 certbot이라는 프로그램을 통해 수령 및 관리 할 수 있습니다. 이처럼, 무료로 인증서를 이용할 수 있게끔 하여 인터넷이라는 거대한 네트워크를 좀 더 안전하게 사용할 수 있도록 하는 이 프로젝트는 딱 한가지 아쉬운 점이 있습니다. 그것은 무료로 배포하는 인증서의 유효기간이 3개월이라는 점 입니다. 아마도 무료로 운영되는 프로젝트 상, 더 많은 사람에게 더 필요한 사람에게 더 효율적으로 이용하게끔 하고자, 한 조치로 보입니다. Let's encrypt에서는 이러한 단점에 크게 불편함을 얻지 않도록 계속해서 인증서를 이용하고자 하는 사람이라면, 인증서의 갱신이 쉽게 가능하도록 만들어 놓았습니다. 이 방법에 대하여 알아보겠습니다.
필자의 인증서 갱신 환경
필자가 인증서 자동갱신에 대하여 설명하는 환경은 다음과 같습니다만, 필자의 환경과 다른 환경에서도 이 글을 참고하시기에 충분할 것입니다. 필자의 환경은 우분투 리눅스환경에서 /etc/letsencrypt
폴더에 인증서가 발급되고 해당 디렉토리가 nginx 도커 컨테이너의 인증서 보관 디렉토리 볼륨과 링크되어 작동하는 환경입니다. 추가적인 설명을 덧붙이자면, let's encrypt와 certbot에서 기본적으로 제공하는 ubuntu+nginx 조합일때 certbot을 설치하여 인증서를 발급받는 방식으로 인증서를 발급하였습니다.
기본적인 수동 인증서 갱신 방법
만약 수동으로 인증서 리뉴얼을 진행하시고 싶으시다면, 아래의 방법으로 진행이 가능합니다. certbot에서 인증서 최초 발급때, 이메일을 입력해 놓으면 인증서 만기전, 이메일로 인증서 갱신에 대하여 이메일로 통보하여 줍니다. 위에서 설명한 필자와 같은 방식으로 서버가 구성되어 있다면, 인증 및 갱신을 위하여 certbot이 http와 https에서 사용하는 포트를 이용하여 인증서 관리측과 통신을 진행해야 하는데, nginx 도커컨테이너가 해당 포트들을 차지하고 있다면 통신이 불가능하니, 잠시 해당 컨테이너들을 멈춰주고 certbot을 통한 갱신을 진행해야 합니다.
$ sudo docker stop nginx-container
$ sudo certbot renew
이 후 certbot이 인증서 갱신을 도와줍니다.
자동 인증서 갱신을 위한 crontab 이용 방법
crontab은 리눅스에서 command-line으로 작동하는 유틸리티로, 일종의 잡 스케쥴러입니다. 좀 더 쉽게 표현하자면, crontab은 특정 시간조건을 설정하면 해당 시간조건이 성립할 때마다 내가 설정한 일련의 일들을 수행하도록 설정하고 관리할 수 있는 유틸리티 입니다. crontab에 대하여 깊숙히 알아야 할 필요는 없으므로, 가장 많이 사용하고 필요한 명령어만 알아보겠습니다.
crontab -e # 새로운 크론잡(크론 스케줄, 잡스케줄)을 생성하거나 편집하기
crontab -l # 생성해놓은 크론잡 목록 조회하기
crontab -r # 이전에 생성한 크론잡 삭제하기
위 명령어를 실행하면 크론잡들이 설정이 저장된 파일이 에디터를 통해 나타납니다. 이 동작을 성공적으로 실행시키기 위해서는 리눅스의 command-line에서 텍스트를 생성 및 수정 등을 할 수 있어야 합니다. 만약 이 요건을 충족하실 수 있다면 아래의 설정 방식대로 크론잡을 등록, 수정, 및 삭제 하실 수 있습니다.
m h dom mon dow(day of week) 사용자의 명령어 쓰는 곳
┬ ┬ ┬ ┬ ┬
│ │ │ │ │
│ │ │ │ │
│ │ │ │ └───── 한주 중 요일 설정 (0 - 6) (0은 일요일 1은 월요일 ... 6은 토요일)
│ │ │ └────────── 월 설정 (1 - 12)
│ │ └─────────────── 한달 중 일자 설정 (1 - 31)
│ └─────────────────── 시각 설정 (0 - 23)
└───────────────────── 분 설정 (0 - 59)
위 크론 스케줄 방식은 상당히 헷갈리기 때문에 이해를 돕기위해 여러 예시를 아래에 보여드리겠습니다.
# 매 시간의 30분에 script-to-run.sh 스크립트를 실행
$ 30 * * * * /script-to-run.sh
# 30분 마다 script-to-run.sh 스크립트를 실행
$ */30 * * * * /script-to-run.sh
# 매주 금요일 오후 한시에 script-to-run.sh 스크립트를 실행
$ 30 13 * * 5 /script-to-run.sh
# 매분마다 script-to-run.sh 스크립트를 실행
$ * * * * * /script-to-run.sh
# 매년 9월 21일날 오전 8시 49분에 script-to-run.sh 스크립트를 실행
$ 49 8 21 9 * /script-to-run.sh
# 매주 수요일 오전 여섯시에 script-to-run.sh 스크립트를 실행
$ 0 6 * * 3 /script-to-run.sh
# 매 시 1분, 18분, 59분마다 script-to-run.sh 스크립트를 실행
$ 1,18,59 * * * * /script-to-run.sh
# 매주 일요일과 화요일마다 오전 6시에 script-to-run.sh 스크립트를 실행
$ 0 6 * * 0,2 /script-to-run.sh
필자가 crontab으로 설정한 인증서 자동 갱신 스케줄
# 매월 1일 오후 6시마다 "/usr/bin/cerbot renew"를 실행
# 해당 명령어를 실행 전 "sudo docker stop nginx-container" 명령어를 실행
# 해당 명령어를 실행 후 "sudo docker start nginx-continaer" 명령어를 실행
$ 0 18 1 \* \* /usr/bin/certbot renew --renew-hook="sudo docker start nginx-container" --pre-hook="sudo docker stop nginx-container"
위 명령어들에 대하여 간단히 설명하자면, 갱신 명령어 전에 certbot이 인증서 관리측과 통신을 할 수 있도록 nginx 도커 컨테이너를 멈춘 후, 갱신을 진행합니다. 갱신 후, 인증서가 갱신되었기 때문에, 다시 서버를 동작하기 위해 nginx 컨테이너를 실행하여 마무리 합니다.