Nginx에 gzip 설정을 추가하자


환경

  • Nginx


웹 사이트 압축?

우리가 흔히 사용하는 웹브라우저 및 통신은 HTTP에 기반한 통신이 많습니다.

그러한 웹 통신에서 속도를 개선하기 위해 많은 노력들이 이루어져 왔고 그러한 노력의 결과로 gzip, 브라우저 캐싱, js 및 css 압축 그리고 CDN(contents delivery network)과 같은 여러 방식들이 나왔습니다.

위에 나온 여러 방법들이 존재하지만 nginx에서 가장 쉽게 설정 할 수 있고 웹서비스를 할 때 기본중에 기본인 gzip을 설정하는 방법에 대해서 알아보겠습니다.


gzip이란?

위키피디아에서 가져온 내용을 발췌하면 아래와 같습니다.

  • gzip은 파일 압축에 쓰이는 응용 소프트웨어이다. gzip은 GNU zip의 준말이며, 초기 유닉스 시스템에 쓰이던 압축 프로그램을 대체하기 위한 자유 소프트웨어이다. gzip은 Jean-loup Gailly와 마크 애들러가 만들었다. 버전 0.1은 1992년 10월 31일에 처음 공개되었으며, 버전 1.0이 1993년 2월에 뒤따라 나왔다. 오픈BSD의 gzip 버전은 더 오래된 압축 프로그램을 기반으로 하고 있으며, 오픈BSD 3.4에 추가되었다.

즉, 쉽게 정리하면 gzip은 압축 프로그램 및 방식이라고 할 수 있습니다. 구체적으로 어떠한 방식과 원리로 압축을 하는지에 대해서는 포스팅하지 않겠으나 LZ77허프만 코딩을 조합한 DEFLATE알고리즘에 기반하여 구현한다고 합니다.


Nginx에서 gzip설정하기

Nginx에서 gzip 설정하는 부분

Nginx를 apt-get을 통해서 패키지로 설치를 했다면 /etc/nginx경로에 있는 nginx.conf에서 설정이 가능합니다.

또한 패키지를 통해 설치를 하셨다면 다음처럼 nginx.confhttp블록 안에 Gzip Settings라고 나와있습니다.

nginx.conf

http {

    ...

    ##
    # Gzip Settings
    ##

    // 이 아래 설정들이 주석처리 되어있거나 설정되어 있을 수도 있습니다.

    gzip on;
    gzip_disable "msie6";

    # gzip_vary on;
    # gzip_proxied any;
    # gzip_comp_level 6;
    # gzip_buffers 16 8k;
    # gzip_http_version 1.1;
    # gzip_types text/plain text/css application/json application/javascript text/xml application/xml application/xml+rss text/javascript;

    ...
}


Nginx에서 gzip 설정하기

간단하게 위에 있는대로 주석이 nginx.conf에 나와있고 주석을 제거해주시면 되고 만약 해당 부분이 없다면 아래부분을 nginx.confhttp블록에 그대로 추가해주시면 됩니다.

nginx.conf

...

http{

    ...

    ##
    # Gzip Settings
    ##

    gzip on;
    gzip_disable "msie6";

    gzip_vary on;
    gzip_proxied any;
    gzip_comp_level 6;
    gzip_buffers 16 8k;
    gzip_http_version 1.1;
    gzip_types text/plain text/css application/json application/x-javascript text/xml application/xml application/xml+rss text/javascript;

    ...

}

...

각각에 대한 내용은 nginx 공식문서를 참고하면 다음과 같습니다.

  • gzip [on/orr]: gzip의 설정을 on/off하는 명령어입니다.
  • gzip_disable [regex]: 해당 명령어 다음에 오는 문장이 요청 헤더에 User-Agent와 일치하면 gzip을 하지 않습니다.
  • gzip_vary [on/off]: gzip, gzip_static, or gunzip의 설정들이 on으로 되어있을 때 응답 헤더에 “Vary: Accept-Encoding”를 넣을지 말지에 대한 명령어 입니다.
  • gzip_proxied: 요청과 응답에 따라서 프록시된 요청에 대해서 gzipping을 할지 말지에 대한 설정입니다. “any”로 설정하면 모든 응답에 대해서 gzipping을 수행합니다.
  • gzip_comp_level [level]: 응답에 대한 압축의 정도를 의미하며 level의 값은 1부터 9까지 가능합니다.
  • gzip_buffers [num] [size]: num은 버퍼의 갯수를 의미하며 size는 그 버퍼의 크기를 의미합니다.
  • gzip_http_version [versino]: minimum HTTP 통신의 버전을 정합니다.
  • gzip_types [types in array]: “text/html”을 제외하고 MIME 타입에서 또 어떠한 응답 형태들을 gzipping 할지 정할 수 있습니다.


Nginx에서 gzip 설정 적용하기

이제 바뀐 설정을 적용해보도록 하겠습니다. 반드시 재시작 했다는 문구가 나와야합니다!

$ sudo /etc/init.d/nginx restart

or

$ sudo service nginx restart

or

$ sudo systemctl restart nginx


적용결과

이제 gzip을 적용하면 제대로된 응답 요청에 대해서(HTTP STATUS CODE가 200) 다음 처럼 응답 헤더에 Content-Encoding:gzip가 표시됨을 알 수 있습니다.

Response Header


참고자료

Circle CI에서 TEST를 다 통과하면 원하는 서버에 배포하도록 해보자


환경

  • Cricle CI
  • Github Repository
  • Remote Server(Ubuntu 14.04) with SSH key


사전 준비사항

  • yml 설정을 하고 Circle CI를 통해 빌드한 경험이 있어야 합니다.
  • Github를 통해서 Merge하고 Deploy까지 할 예정이기에 Github에 프로젝트가 있어야 합니다.
  • 배포할 서버가 있어야하며 서버에 접속할 수 있는 SSH Key가 있어야 합니다.


배포과정

배포하는 과정은 크게 나누면 아래와 같습니다. 위에 있는 사전 준비사항에 있는 과정들을 다 진행해본 경험이 있어야합니다.

  1. 원하는 프로젝트를 특정 branch에 merge(이 글에서는 develop branch에 merge함을 통해서 진행 할 예정)
  2. CI에서 빌드
  3. CI에서 yml코드에 있는 쉘 스크립트를 통해서 서버에 접속 및 배포 코드 실행
  • Merge(in Github) -> Build(in Circle CI) -> Deploy(in Circle CI and Server)


배포 세팅 과정

위에서는 배포 세팅이 완료되었을 때 어떠한 순서로 배포가 이루어졌는지에 대한 과정이었다면, 이제는 우리가 어떠한 순서로 배포 세팅을 할지에 대해서 입니다.

  1. Github와 연결된 Circle CI project setting에서 PERMISSIONS에 서버 SSH Key를 복사해서 추가합니다.
  2. circle.yml에 deployment를 추가하고 관련된 코드들을 입력합니다.
  3. 원격 서버에 설치 스크립트를 추가합니다.


배포 세팅 과정

Circle CI에 연결된 프로젝트에 SSH Key를 추가

서버에 SSH 접속을 할 때 사용하는 Key를 Circle CI에 추가하도록 합시다.

Circle CI에 들어가서 로그인 하고 대시보드에서 좌측에 보면 프로젝트 목록이 있는데 옆에 있는 톱니바퀴 모양을 클릭해 설정에 들어가도록 합니다.

Circle CI Project Setting Icon


프로젝트에 들어가면 아래 보이는 바와 같이 SSH Permissions를 클릭합니다.

SSH Permissions


그러면 메인 화면에 아래와 같이 SSH Key를 추가 할 수 있는 창이 나오며 여기서 가장 우측에 파란 버튼인 Add SSH Key를 선택합니다.

Add SSH Key


아래와 같은 다이얼로그 창이 나오면 Hostname에 해당서버 이름을 Private Key에 해당 서버에 대한 개인키를 넣습니다.

여기서 개인키를 넣을 때 -----BEGIN RSA PRIVATE KEY-----부터 -----END RSA PRIVATE KEY-----까지 모두 복사해서 붙여넣으셔야 인식을 합니다!

Add SSH Dialog


이제 Circle CI에 Key를 추가하는 부분은 완료 되었습니다. 위의 과정을 제대로 추가하셨다면 Circle CI에서 자동으로 ~/.ssh폴더에 id_[Hostname]의 형태로 키를 저장해줍니다.


circle.yml에 branch 추가 및 커맨드 추가

이제 circle.yml에 특정 branch에 Merge되면 Deplyment를 진행하는 코드를 추가하겠습니다. 코드는 아래와 같이 매우 간단합니다.

circle.yml

...

deployment:
    [name]:
        branch: [branch name]
        commands:
            - [command for deployment]

...


LinkU 서비스의 같은 경우 개발환경에 대한 배포는(branch도 develop 브랜치) 아래처럼 만들었습니다.

circle.yml


...

deployment:
    development:
        branch: develop
        commands:
            - ./deploy_to_development_server.sh

...


배포 스크립트 작성

이제 스크립트를 실행시켜서 원격 서버에 접속해 배포하는 과정을 해봅시다.

원격 서버에 접속하고 명령어들을 실행하는 법부터 보면 아래와 같습니다.

#!/bin/bash
ssh [user]@[domain] -i [ssh private key file] -o StrictHostKeyChecking=no <<'ENDSSH'
...
commands
...
ENDSSH
  • <<'ENDSSH' 부터 아래 있는 ENDSSH까지 있는 명령어들을 원격서버에서 실행합니다. 이때 << 다음에 오는건 꼭 ENDSSH일 필요는 없고 원하시는대로 입력해도 되지만 마지막에는 꼭 같아야합니다.
  • StrictHostKeyChecking=no는 ssh key fingerprint를 무시하고(서버에 키를 무조건 저장하고) 진행한다는 의미이며, ssh로 원격 서버에 접속할 때 yes or no룰 묻지 않습니다.


이제 원격서버의 유저 Root Directory에(cd ~) ./set_up_server.sh라는 스크립트가 있다면 아래처럼 실행 할 수 있습니다.

#!/bin/bash
ssh -p [port number] [user]@[domain] -i [ssh private key file] -o StrictHostKeyChecking=no <<'ENDSSH'
./set_up_server.sh
exit
ENDSSH


링쿠 서비스의 경우 다음처럼 스크립트를 작성하였습니다. 다만 보안상 포트 번호만 가리겠습니다. Circle CI에서 저장한 SSH key Host 이름이 linku-dev라면 ~/.ssh/폴더에 접미사 id_가 붙어서 id_linku-dev로 저장되어있습니다!

#!/bin/bash
ssh -p [port number] linku@dev.linkuniversity.me -i ~/.ssh/id_linku-dev -o StrictHostKeyChecking=no <<'ENDSSH'
./set_up_server.sh
exit
ENDSSH


원격 서버에 배포 스크립트 추가

위의 글에서 ./set_up_server.sh라는 쉘 스크립트 파일을 통해서 서버에 서버를 세팅합니다. 해당 sh파일에 원하는 서버 세팅 코드를 추가해주시면 됩니다.

예제로 저희 프로젝트 코드를 보여드리겠습니다.

set_up_server.sh

#!/bin/bash
cd /home/linku
./set_up_frontend.sh
./set_up_backend.sh

다음은 set_up_backend.sh의 코드입니다. 불필요한 부분도 있기에 중간은 생략하겠습니다.

set_up_backend.sh

#!/bin/bash
source ~/.bash_profile
cd /home/linku/LinkU;
git pull origin master;
cd /home/linku/LinkU/linku_backend;
pyenv activate LinkU;
pip install -r requirements.txt;
python manage.py makemigrations;
python manage.py migrate;
UWSGI_COUNT=$(pgrep -c uwsgi)
if [ $UWSGI_COUNT -ge 1 ]
then
        ...
else
        ...
fi
pyenv deactivate;


마무리

이제 develop 브랜치에 merge가 되면 자동으로 서버에 배포가 되게 됩니다! :)

Android에서 실행하는 기기의 SDK Version을 받아오고 그에 따라서 다른 실행을 해주는 코드를 작성해보자


환경

  • Android


기기의 SDK VERSION 가져오기

안드로이드에서는 android.os.Build.VERSION.SDK_INT를 통해서 기기의 SDK Version을 가져올 수 있습니다.

다음 아래가 해당 코드입니다. if문 혹은 switch문에 따라서 해당 Version에 해당하는 코드를 실행시켜 주시면 됩니다.

  • if문의 경우

if(android.os.Build.VERSION.SDK_INT >= 24)
    // Code For Android Version higher equal than 24
else
    // Code For Android Version lower than 24

  • switch문의 경우

switch(android.os.Build.VERSION.SDK_INT){
    case 24 :
        // Code For Android Version 24
        break;
    case 23 :
        // Code For Android Version 23
    default :
        // Other cases
}


참고자료

create-react-app으로 만들어진 React에서 시스템의 환경변수를 가져오는 방법을 알아보자.


환경 및 선수조건

  • npm
  • nodejs
  • React
  • create-react-app
  • npm을통한 create-react-app의 설치 및 프로젝트 생성 (참고)


환경변수 가져오기

create-react-app을 통해서 생성한 React 프로젝트는 process.env를 통해서 쉽게 환경변수를 가져올 수 있습니다.

다음 아래가 해당 코드입니다. 주의해야 할점은 반드시!

  • 꼭 앞에 접미사로 REACT_APP_를 붙여줘야 합니다.
  • 시스템에 저장된 시스템 변수의 이름이 LINKU_SERVER_ENVIRONMENT라면 REACT_APP_를 붙여서 REACT_APP_LINKU_SERVER_ENVIRONMENT라고 해야합니다!
if (process.env.REACT_APP_LINKU_SERVER_ENVIRONMENT=== 'local')
    console.log("local");
else
    console.log("not local")


추가

  • .bash_profile에 추가하시고 source 명령어로 환경변수를 적용해줘야 돌아가는데 가끔 가져오지 못한다면 컴퓨터를 재부팅하시면 됩니다. (이거에 대한 자세한 이슈는 조사가 필요할듯 싶네요)


업데이트(2020.07.19): Ubuntu 지원 버전에 따른 설치 방법 업데이트

업데이트(2018.03.03): 기존에 webroot plugin 방식에서 python-certbot-nginx을 사용하는 방식을 추가하였습니다. python-certbot-nginx를 통해서 설치하는게 훨씬 간단합니다.

무료 인증서 서비스를 제공하는 Let’s Encrypt를 통해서 서비스에 ssl 설정을 추가하자


환경

  • Ubuntu 20.04 (LTS)
  • Ubuntu 18.04 (LTS)
  • Ubuntu 16.04 (LTS)
  • Ubuntu 14.04 (LTS)
  • Nginx (version: 1.4.6)(apt-get을 통한 설치)
  • 도메인


사전 준비사항

  • Nginx에 대한 간단한 사용법
  • HTTPS와 인증서에 대한 개념
  • 도메인도 하나 필요합니다. 여기에서는 example.com이라는 도메인이 있다고 가정하고 진행하겠습니다.


소개

이 글은 How To Secure Nginx with Let’s Encrypt on Ubuntu 20.04를 간단하게 요약 정리한 글이며 SSL과 인증서에 대한 소개는 다음 포스팅에서 하도록 하겠습니다.

Let’s Encrypt는 Certificate Authority (CA). 즉, 인증기관으로 보다 쉬운 방법과 무료로 TLS/SSL 인증서를 발급해서 HTTPS 통신을 가능하게 해주는 서비스 기관입니다.

Let’s Encrypt는 certbot 이라는 소프트웨어를 통해서 이를 쉽게 자동화하도록 만들어져 있습니다.


1. certbot 설치

Ubuntu 16.04 (LTS), Ubuntu 18.04 (LTS) 저장소 세팅

저장소 설정 및 업데이트 진행

$ sudo apt-get update
$ sudo apt-get install software-properties-common
$ sudo add-apt-repository universe
$ sudo add-apt-repository ppa:certbot/certbot
$ sudo apt-get update

Ubuntu 20.04 (LTS) 저장소 세팅

저장소를 설정 및 업데이트 진행

$ sudo apt-get update
$ sudo apt-get install software-properties-common
$ sudo add-apt-repository universe
$ sudo apt-get update

공통

certbot 설치

$ sudo apt-get install certbot python3-certbot-nginx


2. Nginx 세팅

Certbot이 자동으로 SSL을 세팅해주기 때문에 server blockserver_name을 설정해주면 됩니다.

$ sudo vim /etc/nginx/sites-available/[your server block]

아래는 제 예시입니다. undang_backend_nginx.conf에 블록들이 있기 때문에 아래처럼 되었습니다.

$ sudo vim /etc/nginx/sites-available/undang_backend_nginx.conf

이제 서버 블록 파일 안에 server_name을 설정하고자 하는 도메인 이름으로 변경해주시면 됩니다. 저는 아래와 같습니다.

...
# configuration of the server
server {

    listen      80;
    listen [::]:80;
    # Put your domain next to server_name
    server_name undang.twpower.me;
    charset     utf-8;

    # max upload size
    client_max_body_size 75M;   # adjust to taste

...

}

설정이 완료 되었다면 저장하고 아래 명령어를 통해서 재시작합니다.

$ sudo nginx -t
$ sudo service nginx reload


3. SSL 인증 획득하기

다음 아래 명령어를 사용하면 nginx plugin을 통해서 가능합니다. 도메인을 추가적으로 더 하고 싶다면(위에 server_name에도 물론 설정이 되어있어야겠죠?) -d 옵션을 주고 더 주가하면 됩니다.

$ sudo certbot --nginx -d example.com -d www.example.com

제 예시는 아래와 같습니다.

$ sudo certbot --nginx -d undang.twpower.me

그러면 아래와 같이 1과 2를 선택하는 화면이 나오는데 저와 같은 경우는 모든 경우를 https로 하고 싶어서 redirect를 허용하는 2번을 하였습니다.

Please choose whether or not to redirect HTTP traffic to HTTPS, removing HTTP access.
-------------------------------------------------------------------------------
1: No redirect - Make no further changes to the webserver configuration.
2: Redirect - Make all requests redirect to secure HTTPS access. Choose this for
new sites, or if you're confident your site works on HTTPS. You can undo this
change by editing your web server's configuration.
-------------------------------------------------------------------------------
Select the appropriate number [1-2] then [enter] (press 'c' to cancel): 2

번호를 선택해주면 아래처럼 진행되며 key들도 자동으로 생성해줍니다. success


4. 인증서 자동갱신 설정 확인

설정한 certbot은 90일 동안만 유효하기 때문에 갱신을 해줘야합니다. 매번 해주기 귀찮으나 설치한 certbot은 자동으로 갱신을 이틀 단위로 해줍니다.

해당하는 갱신이 제대로 되는지는 아래 명령어를 통해서 확인 가능하며 에러가 나타나지 않으면 renewal이 정상적으로 작동 할겁니다.

$ sudo certbot renew --dry-run

Ubuntu의 경우 /etc/cron.d/에 보면 certbot이 생성되어있습니다.


5. SSL 적용 확인 및 평가

본인의 서버에 SSL이 적용이 잘 되었는지 평가할 수 있는 여러 사이트가 있는데 들어가서 본인의 서버 도메인을 입력하면 됩니다.

https://www.ssllabs.com/ssltest/

ssl-test


참고자료






아래는 webroot plugin 방식을 통해 설정하는 방법입니다.

1. certbot 설치

apt-get에 certbot저장소를 추가해줍니다.

$ sudo add-apt-repository ppa:certbot/certbot

패키치 목록을 업데이트해주고 certbot을 설치합니다.

$ sudo apt-get update
$ sudo apt-get install python-certbot-nginx

간혹 업데이트와 업그레이드가 되지 않는 경우가 있는데 그러면 직접 아래처럼 업그레이드를 해줍니다. 업데이트가 자주 바뀌며 지원되는게 달라지기 때문에 certbot 최신 버전을 설치하시길 추천드립니다.

$ sudo add-apt-repository ppa:certbot/certbot


2. 인증서 발급받기

Let’s Encrypt는 다양한 plugin들을 통해서 SSL 인증서를 제공합니다. 아파치를 제외한 대부분의 설치 플러그인들은 발급만 해주고 나머지 설정을 들을 직접 해주어야합니다.

본문에서는 webroot plugin을 통해서 인증서를 발급해 보겠습니다.


Webroot Plugin 사용하기

Webroot Plugin은 /.well-known이라는 폴더에 파일을 추가해서 Let’s Encrypt 서버가 접속할 수 있도록 합니다.

우선, /etc/nginx/sites-available/에 있는 conf 파일들 중에서 추가하고자 하는 파일을 열어줍니다. 여기서는 default conf 파일을 통해 설정해보도록 하겠습니다.

$ sudo vim /etc/nginx/sites-available/default


이제 해당 파일의 server 블럭 안에 다음을 추가합니다.

server {
        . . .

        location ~ /.well-known {
                allow all;
        }

        . . .
}


nginx의 설정 파일이 문법이 제대로 되었는지 확인하고 재시작합니다.

$ sudo nginx -t
$ sudo service nginx restart


이제 server block에서 root설정이 어디인지 알아보고 인증서를 발급해보겠습니다. 인증서를 발급하기 위해서는 webroot-path라는 부분에 server blockroot 경로를 지정해줘야 발급이 가능하다고 합니다.

다음 명령어를 통해서 설정파일에 들어갑니다. 이번에도 역시 /etc/nginx/sites-available/에 있는 default를 이용하겠습니다.

$ vim /etc/nginx/sites-available/default


문서의 server block을 보시면 아래처럼 나와있는 root에 설정된 경로를 기억해주시면됩니다. 다른 설정을 하지 않았다면 기본으로 /usr/share/nginx/html으로 나와있습니다.

server {
        . . .
        root /usr/share/nginx/html; # 이 경로를 기억해야합니다.
        . . .
}


이제 인증서를 발급해봅시다. --webroot-path에 위에 있던 root로 설정된 폴더 경로를(여기서는 /usr/share/nginx/html), -d 옵션을 통해서 지정하고자 하는 도메인명을 넣어줍니다. 여러 도메인을 적용하고 싶다면 최상위 도메인부터 앞에서부터 적어주어야 합니다. 만약 본문처럼 example.comdev.example.com 둘다 하고 싶다면 아래처럼 적용하면 됩니다.

$ sudo certbot certonly --webroot --webroot-path=/usr/share/nginx/html -d example.com -d dev.example.com


처음 적용하는거라면 Email과 Terms of Service에 동의해야 합니다. 입력하고 동의를 하고 나면 다음처럼 성공적으로 완료되었다는 창이 나오며 인증서들과 키가 어떤 경로에 위치한다는 정보와 만기일이 나옵니다. 다음 아래 내용은 How To Secure Nginx with Let’s Encrypt on Ubuntu 14.04에 있는 결과를 가져왔습니다.

IMPORTANT NOTES:
 - Congratulations! Your certificate and chain have been saved at
   /etc/letsencrypt/live/example.com/fullchain.pem. Your cert
   will expire on 2017-07-26. To obtain a new or tweaked version of
   this certificate in the future, simply run certbot again. To
   non-interactively renew *all* of your certificates, run "certbot
   renew"
 - If you lose your account credentials, you can recover through
   e-mails sent to sammy@example.com.
 - Your account credentials have been saved in your Certbot
   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 Certbot so
   making regular backups of this folder is ideal.
 - If you like Certbot, please consider supporting our work by:

   Donating to ISRG / Let's Encrypt:   https://letsencrypt.org/donate
   Donating to EFF:                    https://eff.org/donate-le


Certificate 파일

webroot plugin을 통해 잘 발급을 받았다면 아래와 같은 4개의 파일들이 생성됩니다.

  • cert.pem: 도메인의 인증서
  • chain.pem: Let’s Encrypt chain 인증서
  • fullchain.pem: cert.pem + chain.pem
  • privkey.pem: 인증서의 개인키


위의 파일들은 /etc/letsencrypt/archive에 위치하며 /etc/letsencrypt/live/[your_domain_name]에서 가장 최근의 인증서들에 대해 symbolic link를 가지고 있습니다. 이 위치에서 가장 최신의 인증서를 가지고 있기 때문에 인증서와 키들을 참조할 때 /etc/letsencrypt/live/[your_domain_name] 폴더를 이용해야 합니다.

다음 아래의 명령어를 통해 해당 4개의 파일들이 존재하는지 확인할 수 있습니다.

$ sudo ls -l /etc/letsencrypt/live/your_domain_name


디프-헬만 그룹 추가하기

보안을 위해서 디프-헬만 그룹을 추가해야한다고 합니다. 아래의 명령어를 통해 실행해줍니다. 화면에 여러 점들이 찍히면서 진행이되며 시간이 다소 몇분 소요됩니다

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

다 생성이 되면 /etc/ssl/certs/에서 dhparam.pem 파일을 확인 할 수 있습니다.


3. TLS/SSL 설정하기

이제 Nginx의 server block들을 처리해서 TLS/SSL 설정을 하도록 하겠습니다. nginx에서 default 파일을 수정합시다.

$ sudo vim /etc/nginx/sites-available/default


server block에서 80포트에 대한 기본정보가 아래처럼 나와 있을텐데 지워줍니다.

server{
    ...
    listen 80 default_server;
    listen [::]:80 default_server ipv6only=on;
    ...
}    


이제 SSL 관련 설정 세팅을 시작해봅시다. server block안에 다음 내용들을 추가합니다. 여기서 [domain]은 등록하신 도메인을 입력해야합니다!

server{
    ...
    listen 443 ssl;

    server_name [domain] [another_domain];

    ssl_certificate /etc/letsencrypt/live/[domain]/fullchain.pem;
    ssl_certificate_key /etc/letsencrypt/live/[domain]/privkey.pem;
    ...
}


위의 작업이 끝났다면 아래의 내용도 그대로 server block에 추가합니다.

server{
    ...
    ssl_protocols TLSv1 TLSv1.1 TLSv1.2;
    ssl_prefer_server_ciphers on;
    ssl_dhparam /etc/ssl/certs/dhparam.pem;
    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: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_session_timeout 1d;
    ssl_session_cache shared:SSL:50m;
    ssl_stapling on;
    ssl_stapling_verify on;
    add_header Strict-Transport-Security max-age=15768000;
    ...
}


마지막으로 아래에 다음과 같은 새로운 server block을 추가합니다.

해당 block은 해당 도메인에 대한 http의 요청을 https로 redirect 해주는 block입니다.

server {
    listen 80;
    server_name example.com www.example.com;
    return 301 https://$host$request_uri;
}


자, 이제 설정이 다 끝났습니다. 다음처럼 문법을 확인하고 재시작해줍시다. 아래와 같은 스크린샷이 나오면 정상적으로 작동하는겁니다.

$ sudo nginx -t
$ sudo service nginx restart
or
$ sudo /etc/init.d/nginx restart
# sudo service nginx restart가 실행되지 않으면 위의 명령어로도 실행 가능합니다.

Nginx Restart


추가로! 다음 아래 사이트에서 마지막 d=에 설정하신 도메인을 넣어주시면 ssl 설정이 완료되었는지 등급이 어느정도인지 알 수 있습니다. 제대로 따라오셨다면 A+가 나와야합니다.

https://www.ssllabs.com/ssltest/analyze.html?d=[domain]


4. 갱신 자동화하기

Let’s Encrypt는 3개월간 유효하며 이를 자동적으로 갱신을 해야하는데 crontab을 통해서 그 일을 자동화시켜 보겠습니다.

다음 명령어를 통해서 crontab을 엽니다.

$ sudo crontab -e


텍스트 에디터로 열리면 아래의 명령어를 파일의 끝에 추가해줍니다.

. . .
15 3 * * * /usr/bin/certbot renew --quiet --renew-hook "/usr/sbin/service nginx reload"

간단히 설명을 하면

  • 15 3 * * *: 매일 3:15 AM에 실행하겠다는 의미입니다.
  • /usr/bin/certbot: 실행하는 파일이며
  • renew: 자동으로 certbot이 인증서들을 보고 갱신이 필요하면 갱신을 진행해줍니다.
  • –quiet: 사용자에게 output을 전달하지 않고 실행합니다.(백그라운드)
  • –renew-hook “/usr/sbin/service nginx reload”: 파일이 새로 갱신되었다면 Nginx를 reload해줍니다.


참고자료