Nginx SSL 인증서 및 HTTPS 리디렉션 오류


소개

Cerbot은 인증서 획득 프로세스를 자동화하고 HTTPS 프로세스로 리디렉션을 지원하지만 여전히 Nginx 웹 서버에서 발생할 수 있는 오류가 있습니다.

이 가이드의 예제는 Ubuntu 22.04 서버에서 테스트되었지만 대부분의 Nginx 설치에 적용할 수 있습니다. 디렉토리와 경로가 약간 다를 수 있지만 이러한 오류의 대부분은 Nginx의 표준화된 구성 파일 범위 내에서 해결할 수 있습니다.

이 튜토리얼에서는 Nginx 서버에 대한 TLS/SSL 인증서 및 HTTPS 리디렉션 연결을 설정할 때 나타날 수 있는 일반적인 오류에 대해 알아봅니다. 또한 이러한 리디렉션 오류의 가능한 원인을 식별하고 수정하는 방법을 배웁니다.

Nginx 오류 로그 검사

이 자습서에 제시된 오류 및 해결 방법은 일반적인 경우이지만 완전하지는 않습니다. Nginx가 유효한 문장으로 인식하는 구조를 깨뜨리는 구문 오류의 특성으로 인해 다음 오류는 Nginx가 응답하는 방법에 대한 지침일 뿐입니다. 종종 하나의 오류가 다른 오류로 연쇄될 수 있으며 오류는 더 크거나 별도의 문제를 나타낼 수 있습니다. 특정 상황과 설정은 다를 수 있습니다.

항상 Nginx 오류 로그를 참조하여 실행 중인 목록을 볼 수 있습니다.

  1. sudo cat /var/log/nginx/error.log

서버 블록에 대한 리디렉션 지시문 확인

웹 사이트가 HTTP에서 HTTPS로 리디렉션되지 않는 문제가 발생하는 경우 구성 파일에서 설정한 지시문에 문제가 있을 수 있습니다. 특히 listen 지시문은 적절한 포트(이 경우 암호화된 HTTPS 트래픽을 나타내는 443)를 가리켜야 합니다. 컨텍스트를 위해 Nginx 웹 서버에 대한 서버 도메인 블록을 설정하는 경우 구성은 다음 구조를 따를 수 있습니다.

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

        root /var/www/example.com/html;
        index index.html index.htm index.nginx-debian.html;

        server_name example.com www.example.com;

        location / {
                try_files $uri $uri/ =404;
        }
}

이 파일의 내용은 여러 지시문에 대한 세부 정보를 제공하지만 주의해야 할 가장 중요한 내용은 listen입니다. 현재 이 지시문은 Nginx의 기본값인 80 포트에 대한 수신 요청만 허용합니다. 이 포트는 HTTPS가 아닌 HTTP 트래픽용이기도 합니다. HTTP 트래픽을 HTTPS로 리디렉션하려면 포트 443을 포함하도록 listen 지시문을 업데이트해야 합니다.

이를 효율적으로 수행할 수 있는 한 가지 방법은 Let’s Encrypt와 같은 인증 기관(CA)에서 TLS/SSL 인증서를 얻는 것입니다. 웹사이트에 대한 인증서가 있으면 웹 서버에 대해 암호화된 HTTPS를 활성화하는 데 도움이 됩니다.

또한 이 인증서를 얻고 설치하는 것은 Nginx용 플러그인이 있는 Certbot이라는 소프트웨어 클라이언트를 통해 Nginx에 대해 완전히 자동화됩니다. Certbot이 모든 HTTP 트래픽을 HTTPS로 리디렉션하고 직접 HTTP 트래픽을 허용하지 않도록 Nginx 구성 파일을 자동으로 구성하도록 허용할 수 있습니다. 원하는 경우 이 작업을 수동으로 수행할 수도 있으며 동일한 원칙이 적용됩니다. Let’s Encrypt를 사용하여 Nginx를 보호하는 방법에 대한 자습서에서 이 작업을 수행하는 방법에 대해 자세히 알아보십시오. 이 자습서의 목적을 위해 Let’s Encrypt를 통해 인증서를 얻었으며 구성 파일은 다음과 같이 업데이트됩니다.

server {

        root /var/www/example.com/html;
        index index.html index.htm index.nginx-debian.html;

        server_name example.com www.example.com;

        location / {
                try_files $uri $uri/ =404;
        }

    listen [::]:443 ssl ipv6only=on; # managed by Certbot
    listen 443 ssl; # managed by Certbot
    ssl_certificate /etc/letsencrypt/live/example.com/fullchain.pem; # managed by Certbot
    ssl_certificate_key /etc/letsencrypt/live/example.com/privkey.pem; # managed by Certbot
    include /etc/letsencrypt/options-ssl-nginx.conf; # managed by Certbot
    ssl_dhparam /etc/letsencrypt/ssl-dhparams.pem; # managed by Certbot


}

server {
        if ($host = www.example.com) {
                return 301 https://$host$request_uri;
        } # managed by Certbot


        if ($host = example.com) {
                return 301 https://$host$request_uri;
        } # managed by Certbot


        listen 80;
        listen [::]:80;

        server_name example.com www.example.com;
        return 404; # managed by Certbot
}

이 서버 도메인 블록을 첫 번째 예와 비교하면 SSL 인증서를 설정하기 위해 Certbot이 관리하는 자동화된 단계의 결과로 변경된 사항을 평가할 수 있습니다. 더 중요한 것은 listen 지시문이 이제 포트 443을 가리키고 있으며 이는 HTTPS 연결이 허용됨을 의미합니다. Let’s Encrypt를 통해 Certbot이 생성한 인증서와 키도 이제 서버 블록과 연결됩니다.

또한 Certbot은 서버 블록을 재구성하여 모든 HTTP 트래픽을 HTTPS로 리디렉션합니다. 이제 포트 80에서 원래 수신 지시문을 처리하는 추가 서버 블록이 있습니다. 이 새로운 서버 블록은 $host 변수에 대한 조건부 검사를 수행하여 도메인에 대한 모든 트래픽을 포착합니다. 이것은 조건부 if 지시문으로 실행됩니다. 이러한 지시문은 변수가 도메인과 일치하는지 확인한 다음 Nginx는 301 리디렉션을 사용하여 사이트의 HTTPS 버전으로 요청을 보냅니다. 또한 안전 장치로서 조건부 리디렉션을 통과하는 모든 트래픽은 404 오류로 포착됩니다.

그러나 여전히 문제가 있는 경우 방화벽 설정을 확인하고 필요한 경우 조정할 수 있습니다.

방화벽 설정 조정

TLS/SSL 인증서를 설정한 후에도 웹 브라우저가 응답하지 않으면 방화벽 설정에 문제가 있을 수 있습니다. 이전 섹션에서 언급했듯이 Let’s Encrypt 자습서를 따른 경우 HTTP 및 HTTPS의 리디렉션이 구성 파일에서 listen 지시문으로 자동 설정됩니다. 따라서 오류의 가능한 원인 중 하나는 방화벽이 포트 443에서 HTTPS 트래픽을 허용하지 않는다는 것입니다.

방화벽에서 현재 열려 있는 포트의 상태를 확인하려면 다음 명령을 실행할 수 있습니다. 이 자습서는 복잡하지 않은 방화벽(UFW)을 사용하므로 배포판에 따라 다를 수 있습니다.

  1. sudo ufw status
Status: active

To                         Action      From
--                         ------      ----
OpenSSH                    ALLOW       Anywhere
Nginx HTTP                 ALLOW       Anywhere
OpenSSH (v6)               ALLOW       Anywhere (v6)
Nginx HTTP (v6)            ALLOW       Anywhere (v6)

출력에 다음과 유사한 목록이 반영되면 방화벽이 현재 HTTP의 요청을 수락하기 위해서만 열려 있음을 의미합니다. 이러한 설정을 조정하려면 포트 443을 통해 TLS/SSL 암호화 트래픽을 허용하는 Nginx HTTPS 프로필을 추가하려고 합니다. 이렇게 하려면 다음 명령을 실행합니다.

  1. sudo ufw allow 'Nginx HTTPS'

Rule added 출력을 수신했다면 이 프로필을 목록에 성공적으로 추가한 것입니다. 상태를 확인하여 확인할 수 있습니다.

  1. sudo ufw status
Status: active

To                         Action      From
--                         ------      ----
OpenSSH                    ALLOW       Anywhere
Nginx HTTP                 ALLOW       Anywhere
Nginx HTTPS                ALLOW       Anywhere
OpenSSH (v6)               ALLOW       Anywhere (v6)
Nginx HTTP (v6)            ALLOW       Anywhere (v6)
Nginx HTTPS (v6)           ALLOW       Anywhere (v6)

참고: HTTP 및 HTTPS 포트 연결을 모두 여는 Nginx Full이라는 사용 가능한 Nginx 프로필이 있습니다. 목록을 정리하려면 sudo ufw delete allow Nginx HTTPsudo ufw delete allow Nginx HTTPS를 사용하여 두 규칙을 제거하고 다음 규칙을 추가할 수 있습니다.

  1. sudo ufw allow 'Nginx Full'

그러면 방화벽이 HTTP 및 HTTPS 트래픽의 연결을 수락할 준비가 됩니다.

이제 Nginx HTTP 및 HTTPS 프로필이 모두 나열되고 포트 443이 열려 있으며 요청이 HTTPS로 리디렉션됩니다.

TLS/SSL 인증서로 안전하게 리디렉션 설정

HTTP를 HTTPS로 리디렉션한다는 것은 암호화된 트래픽 연결을 허용한다는 의미이며 이는 일반적으로 TLS/SSL 인증서로 확인됩니다. 그러나 여전히 브라우저 수준에서 가능한 오류 메시지가 있습니다. 이러한 오류 메시지는 Nginx 서버에 문제가 있음을 의미하는 것이 아니라 인증서 자체에 문제가 있음을 의미합니다.

예를 들어 자체 서명된 SSL 인증서를 사용하는 경우 Let’s Encrypt와 같은 인증 기관(CA)에서 이를 확인하지 않습니다. 따라서 https://example.com에서 브라우저로 이동하면 방문자에게 이 사이트가 안전하지 않다는 경고 메시지 프롬프트가 표시될 수 있습니다.

이 시나리오에서는 연결이 비공개가 아니며 NET::ERR_CERT_AUTHORITY_INVALID라는 특정 오류가 있다는 오류가 있습니다. 고급 옵션을 누르면 인증서가 안전하지 않음에도 불구하고 이를 능가할 수 있습니다.

고급 옵션은 example.com을 적절하게 식별할 수 없다고 설명합니다. 자체 서명된 SSL 인증서를 사용하여 웹 서버를 설정했기 때문에 이것이 사실이 아닐 수도 있지만 이것이 귀하의 사이트를 방문하는 모든 사람이 인식하는 방식입니다.

Proceed to... 옵션을 눌러 웹 사이트로 계속 이동할 수 있지만 사이트를 방문할 때 이러한 유형의 보안 및 개인 정보 보호 메시지를 받는 것은 좋지 않은 사용자 경험입니다. CA에서 확인된 인증서를 사용하려고 합니다. Let’s Encrypt를 사용하여 Nginx를 보호하는 방법에 대한 자습서를 읽고 이를 설정할 수 있습니다.

그러나 Let’s Encrypt를 통해 TLS/SSL 인증서를 설정한 경우에도 다음 메시지를 받을 수 있습니다.

이 메시지는 네트워크 오류에 현재 SSL/TLS 인증서가 만료되었음을 의미하는 NET::ERR_CERT_DATE_INVALID가 표시되기 때문에 원본 연결이 비공개 메시지가 아닙니다. Let’s Encrypt 인증서는 90일 동안만 유효합니다. Let’s Encrypt를 설치할 때 certbot 패키지를 사용한 경우 다음 30일 이내에 만료되는 인증서에 대한 확인이 예약되며 systemd를 통해 하루에 두 번 실행됩니다.

다음을 사용하여 타이머의 상태를 확인할 수 있습니다.

  1. sudo systemctl status snap.certbot.renew.service

출력에서 인증서 갱신이 활성화되었음을 확인할 수 있습니다.

그러나 인증서가 만료되어 강제로 갱신하려는 경우 다음 명령을 사용하여 갱신할 수 있습니다. 이것은 인증서를 갱신하려는 다른 도메인이 있는 경우에도 유용합니다.

  1. certbot certonly –force-renew -d example.com

certbot 패키지에는 /etc/cron.d가 포함된 인증서 갱신 스크립트가 포함되어 있지만 다른 옵션도 있습니다. 예를 들어 갱신 후 다른 작업을 실행할 수 있도록 Certbot으로 renew_hook 옵션을 설정할 수 있습니다. 이렇게 하려면 Certbot 갱신 구성 파일에 renew_hook를 추가해야 합니다. 선호하는 텍스트 편집기로 파일을 열어 시작합니다.

  1. sudo nano /etc/letsencrypt/renewal/example.com.conf

파일 내부에 있으면 갱신된 인증서를 사용하도록 설정할 수 있도록 웹 대면 서비스를 다시 로드하기 위해 마지막 줄에 후크를 추가합니다.

renew_hook = systemctl reload your_service

완료되면 파일을 저장하고 닫을 수 있습니다. nano를 사용하는 경우 CTRL + X, Y를 누른 다음 ENTER를 누릅니다.

인증서 갱신 프로세스를 설정할 때 무엇을 선택하든 다음 명령을 사용하여 의도한 대로 certbot이 갱신 프로세스를 실행하고 있는지 항상 확인할 수 있습니다.

  1. sudo certbot renew --dry-run

마지막으로 sudo nginx -t로 구문 오류를 확인한 다음 sudo systemctl restart nginx로 Nginx를 다시 시작하여 변경 사항이 구현되었는지 확인합니다. 이 모든 작업을 완료한 후 https://example.com에서 웹 브라우저로 이동하여 리디렉션이 올바르게 작동하는지 확인합니다.

결론

이 자습서에서는 Nginx 웹 서버 리디렉션, 특히 HTTP에서 HTTPS로의 일반적인 오류를 해결하는 방법을 배웠습니다. 이러한 솔루션 중 일부에는 구성 파일이 적절한 포트를 수신하도록 올바르게 설정되었는지 확인, 해당 연결을 수신하기 위해 방화벽을 여는 방법, 확인되지 않았거나 만료된 SSL/TLS 인증서와 관련하여 수신할 수 있는 보안 오류 메시지를 처리하는 방법이 포함됩니다. . Nginx에 대해 자세히 알아보려면 Ubuntu 22.04에 Nginx를 설치하는 방법을 확인하세요.