개발
백엔드
certbot renew 갱신 실패시 docker 작업 불능 문제 (dockert certbot)
아...
진짜 오랜만에 그지같은걸 당했다.
안당해보면 모를만한걸 당해서 좀 어이없기도하고 이제와서 당했다는게 부끄럽기도하다...
사건발단
나는 회사에서 도커서버를 통해 여러 웹사이트의 라이브서비스를 제공하는 식의 서버를 운영하고있다.
쉽게 말해 물리적 서버는 하나인데, 프록시 서버로 여러개의 도커컨테이너에 라이브 서비스를 제공하는 방식이다.
당연히 해당 웹사이트는 SSL 인증서를 사용하는 경우도 많아서 나는 Let's Encrypt 무료 인증서를 가져다가 쓰는 방식을 사용하고있다.
물론 이 인증서 발급또한 sh 파일로 만들어서 자동 갱신되도록 crontab과 함께 자동화해둔 상태이다.
문제는 서비스 운용후 몇년만에 발생한 일이다.
고객사중 하나가 도메인을 바꿔달라는 요청하에 기존 a.com을 b.com으로 바꿔주고 b.com도메인에 기존처럼 SSL을 붙이게 되었다.
난 당연히 a.com에 걸린 인증서는 갱신할 타이밍이되면 더이상 존재하지 않는 도메인이라 갱신실패가뜨고 정상적으로 돌아갈줄 알았다.
근데 이게 진짜 안일한 생각이었다.
뭐? 갱신중에 문제발생했다고? 누워
아니 도커 이쉑기는 내가 자동화 코드로 구동시켜둔 코드가 문제가 생겨버리니까 그대로 그자리에서 눕는게 아닌가;;;
The following renewals failed:
/etc/letsencrypt/live/a.com/fullchain.pem (failure)
1 renew failure(s), 0 parse failure(s)
Ask for help or search for solutions at https://community.letsencrypt.org. See the logfile /var/log/letsencrypt/letsencrypt.log or re-run Certbot with -v for more details.
Found orphan containers (docker_temp_1) for this project. If you removed or renamed this service in your compose file, you can run this command with the --remove-orphans flag to clean it up.
Copy
뭐 쉽게말해서 갱신작업도중 문제발생해서 누울꺼고요.
점유한 도커 컨테이너는 이대로 놔둘께요 ㅅㄱ.
를 당해버린것이었다.
어이가 좀 없었는데, 그나마 다행인거는 내가 이 자동화코드를 새벽에 돌려놓고 문제를 아침에 발견했다는거?
바로 문제가 생긴 도메인의 인증서를 확인해보니 위의 사건발단의 내용처럼 없는 도메인의 인증서를 갱신하려했던것이었다.
그래서 일단 서버는 다시 업 시켜놓고 문제를 해결해보기로했다.
문제되는 인증서 삭제
일단 갱신도중 문제되는 인증서 갱신이 이루어지는거니까 인증서 삭제하고 보자라는 생각이 들었다.
근데 나는 이걸 도커환경에서 구현한거라 그냥 터미널에서
certbot delete
를 할수없다는 점이었다.그래서 도커 코드를 이용해서 아래와 같이 문제되는 인증서 파일을 삭제할 수 있었다.
docker run -it --rm \
-v /etc/letsencrypt:/etc/letsencrypt \
-v /var/lib/letsencrypt:/var/lib/letsencrypt \
certbot/certbot delete --cert-name a.com
Copy
요 코드의 장점은 certbot 작업을하나 서버 검증작업이 필요없으므로 굳이 80 포트를 안써도 되고,
--rm
명령어로 작업이 끝나면 도커 컨테이너가 알아서 소멸된다는점이다.위 명령어를 실행하면 아래와 같은 문구가 출력되는데,
- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
The following certificate(s) are selected for deletion:
* a.com
WARNING: Before continuing, ensure that the listed certificates are not being
used by any installed server software (e.g. Apache, nginx, mail servers).
Deleting a certificate that is still being used will cause the server software
to stop working. See https://certbot.org/deleting-certs for information on
deleting certificates safely.
Are you sure you want to delete the above certificate(s)?
- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
(Y)es/(N)o:
Copy
Y를 입력해주면 해당 도메인의 인증서 파일이 삭제가 된다.
그리고 다시 원래 목적대로 인증서 갱신 작업을 진행하면된다.
재발방지
지금 이런 문제가 나는 도메인 교체건에 대해서 발생했지만, 고객사가 사이트 이전을할때도 이렇게 갱신이 안되는 건이 발생할 수 있다는걸 추측할 수 있었다.
굳이 이런 특정상황을 상정하지않아도, 갱신작업중 네트워크 회선이 불안정하다든지의 문제로 얼마든지 갱신작업중 문제가 발생할 수 있다는걸 알게되었다.
그래서 기존의 갱신 배치파일 코드를 소폭 변경했다.
#!/bin/bash
echo
echo [$(date '+%Y-%m-%d %H:%M:%S') Run certbot-renew.sh] ====================================
cd ~/docker
docker-compose down --remove-orphans
docker run --rm --name certbot -p 80:80 -p 443:443 -v '/etc/letsencrypt:/etc/letsencrypt' -v '/var/lib/letsencrypt:/var/lib/letsencrypt' \
certbot/certbot renew || echo "[WARN] certbot renew failed."
docker-compose up -d
echo [DONE] ========================================================================
echo
Copy
변경된점은
docker-compose down
명령어에 고아 컨테이너를 삭제하는 명령어를 추가하는것과,certbot renew
작업이 실패했을경우 echo
명령어를 실행시켜 프로세스를 다음으로 넘기는 구문을 추가한 것이다.위 코드에서
|| echo "[WARN] certbot renew failed."
에 해당하는 내용이다.결론
거참 이런경우를 처음에 상정하지 않았다는게 그냥 부끄러울뿐이고...
관련된 도커 명령어중 인증서 리스트 뽑는 명령어도 있길래 아래처럼 한 번 돌려봤다.
docker run -it --rm \
-v /etc/letsencrypt:/etc/letsencrypt \
-v /var/lib/letsencrypt:/var/lib/letsencrypt \
certbot/certbot certificates
Copy
이런 명령어를 돌리면 아래처럼 certbot을 통해 발급받은 인증서가 주르륵 터미널창에 출력이된다.
Found the following certs:
Certificate Name: domain.com
Serial Number: 0000
Key Type: RSA
Domains: domain.com www. domain.com
Expiry Date: 2025-07-13 17:09:02+00:00 (VALID: 89 days)
Certificate Path: /etc/letsencrypt/live/domain.com/fullchain.pem
Private Key Path: /etc/letsencrypt/live/domain.com/privkey.pem
Copy
이바닥에 7-8년있었지만 아직도 서비스 과정에서의 시행착오는 끝난게 아니라는게 새삼 놀라울따름이다.
끝
#문제해결 #SSL #Ubuntu #docker
0
개의 댓글
백엔드 콜렉션의 다른 글
개발 카테고리의 다른 글

04/16
온라인 UUID 생성기 제작 및 비화
가끔 업무를 하다가 대량의 uuid를 만들어야 하는 경우가 발생한다.나같은 경우는 게시글 데이터 이전을 할때 새로운 게시글 구조에서는 기존에 사용하지 않는 uuid 방식으로 고유값을 이용하는데, 보통 이전 db구조에서 그런걸 쓰지않다보니 개수에 맞게 uuid를 만들어야 하는 경우가 종종 있다. 그럴때 일반적으로 쿼리문...
04/14
MPEGTS 컨테이너 파일 MP4로 변환하는 법
개인적인 공간에서 PLEX로 영상을 관리하는데 일부기기에서 영상재생이 안된다는 내용을 받게되었다.무슨문제인가 싶어 해당 영상의 정보를 확인해 봤는데, 코덱이나 영상자체는 문제가 없었다. 단 영상의 Container가 처음보는 MPEGTS 값으로 되어있었다.이게 뭔가해서 알아보니 MPEGTS는 MPEG-TS(Transport Steam)으로 방...
04/11
MSSQL 데이터 수정(보정) 쿼리문
웹 개발을 하다보면 디비이전을 하는 경우가 종종있다.내가 작업하는 환경은 mysql(mariadb) 환경이라 같은 db사이에서는 무난하게 이전작업을 할 수 있긴하다. 하지만 외부 데이터를 이전할때 이전 db가 mssql인 경우도 정말 많다.대표적으로 ASP로 구현된 윈도우 서버의 경우엔 mssql을 db로 쓰는 사이트가 많기때문이다....