Article

우분투 NginX + Let's Encrypt

2분
우분투 NginX + Let's Encrypt

지난 방화벽 설정에 이어 또 헷갈렸던 명령어를 (미래의 나를 위해) 가져왔다. NginX에 Let's Encrypt를 설정하는데 내가 했었던 것, 의도하는 것을 ChatGPT한테 장황하게 상황 설명만 하다가 힘이 빠져서 꼭 남겨놔야 겠다는 생각이 들었다.


1. 서버 셋팅

우선 NginX에서 인증서를 받으려는 도메인을 각 다음과 같이 설정해둔다.

server {
    listen 80;
    listen [::]:80;

    server_name {{ SERVER_HOST }}

    location /.well-known {
      root /home/{{ USER_NAME }}/temp;
    }
}
...

저 위치만 굳이 별도로 처리하는 이유는 인증서 처리를 위한 영역이라는 것을 구분하고 싶었고 근래에는 웹서버를 프록시 용도로만 쓰다보니 굳이 별도의 root를 지정하고 싶지 않았다.


2. 인증서 생성

이후 letsencrypt 설치 후 다음 명령어를 실행한다.

sudo apt install letsencrypt
sudo certbot certonly --webroot --webroot-path=/home/{{ USER_NAME }}/temp -d {{ SERVER_HOST }} -d {{ SERVER_HOST_2 }} -d {{ SERVER_HOST_3 }} --dry-run

내부적인 정확한 원리는 알 수 없지만 이렇게 하면 letsencrypt에서 해당 경로에 파일을 올리고 해당 도메인으로 접근해서여러가지를체크하는 모양이다.

--dry-run은 해당 작업을 시뮬레이션으로 처리하는 옵션인데, letsencrypt의 경우 명령을 처리할 수 있는 횟수가 (일시적으로) 정해져 있기 때문에 작업을 무분별하게 실행하면 안된다. 시뮬레이션을 통해서 제대로 설정했는지 먼저 확인하고 이후 정상적으로 보이면 --dry-run을 제거하고 실제로 작동시킨다.

그리고 SSL/TLS 구성에 필요한 마지막 파일을 OpenSSL 명령으로 생성해준다.

sudo openssl dhparam -out /etc/ssl/certs/dhparams.pem 2048


3. 인증서 갱신 자동화

letsencrypt로 생성한 인증서는 3개월 마다 갱신을 해줘야하는데, 이걸 자동화하지 않으면 다음과 같은 상황을 맞이할 수 있다.

어떤 의미로... 바보 인증

sudo vi /etc/letsencrypt/renewal-hooks/deploy/restart-nginx.sh
#!/bin/bash

sudo service nginx reload
sudo chmod +x /etc/letsencrypt/renewal-hooks/deploy/restart-nginx.sh

restart가 아닌 reload를 사용하는 이유는 restart는 일시적인 다운타임이 발생하기 때문이다. 또한 스크립트를 실행할 수 있도록 실행 권한을 꼭 주자.

sudo certbot renew --deploy-hook "/etc/letsencrypt/renewal-hooks/deploy/restart-nginx.sh"

이렇게 등록해두면 인증서 갱신이 성공적으로 이뤄졌을 때 등록한 스크립트가 실행된다. 이제 갱신을 적절한 타이밍에 자동으로 진행하도록 처리해두자.

sudo crontab -e
10 5 * * 1 /usr/bin/certbot renew

앞에 규칙은 자신이 생각하는 이상적인 시간으로 바꿔서 쓰면 되겠다.


4. SSL/TLS 적용

초기에 설정했던 서버 설정을 다음과 같이 변경하자.

server {
    listen 80;
    listen [::]:80;
    listen 443 ssl http2;

    server_name {{ SERVER_HOST }};

    ssl_certificate "/etc/letsencrypt/live/{{ SERVER_HOST }}/fullchain.pem";
    ssl_certificate_key "/etc/letsencrypt/live/{{ SERVER_HOST }}/privkey.pem";
    ssl_dhparam "/etc/ssl/certs/dhparams.pem";

    location /.well-known {
        root /home/{{ USER_NAME }}/temp;
    }
        
    if ($scheme = http) {
        return 301 https://$server_name$request_uri;
    }
}

각각의 인증서 등록과 443 포트를 통한 통신이 가능하도록 설정해준다. 마지막으로 http로 접근한 사용자는 강제로 https로 변경하는 조건문을 추가해 주었다. https 통신이 가능한 상황에서 http로의 접근은 불필요하거니와 매우 위험하기 때문이다.

baealex
Series

우분투 서버 관리

2 / 2 포스트

시리즈 목록

2
우분투 NginX + Let's Encrypt읽는 중

댓글 0개