NGINX Unit : Certbot을 이용한 SSL/TLS 구성

NGINX Unit 에서 SSL/TLS 액세스를 설정하려면 인증서 번들이 필요합니다. 자체 서명된 인증서를 사용할 수도 있지만, 웹사이트를 위해 인증 기관(CA)에서 인증서를 발급받는 것이 좋습니다. 이를 위해 비영리 인증 기관인 Let’s Encrypt에서 무료 인증서를 발급하는 EFF의 Certbot을 사용할 수 있습니다.

목차

1. SSL/TLS 인증서 생성
2. 인증서 갱신

1. 인증서 생성

1. NGINX Unit을 서버에 설치합니다.

2. Certbot을 설치하려면 EFF 웹사이트에서 소프트웨어 드롭다운 목록에서 “None of the above(위 항목 없음)”을 선택하고, 시스템 드롭다운 목록에서 서버의 운영 체제를 선택합니다.

3. Certbot 유틸리티를 실행하고 지침을 따라 인증서 번들을 생성하세요. 웹사이트의 도메인 이름을 입력하고 도메인 소유권을 검증하라는 메시지가 표시됩니다. 소유권 검증은 다양한 방식으로 수행할 수 있습니다. 가장 쉬운 방법 중 하나는 Certbot이 특정 파일을 로컬에 저장하고 이를 도메인 이름으로 접근하도록 설정하는 webroot 방법입니다. NGINX Unit을 임시 경로로 포트 80에서 구성합니다.

{
    "listeners": {
        "*:80": {
            "pass": "routes/acme"
        }
    },

    "routes": {
        "acme": [
            {
                "match": {
                    "uri": "/.well-known/acme-challenge/*"
                },

                "action": {
                    "share": "/var/www/www.example.com$uri/"
                }
            }
        ]
    }
}

공유 디렉터리가 NGINX Unit 라우터 프로세스 사용자 계정(일반적으로 unit:unit)에서 액세스 가능하도록 설정합니다.

다음으로, Certbot을 실행하고 공유 디렉터리를 webroot 경로로 제공하세요.

$ certbot certonly --webroot -w /var/www/www.example.com/ -d www.example.com

이전 방법을 사용할 수 없는 경우, DNS 레코드를 사용하여 도메인 소유권을 검증합니다.

$ certbot certonly --manual --preferred-challenges dns -d www.example.com

Certbot은 도메인 소유권을 증명하기 위해 DNS 항목을 업데이트하는 방법에 대한 지침을 제공합니다.

모든 Certbot 명령은 결과로 생성된 .pem 파일을 다음 경로에 저장됩니다.

/etc/letsencrypt/
└── live/
    └── www.example.com
        ├── cert.pem
        ├── chain.pem
        ├── fullchain.pem
        └── privkey.pem


| 메모

Certbot은 다른 검증 방법(인증기기)도 제공하지만, 간결성을 위해 여기서는 생략되었습니다.

4. NGINX Unit에 적합한 인증서 번들을 생성한 후, 이를 NGINX Unit의 제어 API의 인증서 섹션에 업로드합니다.

$ cat /etc/letsencrypt/live/www.example.com/fullchain.pem  \
      /etc/letsencrypt/live/www.example.com/privkey.pem > bundle1.pem
$ curl -X PUT --data-binary @bundle1.pem  \
       --unix-socket /path/to/control.unit.sock  \
       http://localhost/certificates/certbot1

5. NGINX Unit에서 업로드된 인증서 번들을 사용하도록 리스너를 생성하거나 업데이트합니다.

$ curl -X PUT --data-binary  \
      '{"pass": "applications/ssl_app", "tls": {"certificate": "certbot1"}}'  \
      --unix-socket /path/to/control.unit.sock  \
      'http://localhost/config/listeners/*:443'

6. HTTPS를 통해 웹사이트에 접근합니다.

$ curl https://www.example.com -v

      ...
      * TLSv1.3 (OUT), TLS handshake, Client hello (1):
      * TLSv1.3 (IN), TLS handshake, Server hello (2):
      * TLSv1.3 (IN), TLS Unknown, Certificate Status (22):
      * TLSv1.3 (IN), TLS handshake, Unknown (8):
      * TLSv1.3 (IN), TLS Unknown, Certificate Status (22):
      * TLSv1.3 (IN), TLS handshake, Certificate (11):
      * TLSv1.3 (IN), TLS Unknown, Certificate Status (22):
      * TLSv1.3 (IN), TLS handshake, CERT verify (15):
      * TLSv1.3 (IN), TLS Unknown, Certificate Status (22):
      * TLSv1.3 (IN), TLS handshake, Finished (20):
      * TLSv1.3 (OUT), TLS change cipher, Client hello (1):
      * TLSv1.3 (OUT), TLS Unknown, Certificate Status (22):
      * TLSv1.3 (OUT), TLS handshake, Finished (20):
      * SSL connection using TLSv1.3 / TLS_AES_256_GCM_SHA384
      * ALPN, server did not agree to a protocol
      * Server certificate:
      *  subject: CN=www.example.com
      *  start date: Sep 21 22:10:42 2020 GMT
      *  expire date: Dec 20 22:10:42 2020 GMT
      ...

2. 인증서 갱신

Certbot은 인증서를 수동으로 또는 자동으로 갱신할 수 있게 해줍니다. 수동 갱신 및 롤오버의 경우 아래와 같이 Certbot의 명령문을 사용합니다.

1. 앞서 설명한 단계를 반복하여 인증서를 갱신하고, 새로운 번들을 다른 이름으로 업로드합니다.

$ certbot certonly --standalone

      What would you like to do?
      - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
      1: Keep the existing certificate for now
      2: Renew & replace the cert (may be subject to CA rate limits)
$ cat /etc/letsencrypt/live/www.example.com/fullchain.pem  \
      /etc/letsencrypt/live/www.example.com/privkey.pem > bundle2.pem
$ curl -X PUT --data-binary @bundle2.pem  \
       --unix-socket /path/to/control.unit.sock  \
       http://localhost/certificates/certbot2

이제 두 개의 인증서 번들이 업로드되었습니다. NGINX Unit에서는 이를 certbot1과 certbot2로 인식합니다. 선택적으로 인증서 섹션을 조회하여 만료 날짜, 주체, 발급자 등의 일반적인 세부 사항을 확인할 수 있습니다.

$ curl --unix-socket /path/to/control.unit.sock  \
       http://localhost/certificates

리스너를 업데이트하여 갱신된 인증서 번들로 전환합니다.

$ curl -X PUT --data-binary 'certbot2'  \
      --unix-socket /path/to/control.unit.sock  \
      'http://localhost/config/listeners/*:443/tls/certificate'

| 메모

NGINX Unit을 종료할 필요는 없습니다. 인증서 롤오버 동안 서버는 계속 온라인 상태를 유지할 수 있습니다.

만료된 인증서 번들을 삭제합니다.

curl -X DELETE --unix-socket /path/to/control.unit.sock  \
      'http://localhost/certificates/certbot1'

또한, 리스너에 여러 인증서 번들을 구성하여 Unit의 SNI(Secure Name Indication) 지원을 활용할 수 있습니다.

예를 들어, http://www.example.com과 cdn.example.com의 두 도메인에 대해 Certbot을 사용하여 Let’s Encrypt 인증서를 성공적으로 얻었다고 가정합니다. 먼저, 앞서 설명한 단계를 사용하여 이를 Unit에 업로드합니다.

$ cat /etc/letsencrypt/live/cdn.example.com/fullchain.pem  \
      /etc/letsencrypt/live/cdn.example.com/privkey.pem > cdn.example.com.pem
$ cat /etc/letsencrypt/live/www.example.com/fullchain.pem  \
      /etc/letsencrypt/live/www.example.com/privkey.pem > www.example.com.pem
$ curl -X PUT --data-binary @cdn.example.com.pem  \
       --unix-socket /path/to/control.unit.sock  \
       http://localhost/certificates/cdn.example.com

       {
           "success": "Certificate chain uploaded."
       }
$ curl -X PUT --data-binary @www.example.com.pem  \
       --unix-socket /path/to/control.unit.sock  \
       http://localhost/certificates/www.example.com

       {
           "success": "Certificate chain uploaded."
       }



다음으로, 리스너를 구성하고 tls/certificate 옵션에 두 인증서 번들을 JSON 값으로 요청합니다.

$ curl -X PUT --data-binary '{"certificate": ["cdn.example.com", "www.example.com"]}'  \
      --unix-socket /path/to/control.unit.sock  \
      'http://localhost/config/listeners/*:443/tls'

NGINX Unit은 나머지 작업을 자동으로 처리하며, 두 도메인 이름에 대한 각 들어오는 연결에 대해 어떤 인증서 번들을 사용할지 자동으로 결정합니다.

| 메모

현재 Certbot에는 Unit에서 자동 인증서 롤오버를 활성화하는 설치자 플러그인이 없습니다. 그러나 여기 나열된 명령어를 사용하여 Certbot의 훅을 설정하여 동일한 효과를 얻을 수 있습니다.

NGINX Unit에 대해 더 많은 정보를 알고싶으시다면 NGINX STORE NGINX Unit을 방문해주세요.

NGINX STORE를 통한 솔루션 도입 및 기술지원 무료 상담 신청

* indicates required