이 글에서는 Nginx 웹서버에서 SSL을 사용하기 위한 Site Config파일을 작성하는 방법을 다룹니다.
인증기관(CA)로부터 인증서(Certificate)를 발급 받아서 다음 두 개 파일을 이미 확보해 놓은 상태여야 하며, 아직 인증서를 발급받지 않은 경우 인증기관의 홈페이지를 통해 인증서를 발급받은 뒤 진행해야 합니다.
필요한 파일들:
- Certificate (*.crt)
- Private Key (*.key)
Nginx 설정파일 작성
server { listen 443; server_name {서버 도메인}; ssl on; ssl_certificate {인증서 파일 경로}; ssl_certificate_key {Private Key 파일 경로}; ssl_protocols SSLv2 SSLv3 TLSv1 TLSv1.1 TLSv1.2; ssl_ciphers ALL:!aNULL:!EXPORT56:RC4+RSA:+HIGH:+MEDIUM:+LOW:+SSLv2:+EXP; ssl_prefer_server_ciphers on; ... }
인증서와 비밀키 경로 지정: ssl_certificate, ssl_certificate_key
7~8줄에 발급받은 인증서 파일과 비밀키(Private Key)의 경로를 지정해 줍니다. 여기서 주의할 점은 공개키(Public Key)가 아닌, 비밀키(Private Key)의 경로를 지정해 줘야 한다는 점입니다. (사실, 여기에 실수로 Public Key를 지정하더라도 Nginx 재시작 과정에서 오류가 발생할 것입니다.)
반면, Public Key의 경로는 지정해 주지 않아도 되는데, 이는 인증서 내에 Public Key가 포함되어 있기 때문입니다. 인증서를 발급받는 과정에서 Public Key를 업로드하는 과정이 포함되어 있었을 것입니다. 이 때 업로드한 Public Key가 인증서에 포함되고, CA가 여기에 전자서명을 함으로써 Public Key가 누구의 소유인지 보증하게 됩니다. Client측에서 인증서를 받으면 이를 CA의 Public Key로 해독해서 서버의 Public Key를 추출하고 검증할 수 있습니다.
+. 간혹, 서버측에서 Key pair까지 생성해 주는 경우가 있는데, 이 경우 Private Key를 인증서 발급 서버로부터 다운로드 받게 됩니다. RSA Key pair를 어떻게 생성해야 하는지 잘 모르는 분들을 위해 편의를 제공하는 것일 수도 있지만, 보안상 그리 좋은 방법은 아닙니다. Private Key는 원칙상 서버에서 떠나면 안 되는데, 아예 Key pair를 외부에서 생성해서 가지고 들어온 경우이기 때문입니다.
Private Key의 경로를 지정해 주는 이유는 SSL Handshake과정에서 Client가 Pre master secret(PMS; 실질적인 보안 통신 과정에 사용될 대칭키를 생성하기 위한 Seed라 생각하면 됩니다.)을 전송할 때 서버의 Public Key로 암호화해서 전송하는데, 이를 수신한 서버측에서 복호화하기 위해 필요한 것이 바로 Private Key이기 때문입니다.
따라서 HTTPS 서버를 세팅할 때 인증서와 Private Key의 경로만 지정해 주면 됩니다.
허용할 Cipher Suite 설정: ssl_ciphers, ssl_prefer_ciphers
11번째 줄에 지정한 ssl_ciphers에는 보안 통신 과정에서 사용할 암호화 알고리즘을 지정합니다.
SSL 이라고 해서 다 똑같은 암호화 알고리즘을 사용하는 것이 아니라, Client와의 협상(Negotiation)과정을 통해 적당한 수준의 암호화 알고리즘을 채택하게 되는데, 여기서 허용할 Cipher Suite의 종류를 여기에 나열하는 것입니다. Cipher Suite는 각각 서로 다른 보안 수준(즉, 암호화를 깨는 데 얼마나 오래 걸리는지)을 갖습니다.
"뭐 복잡하게 이런 협상을 하나? 그냥 보안 수준 킹왕짱 높은것만 쓰면 안되나?"
...라는 생각이 들지도 모르지만, Client와 Server의 상황에 따라 보안 수준을 조정할 필요가 있기 때문에
예를 들어, Client나 Server가 일반적인 PC+브라우저가 아닌 가난한 하드웨어의 임베디드 시스템인 경우 높은 보안 수준의 Cipher Suite를 사용하면 매 통신마다 많은 연산량을 감당하지 못해서 통신 속도가 느려지거나, 최악의 경우 시스템 자체가 다운될 수도 있습니다.
여기에 써 놓은 암호문같은 값(ALL:!aNULL:!EXPORT56:RC4+RSA:+HIGH:+MEDIUM:+LOW:+SSLv2:+EXP;)은 Nginx 공식 매뉴얼에서 그대로 긁어온 것입니다. OpenSSL에서 Cipher Suite를 지정하는 방법입니다. Semicolon으로 사용할 Suite를 구분하여 지정할 수 있습니다.
사용 가능한 Cipher Suite의 종류는 다음 명령을 통해 알 수 있습니다.
openssl ciphers
12번째 줄의 ssl_prefer_ciphers는 Client와의 Cipher Suite 협상 과정에서 서버측에서 미리 지정해 놓은 순서를 우선시하도록 설정합니다. 예를 들어, on으로 설정된 경우 Client에서 낮은 우선순위에 지정했던 Cipher Suite가 서버측에서는 높은 우선순위로 지정되어 있으면 서버측의 설정에 우선하여 해당 Cipher Suite를 채택하게 됩니다.
이 외에도 Cache크기나 세션 만료시간, Client 인증과 같이 SSL 서버 설정에 관한 여러 옵션을 설정할 수 있습니다. 자세한 내용은 다음 Nginx 공식 매뉴얼을 참조하세요.
http://nginx.org/en/docs/http/ngx_http_ssl_module.html