blog.stackframe.dev

systemd timer로 인증서 갱신 자동화 하기

개인 사이트를 운영한다면 대부분 Let's Encrypt를 사용하여 HTTPS 인증서를 발급받을 것이다. Let's Encrypt는 3개월 기간의 인증서를 발급해 주고 만료 1달 전에 갱신할 수 있다. 만료일이 가까워 졌다는 것을 이메일로 알려주지만 매 번 서버에 접속해서 갱신을 하고 인증서를 사용하는 서비스들을 리로딩하는 것은 귀찮은 일이다. 그래서 systemd를 사용하여 이것을 자동화하려 한다.

systemd에는 timer라는 cron과 동일한 작업을 하는 기능이 있다. 이것의 사용법에 대해서는 나의 티스토리 블로그에 설명한 적이 있다. timer를 사용하여 매 주마다 갱신을 시도하고 서비스들을 리로딩하면 될 것이다.

먼저 매 주마다 실행되는 타이머를 만든다. /etc/systemd/system/certbot.timer:

[Unit]
Description=Renew certificate every week

[Timer]
OnCalendar=weekly
Unit=certbot.service

[Install]
WantedBy=timers.target

그리고 이 타이머가 실행할 service 유닛을 만든다. /etc/systemd/system/certbot.service:

[Unit]
Description=Renew certificate

[Service]
ExecStart=/usr/bin/certbot renew

ExecStop=/usr/bin/systemctl reload nginx
ExecStop=/usr/bin/systemctl reload postfix
ExecStop=/usr/bin/systemctl reload dovecot

ExecStop은 인증서를 사용하는 서비스들에 대한 리로딩 명령을 쓰면 된다.

개인적으로 certbot.service를 어떻게 만드는 것이 좋을 지 고민을 많이 했다. 이외의 방법을 생각해보면

  • Typeoneshot으로 하고 모든 명령들을 ExecStart로 써버린다.
  • Drop-in 디렉토리를 만들어서 각 서비스마다 ExecStop이 들어있는 파일을 하나씩 만든다.
  • 서비스들을 리로딩하는 service를 하나 더 만들어서 certbot 명령의 --renew-hook를 사용하여 실행한다.
  • 서비스들을 리로딩하는 service를 하나 더 만들고 certbot.servicePartOf로 지정한다.

해결 방법은 다양하고 우월하게 좋은 방법도 딱히 보이지 않아서 그나마 단순하고 보기 편한 위의 방법을 사용했다. 다만 서비스를 재시작하는 것은 고려조차 하지 않았다. 서버 프로그램을 껐다 키는 것은 가용성이 떨어질 가능성이 있어서이다.

아무튼 이렇게 설정파일을 만들고 아래의 명령들을 실행하면 타이머가 실행된다:

# systemctl enable certbot.timer
# systemctl start certbot.timer

이제 매 주 인증서 갱신을 시도하고 서비스들을 리로딩 할 것이다.

댓글