본문 바로가기

Dev/etc

[etc] Web Server https 적용 매뉴얼

 

 

 

이번 포스팅에서는 배포된 프로젝트에 https를 적용하는 방법에 대해 다룹니다.

https란 Hypertext Transfer Protocol Secure의 약자로 웹 사이트 내에서 주고받는 데이터가 암호화되지 못해 보안이 떨어지는 http를 보완하기 위해 탄생한 프로토콜입니다.

 

요즘에는 매우 보기 드물어졌지만 http를 사용하는 웹사이트는 브라우저에서 아래와 같이 보안이 취약하다는 경고를 띄워줍니다.

 

 

http는 데이터 암호화가 되지 않기 때문에 불순한 의도에 의해 도중에 데이터가 오염될 가능성도 있고 유출될 가능성이 있습니다.

또한 구글에서도 http를 사용하는 웹사이트에 대해 검색 우선순위를 떨어뜨리는 등의 페널티를 부여하기도 합니다.

 

본 포스팅은 nginx를 기준으로 작성되었지만 약간의 응용이 있다면 tomcat, apache등에도 동일하게 적용 가능합니다.

 

0. 적용 전제 조건

  • 배포 서버가 준비되어 있어야 합니다. (본 포스팅은 AWS - EC2 (Ubuntu 20)를 이용했습니다.)
  • 도메인 구비 및 웹 서버에 적용되어있어야 합니다. (aws의 경우 Route53에서 설정 및 EC2 탄력적 IP 적용) 

 

1. SSL 인증서 발급

국내외로 SSL 인증서를 유료로 발급해주고 있지만 본 포스팅에서는 Letsencrypt의 무료 인증서를 이용할 것입니다.

Letsencrypt는 https 사용을 장려하기 위해 인증서를 무료로 발급해주는 비영리 단체입니다.

 

먼저 배포 서버에 접속해 letsencrypt 패키지를 설치합니다.

$sudo apt-get update
$sudo apt-get install letsencrypt

 

웹 서버 데몬을 중지시키고 letsencrypt 명령어로 사용하고자 하는 도메인의 인증서를 발급받습니다.

$sudo service nginx stop
$sudo letsencrypt certonly --standalone -d [도메인]

 

본인이 사용하는 이메일을 작성합니다.

 

위와 같이 Congratulations!로 시작하는 글이 나오면 발급이 완료된 것입니다.

만약 오류가 발생했다면 현재 서버 데몬이 종료된 상태인지 확인 후 다시 발급받습니다.

 

인증서는 아래의 위치에 존재합니다.

인증서: /etc/letsencrypt/live/도메인/fullchain.pem

인증서 키: /etc/letsencrypt/live/도메인/privkey.pem

 

이제 실제 프로젝트에 이 인증서를 적용시켜야 합니다.

sites-avaliable에 있는 프로젝트 서버 스크립트에 80번 포트(http)로 요청이 오는 것을 https로 받을 수 있도록 하고 ssl 인증서를 등록합니다.

 

# 80번 포트로 들어오는 요청을 443 포트로 리다이렉트한다.
server {
        listen 80;
        server_name 도메인;
        return 301 https://$server_name$request_uri;
}

server {
        # SSL Config
        listen 443 ssl default_server;
        listen [::]:443 ssl default_server;

        ssl_certificate /etc/letsencrypt/live/도메인/fullchain.pem;
        ssl_certificate_key /etc/letsencrypt/live/도메인/privkey.pem;

        ssl_session_cache shared:SSL:1m;
        ssl_session_timeout  10m;
        ssl_ciphers HIGH:MEDIUM:!SSLv2:!PSK:!SRP:!ADH:!AECDH;
        ssl_prefer_server_ciphers on;

        . . .

        server_name 도메인;

        . . .
}

 

이제 서버 테스트 및 데몬을 실행시켜줍니다.

$sudo nginx -t
$sudo service nginx start

만약 nginx -t 명령어가 successful을 반환하지 않는다면 작성한 스크립트에 문제가 있는 것이니 수정해줍니다.

 

 

만약 AWS의 EC2를 이용해 배포하는 경우 해당 인스턴스의 보안 그룹 인바운드를 아래와 같이 http, https 두 접근에 대해 허용해주어야 합니다.

EC2 인스턴스 인바운드 그룹

 

이제 자신이 배포한 프로젝트에 접속해봅니다.

도메인 옆에 자물쇠가 잠겨있는 이미지가 나타나는데 눌러보면 HTTPS 보안 연결이 사용되었다고 표시됩니다.

 

2. SSL 인증서 자동 갱신 설정

letsencrypt의 인증서는 한 번 발급받으면 3개월 동안 사용할 수 있습니다.

따라서 3개월마다 인증서를 갱신해주어야 하는데, 이를 매번 수동으로 하기에는 번거롭기도 하고 갱신 주기를 잊어버려 인증서가 만료되면 사이트에 접속이 불가하기 때문에 이를 자동으로 갱신해주는 스케줄을 정의하도록 하겠습니다.

 

$sudo crontab -e

# 매달 1일 새벽 2시에 인증서 갱신을 시도한다.
0 2 1 * * /usr/bin/letsencrypt renew --deploy-hook="sudo service nginx reload" >> /var/log/letsencrypt/letsencrypt-renew.log

갱신 주기는 자유롭게 설정합니다.

스케줄을 적용해줍니다.

$sudo service cron reload

 

이것으로 웹서버 https 적용에 대한 호스팅을 마칩니다.