문제 상황

처음 SSL 인증서를 발급할 때 메인 도메인만 포함해서 발급했다.

certbot certonly --nginx -d yourdomain.com

이후 서비스가 하나씩 늘어나면서 서브도메인이 추가됐는데, 브라우저에서 photo.yourdomain.com에 접속하면 아래 에러가 발생했다.

NET::ERR_CERT_COMMON_NAME_INVALID
연결이 비공개로 설정되어 있지 않습니다.

인증서에 photo.yourdomain.com이 포함돼 있지 않아서 생기는 문제였다.


해결: –expand 옵션

기존 인증서에 서브도메인을 추가할 때는 --expand 플래그를 써야 한다.

--expand 없이 서브도메인을 추가하려고 하면 아래 에러가 난다.

Missing command line flag or config entry for this setting:
You have an existing certificate that contains a portion of the domains you requested.
It contains these names: yourdomain.com
You requested these names for the new certificate: yourdomain.com, photo.yourdomain.com
Do you want to expand and replace this existing certificate with the new certificate?
(You can set this with the --expand flag)

certbot이 친절하게 --expand 쓰라고 안내해주긴 한다.


셸 스크립트로 관리

서브도메인이 추가될 때마다 명령어를 직접 치는 건 번거롭다. 스크립트로 관리하면 나중에 도메인 하나 추가할 때 -d 줄만 늘리면 된다.

#!/bin/bash
DOMAIN="yourdomain.com"
EMAIL="[email protected]"
SSL_DIR="/ssl"

certbot certonly --nginx \
  --non-interactive \
  --agree-tos \
  --expand \
  --email $EMAIL \
  -d $DOMAIN \
  -d photo.$DOMAIN \
  -d files.$DOMAIN \
  -d vault.$DOMAIN \
  --config-dir $SSL_DIR \
  --work-dir $SSL_DIR/work \
  --logs-dir $SSL_DIR/logs

if [ $? -ne 0 ]; then
    echo "인증서 발급 실패"
    exit 1
fi

echo "인증서 발급 성공"
nginx -t && systemctl restart nginx
옵션 설명
--expand 기존 인증서에 새 도메인 추가
--non-interactive 사용자 입력 없이 자동 실행
--agree-tos 서비스 약관 자동 동의
-d 인증서에 포함할 도메인 (여러 개 가능)

새 서브도메인이 생길 때마다 -d newservice.$DOMAIN \ 한 줄만 추가하고 스크립트를 실행하면 된다.


인증서 확인

발급 후 포함된 도메인 목록 확인:

certbot certificates --config-dir /ssl

certbot certificates 결과 - 서브도메인 목록 확인

인증서에 서브도메인이 모두 포함된 것을 확인할 수 있다. 브라우저에서 접속하면 자물쇠 아이콘을 클릭해서 인증서에 포함된 도메인 목록을 직접 확인할 수 있다.

브라우저 인증서 정보 - 서브도메인 포함 확인


자동 갱신 설정

Let’s Encrypt 인증서는 90일마다 갱신해야 한다. cron으로 자동화해뒀다.

crontab -e
0 3 1 */2 * certbot renew --config-dir /ssl --work-dir /ssl/work --logs-dir /ssl/logs && nginx -s reload

60일마다 새벽 3시에 갱신 시도한다. 갱신 후 Nginx를 리로드해서 새 인증서를 바로 적용한다.


정리

  • 기존 인증서에 서브도메인 추가할 때는 반드시 --expand 플래그 사용
  • 서브도메인 관리를 스크립트로 해두면 나중에 도메인 추가가 편하다
  • cron으로 자동 갱신 설정해두면 인증서 만료 걱정이 없다

다음 편에서는 Immich PostgreSQL DB를 매일 새벽 자동으로 백업하는 스크립트를 만든다.