[블로그 구축] 인증서 추가

[블로그 구축] 인증서 추가

요즘 웹의 추세는 HTTPS를 사용하는 추세이다. 블로그에서도 HTTPS를 붙이고 싶었지만, SSL 인증서를 구매해야 하다 보니 개인 블로그에서는 부담돼서 적용을 못 하고 있었다. 그러던 와중에 무료로 인증서를 제공해주는 Lets` Encrypt를 알게 되었고, 블로그에 바로 적용을 해보았다.

블로그 구축 지난글 다시 보기

1. 인증의 원리

  • 쉽게 말하자면 SSL 은 “보안인증서” 라고 말할 수 있다.

  • 사람으로 비유하자면 보안인증서는 암호화코드가 내장된 주민등록증이라고 볼 수 있다.
    요즘 대부분의 편의점이나 술집에서는 주민등록증 진위여부 판독기를 가지고 있다.

  • 암호학에서 “비대칭키 암호화 방식” 이라는 것이 있다. 어떤 문자를 A 로 암호화하면 B 로만 해독할 수 있는 것이다.

  • 일반적으로 암호화에 사용하는 것을 “암호화키” 라고 부르며 이것은 암호통신에서 공개되기 때문에 “공개키” 또는 “공개 암호화키”, “Public Key” 라고도 부른다.

  1. 클라이언트가 서버에 접속한다.
  2. 서버가 보안인증서를 제공한다.
  3. 클라이언트가 서버가 제출한 보안인증서의 유효성을 파악한다. 최상위 발급 기관과 통신하여 유효성을 확인한다. (최상위 발급기관은 운영체제 또는 웹브라우저에 미리 정의되어 있다.)
  4. 보안인증서가 유효하면 인증서에 쓰여져 있는 공개 암호화키 A 를 사용하여 클라이언트 자신의 공개 암호화키 C 를 암호화 하여 전송한다.
  5. 서버는 전송된 암호화 구문을 자신만 가지고 있는 해독키(개인 비밀키) B 를 통해서 해독한다.
  6. 해독한 메세지가 유효한 요청이고 클라이언트의 공개 암호화키 C 를 포함하고 있다면 암호화키 C 를 사용하여 잘 받았다는 메세지를 암호화해서 응답한다.
  7. 클라이언트는 자신만 가지고 있는 해독키(개인 비밀키) D 를 통해서 해독한다. 서버에서 받은 응답 메시지가 유효하다면 클라이언트는 A 를 통해 암호화해서 메세지를 보내고, 서버는 C 를 통해 암호화해서 메세지를 보낸다.
  8. A키로 암호화된 메세지는 B키로만 해독이 가능하고, C키로 암호화된 메세지는 D키로만 해독이 가능하므로 서로 종단간(End-to-End) 암호화 통신이 성립하는 것이다.

결국, Client는 (C 암호키, D 해독키)를 갖고 있고, 서버는 (A 암호키, B 해독키)를 갖고 있으면서 인증서를 통해 Client가 서버를 신뢰하게 되면 각자의 암호키로 내용을 암호화해서 보낸다.

2. Lets’ Encrypt 란?

SSL 인증서는 클라이언트와 서버간의 통신을 제3자가 보증해주는 전자화된 문서입니다. (유명한 제3자로 Symantec 등이 있습니다.)
SSL 인증서를 사용하기 위해서는 보통 유료로 구매를 해야 합니다.
이를 무료로 사용 가능하게 해 주는 Letsencrypt는, “전 세계 모든 사이트를 HTTPS로 만들기!” 라는 슬로건으로 시작 된 오픈소스 프로젝트입니다. 2015년 12월 공개 베타 서비스를 시작하였습니다.

Letsencrypt는 전 세계의 누구에게든, “무료”로 SSL 인증서를 발급해 줍니다. 이 인증서는 제대로 인증된 중개 기관 및 Root CA와의 체인이 되어, 공개적인 웹 사이트에서 사용할 수 있습니다.

3. Lets’ Encrypt 인증서 설치하기

  • Ubuntu 14.04 일 경우
    # cd /root
    # wget https://dl.eff.org/certbot-auto
    # mv certbot-auto /usr/bin/letsencrypt
    # chmod 755 /usr/bin/letsencrypt
    

  • Ubuntu 16.04 일 경우 (또는 그 이후 버전, 18.04 등)

    # apt-get install letsencrypt
    

4. 인증서 발급받기

letsencrypt certonly --webroot --webroot-path=/home/myuser3/www -d myuser3.com -d www.myuser3.com
  • d 는 도메인명을 지정하면 된다. 최대 100개의 도메인 이름을 지정할 수 있다. (한 인증서가 서로다른 100개의 도메인 인증을 할 수 있음) 일반적으로는 기본도메인과 www 도메인 두개를 지정한다.
  • webroot 는 웹인증을 받을 것이라는 것이다. 외부 인증프로그램이 -d 에 지정된 도메인 사이트에 접속한다.

  • webroot-path 는 웹루트의 경로이다. 보통 index 페이지가 위치하는 경로이다. 인증 프로그램이 이 경로에 임시 랜덤 파일을 생성하고, 외부 인증프로그램이 이 파일을 접근할 수 있다면 Domain Validation 이 되는 것이다.

약관에 동의하면 즉시 인증서가 발급된다.
발급에 실패했다면 외부 접속이 문제가 있거나 -webroot-path 를 올바르게 입력하지 않았을 것이다.

5. 웹서버 설정

Apache2 서버에서는 cert.pem, chain.pem, privkey.pem 을 사용합니다.
Nginx 서버에서는 fullchain.pem, privkey.pem 을 사용합니다.

  1. 아파치 웹서버

    필자 같은 경우, 워드프레스를 사용하기 때문에 내장되어있은 아파치 설정 파일의 경로는 아래와 같고, 내용은 밑에 기입한대로이다.

    /opt/bitnami/apache2/conf/bitnami/bitnami.conf

    ServerName "blog.wonizz.tk"
    DocumentRoot "/opt/bitnami/apache2/htdocs"
    SSLEngine on
    #SSLCertificateFile "/opt/bitnami/apache2/conf/server.crt"
    #SSLCertificateKeyFile "/opt/bitnami/apache2/conf/server.key"
    SSLCertificateFile "/etc/letsencrypt/live/blog.wonizz.tk/fullchain.pem"
    SSLCertificateKeyFile "/etc/letsencrypt/live/blog.wonizz.tk/privkey.pem"
    SSLCACertificateFile "/etc/letsencrypt/live/blog.wonizz.tk/fullchain.pem"
    
    
  2. Nginx 웹 서버
    웹사이트에서 HTTPS를 지원하려면 앞에서 발급받은 인증서를 nginx에 설정해야 한다. nginx의 SSL 설정은 Mozilla SSL Configuration Generator를 사용했다. 사용하는 웹서버와 관련 버전을 명시하면 권장하는 설정파일을 만들어 주므로 이 파일을 그대로 사용했다.

    listen 443 ssl;
    
    # certs sent to the client in SERVER HELLO are concatenated in ssl_certificate
    ssl_certificate /path/to/signed_cert_plus_intermediates;
    ssl_certificate_key /path/to/private_key;
    ssl_session_timeout 1d;
    ssl_session_cache shared:SSL:50m;
    ssl_session_tickets off;
    
    # Diffie-Hellman parameter for DHE ciphersuites, recommended 2048 bits
    ssl_dhparam /path/to/dhparam.pem;
    
    # intermediate configuration. tweak to your needs.
    ssl_protocols TLSv1 TLSv1.1 TLSv1.2;
    ssl_ciphers 'ECDHE-RSA-AES128-GCM-SHA256:ECDHE-ECDSA-AES128-GCM-SHA256:ECDHE-RSA-AES256-GCM-SHA384:ECDHE-ECDSA-AES256-GCM-SHA384:DHE-RSA-AES128-GCM-SHA256:DHE-DSS-AES128-GCM-SHA256:kEDH+AESGCM:ECDHE-RSA-AES128-SHA256:ECDHE-ECDSA-AES128-SHA256:ECDHE-RSA-AES128-SHA:ECDHE-ECDSA-AES128-SHA:ECDHE-RSA-AES256-SHA384:ECDHE-ECDSA-AES256-SHA384:ECDHE-RSA-AES256-SHA:ECDHE-ECDSA-AES256-SHA:DHE-RSA-AES128-SHA256:DHE-RSA-AES128-SHA:DHE-DSS-AES128-SHA256:DHE-RSA-AES256-SHA256:DHE-DSS-AES256-SHA:DHE-RSA-AES256-SHA:ECDHE-RSA-DES-CBC3-SHA:ECDHE-ECDSA-DES-CBC3-SHA:AES128-GCM-SHA256:AES256-GCM-SHA384:AES128-SHA256:AES256-SHA256:AES128-SHA:AES256-SHA:AES:CAMELLIA:DES-CBC3-SHA:!aNULL:!eNULL:!EXPORT:!DES:!RC4:!MD5:!PSK:!aECDH:!EDH-DSS-DES-CBC3-SHA:!EDH-RSA-DES-CBC3-SHA:!KRB5-DES-CBC3-SHA';
    ssl_prefer_server_ciphers on;
    

6. 인증서 갱신하기

Let’s Encrypt 는 3개월짜리 인증서를 발급해준다.

즉 인증서를 3개월마다 주기적으로 갱신(renewal)해 주어야한다. 갱신은 만료일 기준 1개월전부터 할 수 있다.

# letsencrypt renew

필자같이 아파치를 사용하는 경우 crontab에 자동으로 걸어둘 수 있다.

  • 아파치 사용하는 경우
10 5 * * 1 /usr/bin/letsencrypt renew >> /var/log/le-renew.log
15 5 * * 1 /usr/sbin/service apache2 reload
  • Nginx 사용하는 경우
10 5 * * 1 /usr/bin/letsencrypt renew >> /var/log/le-renew.log
15 5 * * 1 /usr/sbin/service nginx reload
  • 최종 적용 화면

워니즈 블로그
워니즈 깃헙

답글 남기기

이메일 주소는 공개되지 않습니다. 필수 필드는 *로 표시됩니다