Ubuntu 18.04에서 Nginx용 자체 서명 SSL 인증서를 만드는 방법
소개
TLS(Transport Layer Security)와 이전 SSL(Secure Sockets Layer)은 일반 트래픽을 보호되고 암호화된 래퍼로 래핑하는 데 사용되는 웹 프로토콜입니다.
이 기술을 사용하여 서버는 외부 당사자가 메시지를 가로챌 가능성 없이 서버와 클라이언트 간에 안전하게 트래픽을 보낼 수 있습니다. 인증서 시스템은 또한 사용자가 연결 중인 사이트의 신원을 확인하는 데 도움을 줍니다.
이 가이드에서는 Ubuntu 18.04 서버에서 Nginx 웹 서버와 함께 사용하기 위해 자체 서명된 SSL 인증서를 설정하는 방법을 보여줍니다.
참고: 자체 서명된 인증서는 서버와 모든 클라이언트 간의 통신을 암호화합니다. 그러나 웹 브라우저에 포함된 신뢰할 수 있는 인증 기관(CA)에서 서명하지 않았기 때문에 사용자는 인증서를 사용하여 서버 ID를 자동으로 확인할 수 없습니다.
자체 서명된 인증서는 서버와 연결된 도메인 이름이 없고 암호화된 웹 인터페이스가 사용자를 향하지 않는 경우에 적합할 수 있습니다. 도메인 이름이 있으면 대부분의 경우 CA 서명 인증서를 사용하는 것이 좋습니다. 여기에서 Let’s Encrypt 프로젝트로 신뢰할 수 있는 무료 인증서를 설정하는 방법을 확인할 수 있습니다.
전제 조건
이 자습서를 따르려면 다음이 필요합니다.
- 루트가 아닌 사용자가
sudo
권한과 방화벽으로 구성된 Ubuntu 18.04 서버 1대. Ubuntu 18.04에 대한 초기 서버 설정에 따라 이러한 사용자 계정을 설정하는 방법을 배울 수 있습니다. - 또한 Nginx 웹 서버가 설치되어 있어야 합니다. 서버에 전체 LEMP(Linux, Nginx, MySQL, PHP) 스택을 설치하려면 Ubuntu 18.04에서 LEMP 설정에 대한 가이드를 따르세요.
- Nginx 웹 서버만 원하는 경우 대신 Ubuntu 18.04에 Nginx 설치 가이드를 따를 수 있습니다.
사전 요구 사항을 완료했으면 첫 번째 단계를 계속합니다.
1단계 - SSL 인증서 생성
TLS/SSL은 공개 인증서와 개인 키의 조합을 사용하여 작동합니다. SSL 키는 서버에서 비밀로 유지됩니다. 클라이언트로 전송되는 콘텐츠를 암호화하는 데 사용됩니다. SSL 인증서는 콘텐츠를 요청하는 모든 사람과 공개적으로 공유됩니다. 연결된 SSL 키로 서명된 콘텐츠를 해독하는 데 사용할 수 있습니다.
단일 명령으로 OpenSSL을 사용하여 자체 서명된 키 및 인증서 쌍을 생성할 수 있습니다.
- sudo openssl req -x509 -nodes -days 365 -newkey rsa:2048 -keyout /etc/ssl/private/nginx-selfsigned.key -out /etc/ssl/certs/nginx-selfsigned.crt
다음은 이 명령의 각 부분이 수행하는 작업에 대한 분석입니다.
sudo
:sudo
명령을 사용하면sudo
그룹의 구성원이 자신의 권한을 일시적으로 다른 사용자(수퍼유저 또는 기본적으로 루트 사용자). 루트 사용자나 다른 권한 있는 계정만 액세스할 수 있는/etc/
디렉토리 아래에 인증서와 키 쌍을 생성하기 때문에 이 경우에 필요합니다.openssl
: 이것은 OpenSSL 인증서, 키 및 기타 파일을 만들고 관리하기 위한 기본 명령줄 도구입니다.req
: 이 하위 명령은 X.509 인증서 서명 요청(CSR) 관리를 사용하도록 지정합니다. X.509는 SSL 및 TLS가 키 및 인증서 관리를 위해 준수하는 공개 키 인프라 표준입니다. 새 X.509 인증서를 생성하려고 하므로 이 하위 명령을 사용하고 있습니다.-x509
: 일반적으로 발생하는 인증서 서명 요청을 생성하는 대신 자체 서명된 인증서를 만들고 싶다고 유틸리티에 알려 이전 하위 명령을 추가로 수정합니다.-nodes
: 이는 OpenSSL이 암호로 인증서를 보호하는 옵션을 건너뛰도록 지시합니다. 서버가 시작될 때 사용자 개입 없이 파일을 읽을 수 있으려면 Nginx가 필요합니다. 암호는 다시 시작할 때마다 암호를 입력해야 하므로 이러한 일이 발생하지 않도록 합니다.-days 365
: 이 옵션은 인증서가 유효한 것으로 간주되는 기간을 설정합니다. 여기서는 1년으로 설정했습니다.-newkey rsa:2048
: 새 인증서와 새 키를 동시에 생성하도록 지정합니다. 이전 단계에서 인증서 서명에 필요한 키를 생성하지 않았으므로 인증서와 함께 생성해야 합니다.rsa:2048
부분은 2048비트 길이의 RSA 키를 만들도록 지시합니다.-keyout
: 이 줄은 OpenSSL에 우리가 만들고 있는 생성된 개인 키 파일을 배치할 위치를 알려줍니다.-out
: OpenSSL에 우리가 만들고 있는 인증서를 둘 위치를 알려줍니다.
앞에서 설명한 것처럼 이러한 옵션은 키 파일과 인증서를 모두 생성합니다. 이 명령을 실행한 후 인증서에 정보를 올바르게 포함하기 위해 서버에 대한 몇 가지 질문을 받게 됩니다.
프롬프트를 적절하게 작성하십시오. 가장 중요한 줄은 일반 이름(예: 서버 FQDN 또는 귀하의 이름)
을 요청하는 줄입니다. 서버와 연결된 도메인 이름을 입력하거나 서버의 공용 IP 주소를 입력해야 합니다.
전체 프롬프트는 다음과 같습니다.
OutputCountry Name (2 letter code) [AU]:US
State or Province Name (full name) [Some-State]:New York
Locality Name (eg, city) []:New York City
Organization Name (eg, company) [Internet Widgits Pty Ltd]:Bouncy Castles, Inc.
Organizational Unit Name (eg, section) []:Ministry of Water Slides
Common Name (e.g. server FQDN or YOUR name) []:server_IP_address
Email Address []:admin@your_domain.com
생성한 두 파일 모두 /etc/ssl
디렉토리의 적절한 하위 디렉토리에 배치됩니다.
OpenSSL을 사용하는 동안 클라이언트와 완전 순방향 보안 협상에 사용되는 강력한 Diffie-Hellman 그룹도 만들어야 합니다.
다음을 실행하여 이를 수행할 수 있습니다.
- sudo openssl dhparam -out /etc/nginx/dhparam.pem 4096
이 작업은 시간이 걸리지만 완료되면 /etc/nginx/dhparam.pem
에 구성 중에 사용될 강력한 DH 그룹이 생깁니다.
2단계 - SSL을 사용하도록 Nginx 구성
이제 /etc/ssl
디렉토리 아래에 키 및 인증서 파일이 생성되었으므로 이를 활용하려면 Nginx 구성을 수정해야 합니다.
먼저 SSL 키 및 인증서 파일 위치에 대한 정보로 구성 스니펫을 생성합니다. 그런 다음 향후 모든 인증서와 함께 사용할 수 있는 강력한 SSL 설정으로 구성 스니펫을 생성합니다. 마지막으로 SSL 요청을 적절하게 처리할 수 있도록 생성한 두 개의 구성 스니펫을 사용하여 Nginx 서버 블록을 조정합니다.
Nginx를 구성하는 이 방법을 사용하면 깨끗한 서버 블록을 유지하고 공통 구성 세그먼트를 재사용 가능한 모듈에 넣을 수 있습니다.
SSL 키 및 인증서를 가리키는 구성 스니펫 생성
먼저 원하는 텍스트 편집기를 사용하여 /etc/nginx/snippets
디렉터리에 새 Nginx 구성 스니펫을 만듭니다. 다음 예에서는 nano
를 사용합니다.
이 파일의 용도를 적절하게 구분하려면 이름을 self-signed.conf
로 지정하십시오.
- sudo nano /etc/nginx/snippets/self-signed.conf
이 파일 내에서 ssl_certificate
지시문을 인증서 파일로 설정하고 ssl_certificate_key
를 관련 키로 설정합니다. 다음과 같이 표시됩니다.
ssl_certificate /etc/ssl/certs/nginx-selfsigned.crt;
ssl_certificate_key /etc/ssl/private/nginx-selfsigned.key;
해당 줄을 추가했으면 파일을 저장하고 편집기를 종료합니다. nano
를 사용한 경우 CTRL + X
를 누른 다음 Y
, ENTER
를 눌러 이 작업을 수행할 수 있습니다.
강력한 암호화 설정으로 구성 스니펫 생성
다음으로 일부 SSL 설정을 정의하는 또 다른 스니펫을 생성합니다. 이렇게 하면 강력한 SSL 암호화 제품군으로 Nginx가 설정되고 서버 보안을 유지하는 데 도움이 되는 몇 가지 고급 기능이 활성화됩니다.
설정한 매개변수는 향후 Nginx 구성에서 재사용할 수 있으므로 파일에 일반 이름을 지정할 수 있습니다.
- sudo nano /etc/nginx/snippets/ssl-params.conf
Nginx SSL을 안전하게 설정하기 위해 인기 있는 소프트웨어에 사용되는 암호화 설정을 이해하는 데 유용하고 이해하기 쉬운 리소스인 Cipherlist.eu의 권장 사항을 적용합니다.
참고: Cipherlist.eu의 권장 설정은 강력한 보안을 제공합니다. 경우에 따라 클라이언트 호환성을 희생해야 합니다. 이전 클라이언트를 지원해야 하는 경우 "예, 레거시/오래된 소프트웨어에서 작동하는 암호화 제품군을 제공합니다.\라고 표시된 페이지의 링크를 클릭하여 액세스할 수 있는 대체 목록이 있습니다. 원하는 경우 해당 목록을 다음 예제 코드 블록의 콘텐츠로 대체할 수 있습니다.
사용할 구성의 선택은 지원해야 하는 항목에 따라 크게 달라집니다. 둘 다 훌륭한 보안을 제공합니다.
우리의 목적을 위해 제공된 설정 전체를 복사하지만 먼저 몇 가지 작은 수정이 필요합니다.
먼저 업스트림 요청에 대해 선호하는 DNS 확인자를 추가합니다. 이 가이드에서는 Google(8.8.8.8
및 8.8.4.4
)을 사용합니다.
둘째, 엄격한 전송 보안 헤더를 설정하는 줄을 주석 처리합니다. 이 줄의 주석을 제거하기 전에 잠시 시간을 내어 "사전 로드\ 기능을 읽어야 합니다. HSTS를 사전 로드하면 보안이 강화되지만 실수로 활성화하거나 잘못 활성화하면 광범위한 부정적인 결과를 초래할 수 있습니다.
ssl-params.conf
스니펫 파일에 다음을 추가합니다.
ssl_protocols TLSv1.3;
ssl_prefer_server_ciphers on;
ssl_dhparam /etc/nginx/dhparam.pem;
ssl_ciphers EECDH+AESGCM:EDH+AESGCM;
ssl_ecdh_curve secp384r1;
ssl_session_timeout 10m;
ssl_session_cache shared:SSL:10m;
ssl_session_tickets off;
ssl_stapling on;
ssl_stapling_verify on;
resolver 8.8.8.8 8.8.4.4 valid=300s;
resolver_timeout 5s;
# Disable strict transport security for now. You can uncomment the following
# line if you understand the implications.
#add_header Strict-Transport-Security "max-age=63072000; includeSubDomains; preload";
add_header X-Frame-Options DENY;
add_header X-Content-Type-Options nosniff;
add_header X-XSS-Protection "1; mode=block";
자체 서명된 인증서를 사용하고 있기 때문에 SSL 스테이플링이 사용되지 않습니다. Nginx는 경고를 출력하고 자체 서명된 인증서에 대한 스테이플링을 비활성화하지만 계속해서 올바르게 작동합니다.
완료되면 파일을 저장하고 닫습니다.
SSL을 사용하도록 Nginx 구성 조정
이제 스니펫이 있으므로 Nginx 구성을 조정하여 SSL을 활성화할 수 있습니다.
이 가이드에서는 /etc/nginx/sites-available
디렉터리에 있는 사용자 지정 서버 블록 구성 파일을 사용하고 있다고 가정합니다. 이 가이드는 또한 필수 Nginx 자습서의 규칙을 따르고 이 예제에서는 /etc/nginx/sites-available/your_domain
을 사용합니다. 필요에 따라 구성 파일 이름을 대체하십시오.
계속 진행하기 전에 현재 구성 파일을 백업하십시오.
- sudo cp /etc/nginx/sites-available/your_domain /etc/nginx/sites-available/your_domain.bak
이제 구성 파일을 열어 조정합니다.
- sudo nano /etc/nginx/sites-available/your_domain
내부에서 서버 블록은 아마도 다음과 유사하게 시작할 것입니다.
server {
listen 80;
listen [::]:80;
server_name your_domain www.your_domain.com;
root /var/www/your_domain.com/html;
index index.html index.htm index.nginx-debian.html;
. . .
}
파일의 순서가 다를 수 있으며 root
및 index
지시문 대신 location
, proxy_pass<가 있을 수 있습니다. /code> 또는 기타 사용자 지정 구성 문.
listen
지시문을 업데이트하고 SSL 스니펫을 포함하기만 하면 되므로 괜찮습니다. 그런 다음 이 기존 서버 블록을 수정하여 포트 443
에서 SSL 트래픽을 제공하고 새 서버 블록을 만들어 포트 80
에서 응답하고 자동으로 트래픽을 포트 443<으로 리디렉션합니다. /코드>.
참고: 모든 것이 제대로 작동하는지 확인할 때까지 302 리디렉션을 사용하십시오. 그런 다음 이를 영구 301 리디렉션으로 변경합니다.
기존 구성 파일에서 포트 443
및 ssl
을 사용하도록 두 개의 listen
문을 업데이트한 다음 이전 단계에서 생성한 두 개의 스니펫 파일을 포함합니다. :
server {
listen 443 ssl;
listen [::]:443 ssl;
include snippets/self-signed.conf;
include snippets/ssl-params.conf;
server_name your_domain.com www.your_domain.com;
root /var/www/your_domain.com/html;
index index.html index.htm index.nginx-debian.html;
. . .
}
다음으로 구성 파일에서 첫 번째 블록의 닫는 괄호(}
) 다음에 두 번째 서버 블록을 추가합니다.
. . .
server {
listen 80;
listen [::]:80;
server_name your_domain.com www.your_domain.com;
return 302 https://$server_name$request_uri;
}
이것은 포트 80
에서 수신하고 HTTPS로 리디렉션을 수행하는 베어본 구성입니다. 편집을 마치면 파일을 저장하고 닫습니다.
3단계 - 방화벽 조정
전제 조건 가이드에서 권장하는 대로 ufw
방화벽을 활성화한 경우 SSL 트래픽을 허용하도록 설정을 조정해야 합니다. 운 좋게도 Nginx는 설치 시 ufw
로 몇 개의 프로필을 등록합니다.
다음을 실행하여 사용 가능한 프로필을 검토할 수 있습니다.
- sudo ufw app list
다음과 같은 목록이 출력에 나타납니다.
OutputAvailable applications:
Nginx Full
Nginx HTTP
Nginx HTTPS
OpenSSH
sudo ufw status
를 입력하여 현재 설정을 확인할 수도 있습니다.
- sudo ufw status
웹 서버에 HTTP 트래픽만 허용됨을 의미하는 다음 출력이 생성될 것입니다.
OutputStatus: active
To Action From
-- ------ ----
OpenSSH ALLOW Anywhere
Nginx HTTP ALLOW Anywhere
OpenSSH (v6) ALLOW Anywhere (v6)
Nginx HTTP (v6) ALLOW Anywhere (v6)
HTTPS 트래픽을 허용하려면 "Nginx Full\ 프로필에 대한 권한을 업데이트하면 됩니다.
- sudo ufw allow 'Nginx Full'
그런 다음 중복 "Nginx HTTP\ 프로필 허용을 삭제합니다.
- sudo ufw delete allow 'Nginx HTTP'
sudo ufw status
를 실행한 후 다음 출력을 받아야 합니다.
- sudo ufw status
OutputStatus: active
To Action From
-- ------ ----
OpenSSH ALLOW Anywhere
Nginx Full ALLOW Anywhere
OpenSSH (v6) ALLOW Anywhere (v6)
Nginx Full (v6) ALLOW Anywhere (v6)
이 출력은 방화벽 조정이 성공했으며 Nginx에서 변경 사항을 활성화할 준비가 되었음을 확인합니다.
4단계 - Nginx에서 변경 사항 활성화
방화벽에 대한 변경 및 조정이 완료되면 Nginx를 다시 시작하여 새로운 변경 사항을 구현할 수 있습니다.
먼저 파일에 구문 오류가 없는지 확인합니다. sudo nginx -t
를 실행하여 이를 수행할 수 있습니다.
- sudo nginx -t
모든 것이 성공하면 다음과 같은 결과가 표시됩니다.
Outputnginx: [warn] "ssl_stapling" ignored, issuer certificate not found for certificate "/etc/ssl/certs/nginx-selfsigned.crt"
nginx: the configuration file /etc/nginx/nginx.conf syntax is ok
nginx: configuration file /etc/nginx/nginx.conf test is successful
처음에 경고를 확인하십시오. 앞서 언급했듯이 이 특정 설정은 자체 서명된 인증서가 SSL 스테이플링을 사용할 수 없기 때문에 경고를 생성합니다. 이것은 예상된 것이며 서버는 여전히 연결을 올바르게 암호화할 수 있습니다.
출력이 예제와 일치하면 구성 파일에 구문 오류가 없어야 합니다. 이 경우 Nginx를 안전하게 다시 시작하여 변경 사항을 구현할 수 있습니다.
- sudo systemctl restart nginx
새로운 변경 사항으로 시스템이 다시 시작되었으므로 테스트를 진행할 수 있습니다.
5단계 - 암호화 테스트
이제 SSL 서버를 테스트할 준비가 되었습니다.
웹 브라우저를 열고 주소 표시줄에 https://
다음에 서버의 도메인 이름 또는 IP를 입력합니다.
https://server_domain_or_IP
브라우저에 따라 생성한 인증서가 브라우저의 신뢰할 수 있는 인증 기관 중 하나에서 서명하지 않았기 때문에 경고를 받을 수 있습니다.

이 경고는 정상적인 현상입니다. 우리는 인증서의 암호화 측면에만 관심이 있으며 호스트의 신뢰성에 대한 제3자 검증에는 관심이 없습니다. "고급\을 클릭한 다음 호스트로 진행할 수 있는 링크가 제공됩니다.

이 시점에서 귀하의 사이트로 이동해야 합니다. 이 예에서 브라우저 주소 표시줄은 그 위에 "x\가 있는 자물쇠를 표시합니다. 이는 인증서를 확인할 수 없음을 의미합니다. 여전히 연결을 암호화하고 있습니다. 이 아이콘은 브라우저에 따라 다를 수 있습니다.
HTTP 콘텐츠를 HTTPS로 자동 리디렉션하는 두 개의 서버 블록으로 Nginx를 구성한 경우 리디렉션이 올바르게 작동하는지 확인할 수도 있습니다.
http://server_domain_or_IP
동일한 아이콘이 표시되면 리디렉션이 올바르게 작동했음을 의미합니다.
6단계 - 영구 리디렉션으로 변경
리디렉션이 올바르게 작동하고 암호화된 트래픽만 허용하려는 것이 확실한 경우 Nginx 구성을 수정하여 리디렉션을 영구적으로 만들어야 합니다.
서버 블록 구성 파일을 다시 엽니다.
- sudo nano /etc/nginx/sites-available/your_domain.com
return 302
를 찾아 return 301
로 변경합니다.
return 301 https://$server_name$request_uri;
파일을 저장하고 닫습니다.
구문 오류에 대한 구성을 확인하십시오.
- sudo nginx -t
준비가 되면 Nginx를 다시 시작하여 리디렉션을 영구적으로 만듭니다.
- sudo systemctl restart nginx
다시 시작하면 변경 사항이 구현되고 이제 리디렉션이 영구적입니다.
결론
클라이언트 연결에 강력한 암호화를 사용하도록 Nginx 서버를 구성했습니다. 이렇게 하면 요청을 안전하게 처리하고 외부인이 트래픽을 읽는 것을 방지할 수 있습니다. 또는 무료 TLS/SSL 인증서를 설치하고 웹 서버에서 암호화된 HTTPS를 활성화하는 인증 기관인 Let’s Encrypt에서 얻을 수 있는 자체 서명된 SSL 인증서를 사용하도록 선택할 수 있습니다. Ubuntu 18.04에서 Let’s Encrypt로 Nginx를 보호하는 방법에 대한 자습서에서 자세히 알아보십시오.