준호씨의 블로그

https 적용하기 - certbot. Let's encrypt 본문

개발이야기/호스팅관리

https 적용하기 - certbot. Let's encrypt

준호씨 2022. 8. 1. 23:01
반응형

어느 날 갑자기 제가 호스팅하고 있는 사이트에 접속이 안되더군요. 분명 저는 http://labs.junho85.pe.kr라고 입력했는데 저절로 https로 바뀌면서 인증서에 문제가 있다고 나옵니다. 분명 https로 접속했던 적도 없는데 어느 날부터 저렇게 되더군요. junho85.pe.kr 도메인을 사용하는 다른 사이트에서 https를 사용하는 경우가 있어서 그런 걸 지도 모르겠습니다.

 

요즘 크롬 브라우저도 그렇고 기본 https로 접근되도록 바뀌고 있습니다. https로 한 번이라도 접속하고 나면 http로 들어가려 해도 자동으로 https로 바꿔버리기도 합니다. 아무래도 이제는 웬만하면 웹사이트 운영할 때 https를 설정해 두는 것이 좋겠습니다.

 

일단 웹서버에 https를 설정하려면 인증서가 필요합니다. 보통 인증서는 돈 주고 구입해야 되는데 다행히도 무료로 인증서를 발급해 주는 곳이 있습니다. Let's Encrypt라는 곳입니다.

https://letsencrypt.org/getting-started/ 

여러 설명이 나와있는데 아무튼 Certbot을 이용하기를 권장한다고 합니다. 자동으로 인증서를 발급받고 설치까지 해준다고 합니다.

 

Certbot 사이트 주소는 https://certbot.eff.org/이고 아래는 Certbot사이트에 접속한 모습입니다. 아래쪽에 보면 서버 애플리케이션 (e.g. Apache, Nginx 등)와 OS (Ubuntu, macOS 등)을 선택하는 부분이 보입니다. 저는 Apache와 Ubuntu 18을 선택했습니다.

 

snapd 설치

설치하는 방법 설명이 나오는데 간단히 요약해 보면 일단 snapd를 설치하고 최신 버전으로 업데이트합니다.

$ sudo yum install snapd
$ sudo snap install core; sudo snap refresh core

 

certbot 설치

혹시 기존에 certbot이 설치되어 있었다면 버전이 낮을 수 있으니 삭제해 줍니다.

$ sudo apt-get remove certbot

그리고 snapd를 이용해서 certbot을 설치합니다.

$ sudo snap install --classic certbot

그리고 certbot 커맨드를 어디에서나 실행할 수 있도록 /usr/bin/에 심볼릭 링크를 만들어줍니다.

$ sudo ln -s /snap/bin/certbot /usr/bin/certbot

 

인증서 받고 apache 설정 변경

인증서를 받고 apache 웹서버 설정을 바꿔주는 명령어입니다.

$ sudo certbot --apache

만약 인증서만 받고 apache 설정을 수정하고 싶지 않은 경우에는 certonly를 추가합니다.

$ sudo certbot certonly --apache

 

참고로 저는 여러 사이트를 운영하다 보니 리스트가 여러 개 나타납니다.

인증서를 설정하고 싶은 사이트 주소의 번호를 입력하면 해당 도메인에 맞는 인증서를 받고 apache 설정을 변경해 줍니다.

 

인증서가 세팅되어서 사이트에 잘 접속되는 모습을 볼 수 있습니다. 자물쇠 모양이 정상적으로 뜬다는 것은 https에 정상적으로 접속했다는 의미입니다.

트러블슈팅 1. 방화벽이 있다면 https(443 포트) 방화벽을 열어줍니다

서버 설정이 제대로 되어 있더라도 방화벽이 닫혀있다면 방화벽을 열어주어야 합니다.

$ sudo ufw allow https

 

트러블슈팅 2. apache 설정이 적용되지 않았다면 apache를 재시작합니다.

$ sudo service apache2 restart

 

트러블슈팅 3. 자동 설정 변경이 제대로 안되었다면 직접 설정합니다

설정 구조가 특이한 경우 certbot이 자동으로 설정을 못해주는 경우가 있습니다. 인증서 받기까지는 잘 되었다면 설정만 직접 바꿔주면 됩니다.

 

/etc/apache2/sites-enabled에 love.junho85.pe.kr 도메인에 인증서를 설정한 모습니다.

 

love.junho85.pe.kr.conf

<VirtualHost *:80>
    DocumentRoot /home/junho85/web/wedding
    ServerName love.junho85.pe.kr
    <Directory /home/junho85/web/wedding>
        Require all granted
    </Directory>
    RewriteEngine on
    RewriteCond %{SERVER_NAME} =love.junho85.pe.kr
    RewriteRule ^ https://%{SERVER_NAME}%{REQUEST_URI} [END,NE,R=permanent]
</VirtualHost>

http(80 포트)로 접근하면 https로 리다이렉트 시키는 설정입니다.

자세한 설정이 궁금하면 공식문서를 참고합니다. https://httpd.apache.org/docs/current/mod/mod_rewrite.html#rewriterule

 

love.junho85.pe.kr-le-ssl.conf

<IfModule mod_ssl.c>
<VirtualHost *:443>
    ServerName love.junho85.pe.kr
    DocumentRoot /home/junho85/web/wedding
    <Directory /home/junho85/web/wedding>
        Require all granted
    </Directory>

    Include /etc/letsencrypt/options-ssl-apache.conf
    ServerAlias love.junho85.pe.kr
    SSLCertificateFile /etc/letsencrypt/live/love.junho85.pe.kr/fullchain.pem
    SSLCertificateKeyFile /etc/letsencrypt/live/love.junho85.pe.kr/privkey.pem
</VirtualHost>
</IfModule>

https(443 포트) 설정입니다. 윗부분 기본 설정은 같은데 아래쪽이 다릅니다. 리다이렉트 설정은 없고 인증서 관련 설정이 있습니다.

 

/etc/letsencrypt/options-ssl-apache.conf 에는 지원 암호화 설정들이 있습니다. (의외로 아직 TLS 1.2, TLS 1.3이 기본 설정으로 안 들어가네요)

# This file contains important security parameters. If you modify this file
# manually, Certbot will be unable to automatically provide future security
# updates. Instead, Certbot will print and log an error message with a path to
# the up-to-date file that you will need to refer to when manually updating
# this file. Contents are based on https://ssl-config.mozilla.org

SSLEngine on

# Intermediate configuration, tweak to your needs
SSLProtocol             all -SSLv2 -SSLv3 -TLSv1 -TLSv1.1
SSLCipherSuite          ECDHE-ECDSA-AES128-GCM-SHA256:ECDHE-RSA-AES128-GCM-SHA256:ECDHE-ECDSA-AES256-GCM-SHA384:ECDHE-RSA-AES256-GCM-SHA384:ECDHE-ECDSA-CHACHA20-POLY1305:ECDHE-RSA-CHACHA20-POLY1305:DHE-RSA-AES128-GCM-SHA256:DHE-RSA-AES256-GCM-SHA384
SSLHonorCipherOrder     off
SSLSessionTickets       off

SSLOptions +StrictRequire

# Add vhost name to log entries:
LogFormat "%h %l %u %t \"%r\" %>s %b \"%{Referer}i\" \"%{User-agent}i\"" vhost_combined
LogFormat "%v %h %l %u %t \"%r\" %>s %b" vhost_common

 

트러블슈팅 4. WSGI 사용하는 경우 설정 참고

WSGI를 이용하는 설정이 있었는데 이 경우도 자동으로 설정이 잘 안 되더군요. 참고 삼아 남겨둡니다.

 

garden7.junho85.pe.kr.conf

<VirtualHost *:80>
    ServerName garden7.junho85.pe.kr

    WSGIDaemonProcess garden7 python-home=/home/junho85/web/garden7/venv python-path=/home/junho85/web/garden7/
    WSGIProcessGroup garden7

    WSGIScriptAlias / /home/junho85/web/garden7/garden7/wsgi.py

    ErrorLog "/var/log/apache2/garden7-error_log"
    CustomLog "/var/log/apache2/garden7-access_log" common

    <Directory /home/junho85/web/garden7/garden7>
    <Files wsgi.py>
        Require all granted
    </Files>
    </Directory>

    RewriteEngine on
    RewriteCond %{SERVER_NAME} =garden7.junho85.pe.kr
    RewriteRule ^ https://%{SERVER_NAME}%{REQUEST_URI} [END,NE,R=permanent]
</VirtualHost>

 

garden7.junho85.pe.kr-le-ssl.conf

<IfModule mod_ssl.c>
<VirtualHost *:443>
    ServerName garden7.junho85.pe.kr

    WSGIDaemonProcess garden7-ssl python-home=/home/junho85/web/garden7/venv python-path=/home/junho85/web/garden7/
    WSGIProcessGroup garden7-ssl

    WSGIScriptAlias / /home/junho85/web/garden7/garden7/wsgi.py

    ErrorLog "/var/log/apache2/garden7-error_log"
    CustomLog "/var/log/apache2/garden7-access_log" common

    <Directory /home/junho85/web/garden7/garden7>
        <Files wsgi.py>
            Require all granted
        </Files>
    </Directory>

    SSLCertificateFile /etc/letsencrypt/live/garden7.junho85.pe.kr/fullchain.pem
    SSLCertificateKeyFile /etc/letsencrypt/live/garden7.junho85.pe.kr/privkey.pem
    Include /etc/letsencrypt/options-ssl-apache.conf
</VirtualHost>
</IfModule>

주의해야 할 부분은 WSGIDaemonProcess 뒤에 들어오는 name부분을 구분해야 한다는 부분입니다. http에서는 garden7, https에서는 garden7-ssl로 바꿔서 중복 오류가 발생하지 않도록 한 부분입니다.

사실 http를 아예 사용하지 않는다라고 생각하면 리다이렉트를 위해 Rewrite관련 설정만 남겨두고 나머지는 삭제해도 되겠습니다.

 

혹시나 http로 돌아올 경우를 생각해서 남겨두었었는데 생각난 김에 수정해보았습니다.

 

garden7.junho85.pe.kr.conf

<VirtualHost *:80>
    ServerName garden7.junho85.pe.kr

    ErrorLog "/var/log/apache2/garden7-error_log"
    CustomLog "/var/log/apache2/garden7-access_log" common

    RewriteEngine on
    RewriteCond %{SERVER_NAME} =garden7.junho85.pe.kr
    RewriteRule ^ https://%{SERVER_NAME}%{REQUEST_URI} [END,NE,R=permanent]
</VirtualHost>

 

반응형
Comments