사용자 도구

사이트 도구


let_s_encrypt_https_적용기

Let's Encrypt HTTPS 적용기

cumul::wiki는 HTTPS로 서비스되고 있습니다. 얼마 전부터 Chrome에서 HTTP 사이트에 경고를 표시하고 있는 것도 그렇고, 통신 보안도 개인의 권리라는 측면에서 생각해 보면 HTTPS 서비스는 이제라도 필수가 되어야 하지 않을까 싶습니다. 그런데 막상 HTTPS를 서버에 적용하려고 보면 상당히 골치가 아픈 것도 사실입니다. 인증서의 종류도 여러 개이고, 공개키, 개인키, 암호화 알고리즘 등등 평소에 보안에 관심이 없었다면 접하기 어려운 단어들이 튀어나옵니다.

그래서 이 문서에서는 나중에 참고가 될 수 있도록 cumul::wiki에 HTTPS를 적용하기까지의 짧은 기록을 남겨볼까 합니다. 저는 Linux Foundation에서 무료로 제공하는 Let's Encrypt 인증서를 사용했습니다. Let's Encrypt에서는 여러가지 작업들을 자동화해 주는 certbot을 통해서 인증서를 발급/갱신하고 있어서, 먼저 certbot을 설치해야 합니다.

certbot 설치

설치야 여러가지 방법이 있겠지만, 저는 Debian 8(jessie)을 사용하고 있어서 apt로 설치했습니다.

먼저 리포지터리를 추가해 줍니다.

sudo sh -c "echo deb http://ftp.debian.org/debian jessie-backports main > /etc/apt/sources.list.d/certbot.list"

패키지 목록을 업데이트하고 설치를 진행합니다.

sudo apt update
sudo apt install certbot -t jessie-backports

그런데 저는 여기서 데비안의 GPG 키가 등록되지 않은 상태였기 때문에 오류가 발생했습니다. 아마도 정식 배포판이 아니라 Raspberry Pi 번들이라서 그런 것 같습니다.

gpg --keyserver pgpkeys.mit.edu --recv-key 8B48AD6246925553
gpg -a --export 8B48AD6246925553 | sudo apt-key add -
 
gpg --keyserver pgpkeys.mit.edu --recv-key 7638D0442B90D010
gpg -a --export 7638D0442B90D010 | sudo apt-key add -

이렇게 키 두 개를 등록해 주고 다시 설치해 보면 잘 됩니다.

인증서 발급

certbot를 실행해서 인증서를 발급 받을 때, 두 가지 방법이 있습니다. 하나는 webroot 플러그인으로 기존 웹 서버를 활용하는 방식이고, 다른 하나는 certbot에 내장된 standalone 서버를 사용하는 방식입니다. standalone을 사용하는 것이 더 간단하지만, 기존 웹 서버를 잠시 중단시켜야 할 수도 있습니다. 제 서버에서는 nginx 서버가 작동 중이었지만, 혼자 쓰는 간단한 개인 사이트라서 일단 서버를 중단시키고 standalone 모드로 certbot을 실행했습니다.

sudo service nginx stop
sudo certbot certonly --standalone -d wiki.cumul.pe.kr

조금 후에 뜨는 창에 이메일을 입력하고 기다리면 인증서 발급이 진행됩니다. 다만, 80, 443포트로 외부 접속이 가능해야 하는 것 같습니다. 저의 경우에는 443 포트를 열어 놓지 않아서 한참을 헤맸습니다. 꼭 방화벽과 라우터 설정을 확인합시다.

정상적으로 발급이 완료되면 인증서는 /etc/letsencrypt/live/wiki.cumul.pe.kr에 저장됩니다. 다음 명령으로 확인할 수 있습니다.

sudo ls -l /etc/letsencrypt/live/wiki.cumul.pe.kr

강한 디피-헬만 그룹 생성

강한 디피-헬만 그룹(strong Diffie-Hellman group)을 적용하면 HTTPS/TLS 통신의 보안을 향상시킬 수 있다고 합니다. 중간자 공격을 어렵게 하는 효과가 있는 것 같습니다만, 사실 저도 잘 모르겠습니다. 여유가 있을 때 공부해 봐야겠어요. 어쨌든 다음 명령으로 강한 DH 그룹을 생성할 수 있습니다.

sudo openssl dhparam -out /etc/ssl/certs/dhparam.pem 2048

다만 이 작업은 엔트로피를 증가시키기 위해서 CPU에 큰 부담을 주는 작업을 수행합니다. 제법 오래 기다렸는데도 끝나지 않아서 구글링 해보니 같은 Raspberry Pi 모델 B에서 무려 24시간이 걸린 사례도 있습니다. 당장 취소하고 데스크탑에서 생성해서 파일을 복사했습니다. 데스크탑에서는 30초도 걸리지 않았습니다.

인증서 사용

이제 웹 서버를 설정하는 일만 남았습니다. 먼저 DH 그룹과 HSTS 기능을 사용하기 위한 설정 스니펫을 만듭니다.

# /etc/nginx/ssl_params.conf

# from https://cipherli.st/
# and https://raymii.org/s/tutorials/Strong_SSL_Security_On_nginx.html

ssl_protocols TLSv1 TLSv1.1 TLSv1.2;
ssl_prefer_server_ciphers on;
ssl_ciphers "EECDH+AESGCM:EDH+AESGCM:AES256+EECDH:AES256+EDH";
ssl_ecdh_curve secp384r1;
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 preloading HSTS for now.  You can use the commented out header line that includes
# the "preload" directive if you understand the implications.
#add_header Strict-Transport-Security "max-age=63072000; includeSubdomains; preload";
add_header Strict-Transport-Security "max-age=63072000; includeSubdomains";
add_header X-Frame-Options DENY;
add_header X-Content-Type-Options nosniff;

ssl_dhparam /etc/ssl/certs/dhparam.pem;

이어서 가상 서버 설정에 SSL 설정을 추가해 주면 됩니다.

server {
    listen                 443 ssl;

    ssl_certificate        /etc/letsencrypt/live/wiki.cumul.pe.kr/fullchain.pem;
    ssl_certificate_key    /etc/letsencrypt/live/wiki.cumul.pe.kr/privkey.pem;
    include                ssl_params.conf;
}

서버를 재시작하면 HTTPS로 접속할 수 있습니다.

sudo service nginx start

HTTP 리다이렉트

HTTP 프로토콜로 서버에 접속하면 HTTPS로 리다이렉트 되도록 설정할 수도 있습니다.

server {
        server_name                     wiki.cumul.pe.kr;
        listen                          80;
        return                          301 https://$server_name$request_uri;
}

인증서 갱신 예약

인증서의 유효기간은 약 한 달 정도인 것 같습니다. crontab -e 명령을 사용해서 다음과 같이 작업을 예약할 수 있습니다.

30 2 * * 1 /usr/bin/letsencrypt renew >> /var/log/le-renew.log
35 2 * * 1 /bin/systemctl reload nginx

참고 자료

let_s_encrypt_https_적용기.txt · 마지막으로 수정됨: 2017/02/26 19:06 (바깥 편집)