웹 보안 · 2 min read · Oct 12, 2025

NGINX 웹 서버에서 SSL 완벽한 전달 비밀성 구현하기

이 HOW-TO는 Debian 및 Ubuntu 시스템에서 NGINX 웹 서버와 함께 완벽한 전달 비밀성을 구현하는 과정을 설명합니다. 이 과정은 다른 GNU/Linux 시스템에 쉽게 적용할 수 있습니다.

간단히 말해, 완벽한 전달 비밀성은 다음을 보장합니다: “… 하나의 메시지가 손상되더라도 다른 메시지가 손상되지 않으며, 여러 메시지의 손상으로 이어질 수 있는 단일 비밀 값이 존재하지 않습니다.” 더 많은 정보는 http://en.wikipedia.org/wiki/Forward_secrecy#Perfect_forward_secrecy를 참조하십시오.

2014년 초 OpenSSL의 Heartbleed 취약점이 공개되었을 때, PFS는 SSL/TLS를 심각하게 사용하는 모든 시스템에 필수라는 것이 점점 더 분명해졌습니다.

내 결과와 비교하고 싶으시다면, 제 참조 구현은 https://www.ssllabs.com/ssltest/analyze.html?d=indietorrent.org에서 테스트할 수 있으며, 전송된 SSL 인증서 체인과 NGINX 헤더는 https://indietorrent.org에서 검토할 수 있습니다.

더 이상 지체하지 않고, NGINX를 구성하여 PFS를 구현해 보겠습니다.

NGINX의 구성 디렉토리로 이동합시다:

cd /etc/nginx/

충분히 강력한 Diffie-Hellman 매개변수를 생성해야 합니다. 일부는 4096 비트가 과도하며 시스템의 CPU에 불필요한 부담을 줄 것이라고 주장하지만, 현대의 컴퓨팅 파워로 볼 때 이는 가치 있는 타협처럼 보입니다. 더 많은 정보는 아래의 참고 문헌 섹션을 참조하십시오.

openssl dhparam -out dh4096.pem 4096

이 작업에 특정한 구성 파일을 포함 파일로 분리해 두는 것이 유용합니다. 이렇게 하면 많은 시스템에서 PFS를 구현하는 것이 더 간단해집니다.

vi /etc/nginx/perfect-forward-secrecy.conf

위 파일에 다음 내용을 붙여넣습니다:

ssl_protocols TLSv1 TLSv1.1 TLSv1.2;
ssl_prefer_server_ciphers on;
ssl_ciphers "EECDH+ECDSA+AESGCM EECDH+aRSA+AESGCM EECDH+ECDSA+SHA384 \
EECDH+ECDSA+SHA256 EECDH+aRSA+SHA384 EECDH+aRSA+SHA256 EECDH+aRSA+RC4 \
EECDH EDH+aRSA RC4 !aNULL !eNULL !LOW !3DES !MD5 !EXP !PSK !SRP !DSS !MEDIUM";
ssl_dhparam dh4096.pem;

NGINX 구성에서 위 파일을 포함하도록 수정합니다. NGINX의 기본 구성 파일(기본적으로 /etc/nginx/nginx.conf)의 http {} 블록의 하단에 다음 줄을 삽입합니다:

# 참조: https://community.qualys.com/blogs/securitylabs/2013/08/05/configuring-apache-nginx-and-openssl-for-forward-secrecy
# 이 줄은 .../sites-enabled/*를 포함하는 줄 이후에 와야 하며, 그렇지 않으면 SSLv3 지원이 우연히 다시 활성화될 수 있습니다.
include perfect-forward-secrecy.conf;

변경 사항을 적용하기 위해 NGINX를 재시작합니다:

service nginx restart

https://www.ssllabs.com/ssltest/analyze.html에서 테스트 결과가 빨간색으로 세션 재개(캐싱) 없음(할당된 ID가 있지만 수락되지 않음)을 표시하고 서버가 SNI를 구현하고 있다면, 최상위 http {} 블록에 다음을 추가합니다(즉, 이전에 추가한 부분 바로 아래에 nginx.conf에 추가합니다):

# 참조: http://forum.nginx.org/read.php?2,152294,152401#msg-152401
ssl_session_cache shared:SSL:10m;

다시 한 번 NGINX를 재시작하여 변경 사항을 적용합니다:

service nginx restart

위 테스트는 더 이상 이 문제를 보고하지 않아야 합니다(비록 이 문제가 전체 테스트 점수를 줄이지는 않지만).

더 나아가기: 장기 지속성을 가진 HTTP 엄격 전송 보안(HSTS) 구현하기

이것은 간단하며, 다음 조건을 충족하는 한 수행할 가치가 있습니다:

  1. 이 헤더가 설정된 모든 호스트에 대해 모든 리소스에 대해 SSL을 강제하고 싶습니다(즉, 해당 웹사이트의 모든 페이지).
  2. 이 헤더가 설정된 모든 호스트에서 요청된 리소스에 대해 SSL 경고를 수락하고 무시할 수 없는 상황을 감수할 수 있습니다. HSTS의 본질은 SSL 인증서와 관련된 경고 및 오류 조건을 무시할 수 없다는 것입니다.

이 헤더가 지원되지 않는 브라우저에서 의도하지 않은 결과를 초래할 수 있는지에 대한 정보를 찾기 위해 인터넷을 샅샅이 뒤졌지만, 결과는 없었습니다. 그러나 예를 들어 Internet Explorer 6에서 이 구현을 테스트하여 제 우려를 해소할 수 있었습니다. HSTS가 구현되지 않은 브라우저는 단순히 헤더를 무시합니다. 완벽합니다!

다음 줄을 /etc/nginx/perfect-forward-secrecy.conf의 하단에 추가하고 변경 사항을 저장합니다:

add_header Strict-Transport-Security "max-age=31536000; includeSubDomains";
# 이는 특정 클릭재킹 공격을 방지하지만, 다른 사이트가 귀하의 사이트를 프레임하는 것을 방지하므로 필요에 따라 삭제하거나 수정하십시오!
add_header X-Frame-Options SAMEORIGIN;

NGINX가 이러한 특정 변경 사항을 반영하도록 하려면 재시작 대신 다시 로드하면 됩니다:

service nginx reload

HSTS가 의도한 대로 작동하는지 확인하려면 https://www.ssllabs.com/ssltest/analyze.html에서 구현을 테스트할 수 있습니다. HSTS가 올바르게 구현되었다면, 점수 바로 아래에 “이 서버는 장기 지속성을 가진 HTTP 엄격 전송 보안을 지원합니다. 등급이 A+로 설정되었습니다.”라는 녹색 상자를 볼 수 있어야 합니다.

축하합니다!

이제 인터넷에서 가장 안전한 SSL/TLS 구현 중 하나를 갖추게 되었습니다.

참고 문헌:

Copyright © 2014 Ben Johnson

Share: X/Twitter LinkedIn

새 게시물을 받은 편지함에서 받기

스팸은 없습니다. 언제든지 구독 해지 가능합니다.