Tutorial of automated Letsencrypt certificates with nginx

지난 포스팅에서는 certbot을 사용하여 gitlab의 인증서를 설치하는 법에 대해서 작성하였고, 자동으로 인증서를 재발행하도록 해 보아야겠다고 생각했었는데, 오늘은 엔진엑스에 인증서를 설정하고 자동으로 갱신되도록 하는 부분에 대해 작성해 보려 한다.

지난 포스팅 이후에 인증서 재발행을 간단히 실행해 보고, 문제가 될 수 있는 지점을 하나 발견하였다. –manual 옵션으로 인증서를 발행한 경우에는 certbot renew 명령으로 인증서 재발행이 불가능하다는 것이다.

기본적으로 certbot은 인증서를 생성하는 과정에서 해당 도메인에 접속가능한 것을 확인한 후에 인증서를 발행해 준다. 인증서를 수동으로 발행할 때에도 정해진 경로에 해당 파일을 생성하고 certbot에서 생성한 키를 파일 내용으로 적어서 저장한 후, 이후 과정을 진행했었다.

–manual을 쓰지 않아야 한다면, 명령줄 하나만으로도 가능하지 않을까라는 생각이 들었고, 어렵지 않게 파악한 명령줄은 다음과 같다.

certbot certonly \
  --webroot -w /var/www/blog.osg.kr \
  -d blog.osg.kr \
  --agree-tos

위에 입력한 옵션들에 대한 설명은 다음과 같다.

certonly(부명령어)는 인증서를 발행까지만 하고 자동 설치는 하지 않을 때 사용한다.
–webroot는 위에서 이야기한 인증 파일을 둘 경로를 지정할 때 사용하며, -w 옵션으로 해당 경로를 설정한다. 이 옵션을 사용할 때는 해당 경로를 미리 생성해 놓아야 한다.
-d는 SSL 인증서를 발행할 대상 도메인 이름을 지정할 때 사용한다.
–agree-tos는 이용약관에 동의한다는 것을 옵션으로 설정하는 것이다.

위와 같이 입력하고 실행하면 되는데, 뭔가 빠진 느낌이 들지 않는가. 그렇다. 위의 명령어를 실행하기 전에 먼저 해 주어야 할 것이 있다. 그건 바로 nginx에 .well-known 디렉토리에 대한 경로를 설정해 주어야 하는 것이다.

server {
    listen 80;
    server_name blog.osg.kr;

    ...
    
    location /.well-known/acme-challenge {
        root /var/www/blog.osg.kr/;
    }
}

파랗게 적은 부분은 .well-known/acme-challenge의 경로의 root를 설정해 주는 것이다. root로 설정했기 때문에 실제 파일의 경로는 아래와 같은 경로가 된다. 이제 nginx를 재시작 해 준다.

/var/www/blog.osg.kr/.well-known/acme-challenge/인증파일명

위에서 언급했던 certbot 명령줄을 입력해 주면, certbot이 위의 파일을 엑세스 한 후 해당 파일을 삭제하고, 최종적으로 인증서를 발행해준다. 인증서 발행 경로를 따로 지정하지 않았으므로 /etc/letsencrypt/live/blog.osg.org에 인증서가 발행되게 된다.

인증서 발행 후에는 nginx의 설정 파일에 아래와 같이 추가로 HTTPS 접속에 대한 설정을 해 주어야 한다. 인증서 적용에 필요한 부분만 적었기에 다른 부분들은 생략하였다.

server {
    listen 443 ssl;
    server_name blog.osg.kr;

    ...

    ssl_certificate /etc/letsencrypt/live/blog.osg.kr/fullchain.pem;
    ssl_certificate_key /etc/letsencrypt/live/blog.osg.kr/privkey.pem;
}

SSL은 공개키 알고리즘을 사용하므로 ssl_certificate은 full chaining된 인증서의 경로를 적어주면 되고, ssl_certificate_key는 해당 인증서에 대한 개인키 경로를 적어주면 된다.

이제 엔진엑스를 재시작한 후, 자신의 도메인에 접속(필자의 경우 https://blog.osg.kr)하면 다음과 같이 자물쇠 표시가 된다.

이제 이 경로를 통해서 주고 받는 패킷들은 공개키 알고리즘을 사용해서 암/복호화가 이루어진다.

이제 앞서 이야기한 것처럼 인증서를 자동으로 재발행하는 게 가능하다.

certbot renew

라는 명령어 한 줄이면, 발행한 모든 인증서를 갱신해 준다. 하지만 발행한 지 일정 시간이 지나지 않으면 아직 발행할 때가 아니라며 인증서를 갱신해 주지 않는다.

이럴 때 강제로 인증서를 갱신하는 옵션이 있다.

certbot renew --force-renewal

–force-renewal 옵션을 추가로 적어주기만 하면, 인증서가 자동으로 갱신된다.

이제 해당 명령을 쉘스크립트로 생성하고, crontab에 원하는 주기에 한 번씩 실행되도록 등록해 주면 모든 준비가 끝난다. 인증서 갱신 때문에 인증서 설정을 새로한다든가 하지 않아도 된다. 단, 갱신된 인증서를 적용하려면 웹서버를 재시작해 주어야 한다. 웹서버 재시작까지 스크립트로 미리 준비해 둔다면, 별도로 웹서버를 재시작할 필요도 없을 것이다.

아참, 아직 crontab에 등록하는 것까지는 하지 않았다. 조만간 실행해 보고 잘 되면 추가로 포스팅 하도록 하겠다.

이제 인증서 발행과 설정 때문에 리소스를 과도하게 투입하지 않아도 된다. 사람이 손으로 일일이 설정하는 것들은 자동화해야 한다. 이렇게 자동화하면 아무리 많은 인증서도 자동으로 갱신되니 신경쓸 필요가 없다. 모든 설정이 끝났다면 인증서 갱신에 대한 걱정은 내려놓고, 집중해야 할 개발업무로 달려가면 된다.

Leave a Comment