WEB

Nginx HTTPS Let's Encrypt 무료 인증서 설치하기 우분투 16.04

우성군 0 8237 0

 

 

1. 왜 HTTPS 무료 인증서를 설치해야 할까요?

 

인증서에 대한 개념은 나무 위키를 보면 이해가 쉽습니다.

 

참조 링크 : https://namu.wiki/w/TLS

 

 

간단하게 말해서 웹 상에 전송되는 모든 데이터를 암호화한다고 보면 됩니다.

 

암호화의 중요성은 구글도 매우 강조하고 있습니다.

 

https://security.googleblog.com/2016/09/moving-towards-more-secure-web.html

 

위 링크에도 있지만

 

 

 

위 스샷에 보면 현재 HTTP로 전송되는 사이트의 경우 느낌표로 간단하게 표시되고 있지만

 

Chrome 56 버전(2017년 1월 예정)에서는 Not secure 라는 강조된 단어가 들어갈 예정입니다.

 

 

 

그 뒤엔 위와 같이 빨간색으로 더 강조할 예정이라고 합니다.

 

웹사이트를 이용하는 유저들이 확실하게 체감하게 된다는거죠.

 

암호화 및 복호화에 따른 서버의 부담이 증가되긴 하지만, 우리의 데이터를 지키는 것은 매우 중요한 일입니다.

 

지금 이 홈페이지도 2016년 9월 중순부터 HTTPS를 이용하여 안전하게 데이터를 전송하고 있습니다.

 

 

2. 인증서 설치는 비싸고 번거롭지 않을까요?

 

그렇지 않습니다. 최근 여러 업체들의 노력으로 인증서 발급이 매우 저렴해지고, 설치가 간편해지고 있습니다.

 

오늘 소개해드릴 Let's Encrypt의 인증서는 무료에다가 설치도 자동으로 됩니다.

 

그리고 예전에 있었던 브라우저 호환성 문제도 거의 없다고 보면 됩니다. 

 

현재 이 홈페이지도 윈도우XP에 IE6만 아니라면 모두 접속 가능합니다.

 

 

3. Let's Encrypt 클라이언트 설치하기

 

root 권한을 가졌다고 가정하고 진행하겠습니다.

 

apt-get update

apt-get install letsencrypt 

 패키지 리스트 업데이트 후 letsencrypt 패키지를 설치합니다.

 

 

https://certbot.eff.org/docs/install.html

 

위와 같이 certbot을 설치할 수도 있지만 패키지 설치가 더 편할 것입니다. 기능은 거의 같습니다.

 

 

4. Nginx 서버 설정 추가하기

 

nano /etc/nginx/sites-available/default

위 명령어로 서버 설정에 들어갑니다.  

 

server { 블록 안에

 

location ~ /.well-known {

allow all;

}

위와 같은 내용을 삽입합니다.  

 

이 작업을 하는 이유는 Letsencrypt의 Webroot Plugin을 사용하기 위해서 입니다.

 

그리고 서버의 root를 알아야 합니다.

 

보통 root /var/www ;  과 같이 사용하는 바로 그것입니다.

 

 

이제 저장하고 나와서 nginx를 재시작 해줍니다.

 

nginx -t

위 명령어를 내렸을 때  

 

nginx: the configuration file /etc/nginx/nginx.conf syntax is ok 

nginx: configuration file /etc/nginx/nginx.conf test is successful

위와 같은 내용이 나오면 에러가 없는 것입니다. 그 후에

 

 

service nginx restart

위 명령어로 재시작 해줍니다.  

 

 

5. 인증서 발급받기

 

letsencrypt certonly -a webroot -w /var/www -d example.com -d www.example.com

기본적인 명령어는 위와 같다고 보시면 됩니다.  

 

간단하게 설명을 드리면, webroot 라는 플러그인을 이용하고, -w 다음에는 발급을 원하는 홈페이지의 root 폴더를 넣습니다.

 

그리고 -d 다음에 도메인을 넣습니다. 해당 도메인이 여러개라면 -d를 계속 추가해줘도 상관없습니다.

 

또한 위처럼 1개의 도메인이 아니라 여러개의 도메인도 1개의 인증서에 모두 넣을 수 있습니다. 이론상 100개의 도메인 입력이 가능하다고 합니다.

 

여러개의 도메인 그리고 여러개의 root가 있다면 

 

letsencrypt certonly -a webroot -w /var/sitea/ -d www.yourhomepage.com -w /var/siteb/ -d yourhomepage.com -d 1.yourhomepage.com -w /var/sitec/ -d 2.yourhomepage.com -w /var/sited/ -d 3.yourhomepage.com -w /var/sitee/ -d 4.yourhomepage.com -w /var/sitef/ -d sitef.site.com -w /var/siteg/ -d 5.yourhomepage.com

위와 같이 넣으면 됩니다. 참고로 제 홈페이지의 인증서도 10개가 넘는 도메인이 들어있습니다. 

 

그리고 더 나은 보안을 위해 --rsa-key-size 4096 옵션을 추천드립니다.

 

기본으로 2048 bit 로 들어가는데, 위 옵션을 넣으면 4096 bit 로 만들어집니다.

 

letsencrypt certonly -a webroot -w /var/www -d example.com -d www.example.com --rsa-key-size 4096

위와 같이 맨 뒤에 붙여주기만 하면 됩니다. 

 

 

 

위와 같이 이메일을 넣고, 동의를 누르면 발급이 됩니다.

 

Output:

IMPORTANT NOTES:

 - If you lose your account credentials, you can recover through

   e-mails sent to XXXXX@XXXXXXXX.XXX

 - Congratulations! Your certificate and chain have been saved at

   /etc/letsencrypt/live/example.com/fullchain.pem. Your

   cert will expire on 2017-XX-XX. To obtain a new version of the

   certificate in the future, simply run Let's Encrypt again.

 - Your account credentials have been saved in your Let's Encrypt

   configuration directory at /etc/letsencrypt. You should make a

   secure backup of this folder now. This configuration directory will

   also contain certificates and private keys obtained by Let's

   Encrypt so making regular backups of this folder is ideal.

 - If like Let's Encrypt, please consider supporting our work by:

 

   Donating to ISRG / Let's Encrypt:   https://letsencrypt.org/donate

   Donating to EFF:                    https://eff.org/donate-le

최종적으로 인증서 발급에 성공하면 위와 같은 문구가 나옵니다. 

 

 

참고로 

 

Failed to connect to host for DVSNI challenge

위와 같은 메세지가 나오면서 발급이 되지않는다면 80포트와 443포트가 막혀있다는 말입니다. 

 

그래서 해당 포트를 열어주면 됩니다.

 

 

발급되는 인증서 파일을 살펴보면

 

cert.pem: 해당 도메인의 인증서

chain.pem: Let's Encrypt의 연결 인증서

fullchain.pem: 도메인 인증서와 LE 연결 인증서를 합친 것

privkey.pem: 인증서의 키 파일

Nginx에서 쓸 파일은 cert.pem을 제외한 나머지 3개 파일입니다. 

 

실제 인증서는 /etc/letsencrypt/archive/yourdomain/ 에 들어있지만

 

사용되는 경로는 /etc/letsencrypt/live/yourdomain/ 에 있습니다.

 

그 이유는 인증서가 업데이트 되어도 같은 경로를 쓰기 위해서입니다.

 

 

6. Dhparams 파일 생성

 

 

mkdir /etc/nginx/ssl

cd /etc/nginx/ssl

openssl dhparam -out dhparams.pem 4096

위와 같이 폴더를 생성한 후 dhparams 파일을 생성합니다. 보통 2048 bit 를 쓰지만 더 나은 보안을 위해 4096 bit 를 넣었습니다.

 

서버의 성능에 따라 다르지만 생성되는 시간이 매우 오래 걸립니다.

 

openssl rand 48 > session_ticket.key

그리고 위 명령어로 세션 티켓키도 생성해줍니다. 이건 금방 만들어집니다. 

 

 

7. Nginx 서버 설정 변경하기

 

이제 인증서 및 필요한 파일은 모두 만들었습니다.

 

Nginx에 반영만 해주면 됩니다.

 

이제 80포트는 경유하는 경로로만 쓰고 443이라는 HTTPS 포트로만 사용할 것입니다.

 

참고로 웹호스팅의 경우 443 포트가 아닌 449라든지 40958와 같은 랜덤 포트가 주어질 수 있습니다.

 

이런 경우 주소창 뒤에 해당 포트 번호가 붙게 됩니다... (ㅜㅜ)

 

 

nano /etc/nginx/sites-available/default

이제 위 명령어로 들어가 완전히 뜯어 고칠 예정입니다. 

 

예시로 제 홈페이지 설정입니다.

 

server {

#80포트로 접근시 https로 이동

listen 80;

server_name www.wsgvet.com wsgvet.com;

add_header "Cache-Control" "public, max-age=31536000";

location / {

rewrite       ^/(.*)$ https://www.wsgvet.com/$1 permanent;

}

}

 

server {

listen 443 ssl http2;

listen [::]:443 ssl http2;

 

server_name www.wsgvet.com wsgvet.com;

 

root /var/www;

index index.php;

 

#www.wsgvet.com이 아닌 wsgvet.com으로 접근시 www 붙여주기

#참조 : https://www.wsgvet.com/home/513

if ($host != 'www.wsgvet.com' ) {

rewrite ^/(.*)$  https://www.wsgvet.com/$1 permanent;

}

 

#캐시 시간 설정

location ~*.(ogg|ogv|svg|svgz|eot|otf|woff|mp4|ttf|css|rss|atom|js|jpg|jpeg|gif|png|ico|zip|tgz|gz|rar|bz2|doc|xls|exe|ppt|tar|mid|midi|wav|bmp|rtf|cur)$ {

expires max;

log_not_found off;

access_log off;

}

 

#Letencrypt 인증서 생성시 필수

location ~ /.well-known {

allow all;

}

 

charset utf-8;

server_tokens off;

client_max_body_size 100M;

 

location / {

try_files $uri $uri/ =404;

}

 

# Add PHP handler

location ~ [^/]\.php(/|$) {

fastcgi_split_path_info ^(.+?\.php)(/.*)$;

if (!-f $document_root$fastcgi_script_name) {

return 404;

}

try_files $fastcgi_script_name =404;

set $path_info $fastcgi_path_info;

fastcgi_param PATH_INFO $path_info;

fastcgi_index index.php;

include fastcgi.conf;

fastcgi_pass unix:/run/php/php7.0-fpm.sock;

}

 

location ~ /\.ht {

deny all;

}

 

# Letsencrypt 기본 RSA 인증서

ssl_certificate /etc/letsencrypt/live/www.wsgvet.com/fullchain.pem

ssl_certificate_key /etc/letsencrypt/live/www.wsgvet.com/privkey.pem;

 

#OCSP 설정 (https://www.wsgvet.com/home/454)

ssl_trusted_certificate /etc/letsencrypt/live/www.wsgvet.com/chain.pem;

ssl_stapling on;

ssl_stapling_verify on;

resolver 8.8.8.8 8.8.4.4 valid=300s;

resolver_timeout 10s;

 

ssl_protocols TLSv1 TLSv1.1 TLSv1.2;

ssl_prefer_server_ciphers on;

 

# 밑 ssl_ciphers는 https://wiki.mozilla.org/Security/Server_Side_TLS#Intermediate_compatibility  참고하시면 됩니다.

ssl_ciphers ECDHE-ECDSA-CHACHA20-POLY1305:ECDHE-RSA-CHACHA20-POLY1305:ECDHE-ECDSA-AES128-GCM-SHA256:ECDHE-RSA-AES128-GCM-SHA256:ECDHE-ECDSA-AES256-GCM-SHA384:ECDHE-RSA-AES256-GCM-SHA384:DHE-RSA-AES128-GCM-SHA256:DHE-RSA-AES256-GCM-SHA384:ECDHE-ECDSA-AES128-SHA256:ECDHE-RSA-AES128-SHA256:ECDHE-ECDSA-AES128-SHA:ECDHE-RSA-AES256-SHA384:ECDHE-RSA-AES128-SHA:ECDHE-ECDSA-AES256-SHA384:ECDHE-ECDSA-AES256-SHA:ECDHE-RSA-AES256-SHA:DHE-RSA-AES128-SHA256:DHE-RSA-AES128-SHA:DHE-RSA-AES256-SHA256:DHE-RSA-AES256-SHA:ECDHE-ECDSA-DES-CBC3-SHA:ECDHE-RSA-DES-CBC3-SHA:EDH-RSA-DES-CBC3-SHA:AES128-GCM-SHA256:AES256-GCM-SHA384:AES128-SHA256:AES256-SHA256:AES128-SHA:AES256-SHA:DES-CBC3-SHA:!DSS;

 

ssl_session_timeout 1d;

ssl_session_cache shared:SSL:50m;

 

ssl_dhparam /etc/nginx/ssl/dhparams.pem;

ssl_session_tickets        on;

ssl_session_ticket_key /etc/nginx/ssl/session_ticket.key;

 

#HTST 설정은 해당 도메인에 접근시 HTTPS로 접속을 강제하는 옵션입니다. HTTPS로 주소를 고정하려면 #을 삭제하고 사용하시면 됩니다.

# 밑 옵션을 넣은 후 https://hstspreload.appspot.com  사이트에서 도메인 등록 필요

#add_header Strict-Transport-Security "max-age=31536000; includeSubDomains; preload";

 

#HPKP 설정 (참조 : https://www.wsgvet.com/home/491 )

add_header Public-Key-Pins 'pin-sha256="PduLXRpowV4q5wsWHVtMiOTIHusvcWdDHOhG2Hmj/ec="; pin-sha256="YLh1dUR9y6Kja30RrAn7JKnbQG/uEtLMkBgFF2Fuihg="; pin-sha256="Vjs8r4z+80wjNcr1YKepWQboSIRi63WsWXhIMN+eWys="; pin-sha256="qjCCVdtrybQNPEz/7iQTKZbUKE++18Rlsg8JW4O91pA="; max-age=5184000; includeSubDomains';

 

add_header X-Frame-Options SAMEORIGIN;

add_header X-Content-Type-Options nosniff;

add_header X-XSS-Protection "1; mode=block";

저는 위와 같은 형식으로 넣었습니다. 이제 설정을 저장하고 Nginx를 재시작 해주면 됩니다. 

 

 

nginx -t

service nginx restart

  

8. 인증서 자동 갱신 설정하기

 

Letsencrypt 인증서의 유효기간은 90일입니다. 무료이지만 유효기간이 짧은 것이 단점인데요.

 

그것을 해결하기 위해 renew라는 갱신 명령어가 있습니다.

 

간단하게 

 

letsencrypt renew

위 명령어를 내리면 갱신됩니다.

 

Processing /etc/letsencrypt/renewal/example.com.conf

 

The following certs are not due for renewal yet:

  /etc/letsencrypt/live/example.com/fullchain.pem (skipped)

No renewals were attempted.

다만 유효기간이 30일 남았을 때부터 갱신이 가능하니 일주일에 한번씩 갱신 명령어가 실행되도록 하면 되겠죠? 

 

crontab -e

위 명령어로 crontab에 들어가서 

 

30 2 * * 1 /usr/bin/letsencrypt renew >> /var/log/le-renew.log 

35 2 * * 1 /bin/systemctl reload nginx

위와 같이 매주 월요일 새벽 2시 30분에 갱신이 되며, 35분에 nginx가 재실행됩니다. 

 

이제 주소창에 자물쇠가 채워진 것을 볼 수 있을 것입니다.

, , , , , , , , ,

0 Comments