nginx 서버에 HTTPS사용을 위한 SSL 인증서 발급받기 (Let’s Encrypt)

7

LEMP 스택에 워드프레스 사이트 설치하기 시리즈 연재작 마지막 단계는 HTTPS 사용일 것입니다. SSL 인증서는 무료인 Let’s Encrypt(렛츠 인크립트)를 사용할 것이기 때문에 웹서버로 아파치를 사용했을 때와 인증서 발급 절차는 같을 것이지만 이 글에서는 nginx를 웹서버로 사용하므로 nginx 설정파일을 다룬다는 점에서 다릅니다.

반면, 아파치 웹서버를 사용하는 bitnami 워드프레스 블로그 사용시  SSL 인증서발급과 설정에 대한 내용은 이글보다는 아래링크 글을 참고하시기 바랍니다. 이글을 따라 하시려는 분도 아래링크글에서 사전지식을 쌓을 만한 내용도 있습니다.

 

이 글은 리눅스서버  LEMP 스택에 WordPress 설치하기 시리즈 연재작의 일환으로 작성되었지만 워드프레스를 사용하지 않는 경우에도 적용가능합니다. 웹서버로 nginx(엔지엑스)를 사용하는 우분투 16.09 LTS 기준으로 설명됩니다. 

letsencrypt.conf 설정파일

Let’s Encrypt 인증서를 발급받을때 webroot(웹루트)라는 플러그인을 사용해서 다운받을 건데요. webroot path 라고해서 자신의 리눅스 서버 어딘가에 .well-known 폴더하위에 acme-challenge 이라는 폴더(디렉토리)가 필요하다고 합니다. 그리고 그위치를 알리는 location 블록 내용이 작성된 letsencrypt.conf 파일을 준비해야합니다.

certbot-auto의 webroot 경로 폴더 준비하기

저는 /var/www/ 하위에 letencrypt 라는 디렉토리를 만들어 그안에 .well-known 폴더를 만들고 또 그안에 acme-challenge 폴더를 만들어야겠습니다. 

참고: 폴더중에 .well-known 처럼 폴더이름 앞에 점(.)이 붙은건 숨김 폴더라는 뜻입니다.

라이트세일 인스턴스 서버에 CLI 접속(ssh)을 통해서 ubuntu 사용자로 아래 처럼 mkdir 명령어를 이용해 폴더를 만들어 주세요.

mkdir -p /var/www/letsencrypt/.well-known/acme-challenge

위처럼 mkdir 명령어의 -p 옵션을 넣으면 중간에 존재하지 않는 디렉토리까지 함께 만들어줍니다. 우리 서버의 현재 디렉토리는 /var/www 까지만 있기때문에 위 명령어는 /var/www 하위에 letsencrypt 폴더, 또 그 안에 .well-known 폴더, 다시 그안에 acme-chanllenge  폴더를 연속해서 만들어줍니다.

mkdir 명령어로 acme-challenge 폴더 생성

 

webroot 폴더 경로를 알려주는 letsencrypt.conf 파일 생성

위의 acme-challenge 폴더위치를 nginx 라우팅설정파일에 알려야하는데요. 별도의 파일(letsencrypt.conf)로 작성해두고 이 파일을 nginx 라우트 설정파일에 껴넣는 코드를 작성할 겁니다.

 /etc/nginx/snippets/ 폴더 아래 letsencrypt.conf 파일을 만들겠습니다. 그런데 /etc/nginx/snippets/ 폴더는 소유자와 사용자그룹이 root입니다. ubuntu 유저로는 이 폴더안에 파일을 생성할 수 없으므로 sudo 명령어를 앞에 붙여서 root 사용자로 파일을 만들어줍시다. 새로운 파일 만들기 리눅스 명령어는 touch이고 아래같은 형태로 만들 수 있습니다.

sudo touch /폴더/경로/새로운파일이름

그러면 아래처럼 입력하면 되죠

sudo touch /etc/nginx/snippets/letsencrypt.conf

 

이제 방금 만든 letsencrypt.conf 파일을 열어서 그 내용을 작성해야하는데요. 이 파일은 root 사용자로 만들어 져있기 때문에 ubuntu는 수정할 권한이 없습니다. CLI 텍스트편집기인 nano나 vim 으로 작성하려면 권한변경이 별도로 필요없겠지만 ubuntu로 접속한 SFTP에서 수정하려면 일단은 ubuntu가 수정할 수 있도록 권한설정이 되어있어야합니다. 

소유자는 root 그대로 두고 사용자그룹을 ubuntu로 바꾼 뒤 

sudo chown 소유자명:그룹명 대상파일명

그룹사용자가 수정할 수 있도록 권한을 775로 바꾸겠습니다. 아래 두개 명령어죠.

$ sudo chown root:ubuntu /etc/nginx/snippets/letsencrypt.conf
$ sudo chmod 775 /etc/nginx/snippets/letsencrypt.conf

 

아래그림은 CLI에서 위 3개 명령어를 연속으로 입력한 모습입니다.

letsencrypt.conf 파일 생성 후 권한 설정하는 명령어 연속입력

그러면 FTP 프로그램에서 접속해서 본 폴더 구조는 아래와 같습니다.

ftp 프로그램 transmit 5에서 본 letssencrypt.conf 파일 폴더트리

위 파일을 열어 내용은 아래와 같이 작성하고 저장해줍니다. 

location ^~ /.well-known/acme-challenge/ {
    default_type "text/plain";
    root /var/www/letsencrypt;
}

앞서 만들어뒀던 well-known/acme-challenge 폴더의 위치가 /var/www/letsencrypt 폴더임을 말해주는 location 블록이 생겼습니다. 

nginx 라우팅 설정에 include문 포함시키기

이제 nginx 라우팅설정 파일 중간중간에 include 문으로 위 파일 내용을 껴넣게 됩니다. include문을 쓰지않고 위 내용을 그냥 여러번 작성할 수도 있는데요. 이해하기 어려울진 모르겠지만 중복되는 코드는 아래처럼 나누는게 프로그래머들의 전통입니다.

그럼 이제 시리즈 이전 글에서 수정했던 nginx의 라우팅 설정파일을 열어서 include문으로 추가해 줄 차례입니다. /etc/nginx/sites-available/default 파일을 텍스트 편집기에서 다시 열어주세요.

default 파일의 위치를 transmit 에서 확인

이 파일 내용을 열어보면 앞서 도메인열결 및 www 리다이렉팅 설정했을 때 그 내용이 그대로 있을 텐데요.  NGINX의 HTTP 설정 server {...} 블럭 마다 아래와 같은 내용으로 한줄 씩 추가해줍시다.

include /etc/nginx/snippets/letsencrypt.conf;

아래그림 처럼 말예요. 

nginx 의 라우팅설정 default 파일의 전체내용

중요: 위 내용중 server_name 줄과 리다이렉팅하는 return 301 http://…. 줄에는 제 도메인인 swiftcoding.org 대신 여러분 자신의 도메인이름을 넣어야합니다.

이러면 include 문이 작성된 위치마다  letsencrypt.conf 파일의 내용이 작성된 것과 같은 효과가 있습니다.  위 처럼 단 두군데면  letsencrypt.conf을 따로 만드는게 번거로워 보일뿐이지만 여러군데가 되면 간결함과 유지보수시에 차이가 나게됩니다. 수십군데 써놓는다고 해도 나중에 내용을 수정하게 되면 letsencrypt.conf 파일 하나만 수정하면 되는 것이죠.

 

nginx 설정파일을 수정했으니 nginx를 재시작 해줘야합니다. 

sudo nginx -t 

위 명령어로 설정파일 문법이 이상없는지 확인해봐서 …syntax is oktest is successful 메시지가 나오는지 먼저 확인한다음 아래 재시작 명령어를 통해 재시작해주세요.

sudo service nginx restart

nginx 재시작 명령어 입력

이제 SSL 인증서를 발급 받을 준비가 되었습니다. 아래에서 계속됩니다.

Let’s Encrypt SSL 인증서 발급 받는 방법

인증서 발급프로그램 certbot-auto 다운로드 하기

우선 Let’s Encrypt의 인증서를 발급 받으려면 그것을 도와주는 프로그램인 certbot-auto(서트봇-오토)를 다운로드 받아야합니다. apt-get 명령어를 통해서 하는 방법도 있긴하지만 certbot-auto 프로그램의 위치를 딱 지정하기위해서 wget 명령어로 직접 다운로드 받겠습니다.

참고: wget은 CLI 환경에서 사용할 수있는 프로그램으로서, 웹에있는 리소스를 다운받는 작업을 수행하는데 리눅스에 기본적으로 설치되어있을 것입니다.

 

우선 저장할 위치를 저는 현재 사용자인 ubuntu 사용자의 홈폴더로 하기로 했습니다. 경로는 /home/ubuntu/ 일 것이지만 CLI에서 현재 ubuntu 사용자를 사용중이니까 짧게 ~ 물결표시로 표현되죠.

다른 위치에 계시다면 cd /home/ubuntu/ 또는 cd ~  명령문으로 ubuntu 사용자 홈폴더로 이동해 오세요.

아래처럼 ls 명령어로 살펴보니 숨김파일과 폴더만 나오는 군요. 이곳에 certbot-auto 라는 프로그램을 저장하겠습니다.

CLI에서 ubuntu 홈폴더에서 ls 명령어로 내용물을 살펴보았다

 

이제 특정 웹주소에 있는 인증서 발급 프로그램 패키지인 certbot-auto를 다운로드 받으라는 명령어를 입력해 봅시다. 아래 같은 형태로 입력하면 CLI 현재경로에 다운로드 받습니다.

wget 인터넷파일의URL 

원하는 위치로 다운로드 받으려면 -P 옵션을 사용하면 됩니다.

wget 인터넷파일URL -P 목적지폴더경로

그리고 certbot-auto 의 다운로드 URL은 https://dl.eff.org/certbot-auto 이므로 ㅇ아래처럼 입력해서 받았습니다.

wget https://dl.eff.org/certbot-auto -P /home/ubuntu/

wget 리눅스 명령어를 이용해 certbot-auto 다운로드 완료 - certbot-auto saved

 

다운로드가 완료되면 위 그림처럼 화면 아래쪽에 ‘…/certbot-auto’ saved 라는 메시지를 볼 수 있고 ls 명령어로 확인해볼 수 있습니다.

 

이 프로그램을 처음 다운 받았을 때는 서버의 사용자그룹 그 어느 누구도 이 파일에 대한 실행권한을 가지고 있지 않으므로 cerbot-auto 프로그램을 사용하기 전에 권한을 변경해주어야합니다. 

chmod a+x /폴더경로/파일

의 형태인데요.  chmod는 권한변경 명령어이고 a+x 는 모든사용자(a)에게 추가하는(+) 실행권한(x) 라는 뜻입니다.

참고: 권한을 a+x 대신 775로 해도됩니다.

그래서 아래처럼 입력하면됩니다.

chmod a+x certbot-auto

certbot-auto의 실행권한을 준다

SSL 인증서 발급받기: cerbot-auto 실행

이제 앞서 다운 받았던 cerbot-auto을 실행해서 인증서를 발급받을 것인데요. 그에 앞서 입력해줘야할 명령어가 하나 더 있습니다.

export LC_ALL="C"

우분투 리눅스 특정 버전의 OS에서는 위 명령어없이 진행할 경우 발급과정에서 에러가 날 수 있다고 합니다.

 

certbot-auto의 플러그인 중 webroot 라는 플러그인을 사용해서 받는 과정 중간 중간에 이메일주소나 약관동의등을 거쳐야하는데 미리 대답까지 넣어서 한번에 실행시키는 명령어는 아래와 같습니다.

certbot-auto파일경로 certonly --webroot --agree-tos --no-eff-email --email 자신의@이메일주소 -w /webroot/폴더/경로 -d 도메인1 -d 도메인2

약관이나 메일링리스트 참여여부등  내용을 모두 읽어보면서 발급받고 싶다면 아래처럼 입력하고 시작하면 되지만 번거롭죠. 전 위에 걸 쓰려고 합니다.

certbot-auto certonly --webroot -w /webroot/폴더/경로 -d 도메인명1 -d 도메인명2

 

certbot-auto 사용 옵션에대한 설명을 하자면 certonly 는 인증서만 받아오겠다는 것이고 앞에 대시 2개 – – 가 붙은 것들은 옵션 플래그인데요. 

  • –webroot 는 webroot 플러그인을 사용하겠다는 것입니다. 
  • –agree-tos 는 약관에 동의하는 걸로 설정,
  • –no-eff-emailEFF mailing list 에 참여하지 않겠다는 것입니다. 인증서 발급기관(CA)으로부터 영어로된 스팸메일을 받고싶다면 이옵션은 삭제하시면 됩니다. 
  •  –email 당신의@이메일주소  이것은 필수로 이메일을 넣어야합니다. 인증서 만료기간이 다가오거나 만료되면 이메일을 보내옵니다.
  •  -w /webroot/폴더/경로 는 챌린지라고 하는 파일을 생성할 webroot 폴더경로를 지정해줍니다. 우리가 위에서 앞서 /var/www/letsencrypt 폴더 안에 .well-known/acme-challenge 폴더를 만들어 뒀죠.  그래서 -w /var/www/letsencrypt 가 됩니다.
  •  -d 도메인 형태는 여러개 붙일 수 있는데요..인증서 하나가 인증해줄 도메인명(사이트주소)은 여러개일 수 있습니다.  www가 안붙은 메인도메인과 www.서브도메인은 엄밀히는 서로 다르지만 오늘날엔 같은 것으로 취급하는게 일반적이므로 둘다 추가해줄 겁니다. 여러분이 이 두개의 도메인을 서로 다른모습의 사이트로 따로 취급한다고 해도 같은 서버에 있다면 상관없이 함께 발급 받으면 됩니다. 만일 10개의 도메인, 서브도메인등을 하나의 서버에서 서비스하는거라면 뒤에 연속해서 -d 도메인주소  형태로 추가해주고 한 번에 발급받을 수도 있겠습니다.

 

그래서 저는 아래형태의 명령어 한번으로 인증서를 발급받겠습니다. 여러분은 여러분의 이메일주소와 메인도메인, www서브도메인으로 바꿔서 입력하세요.

/home/ubuntu/certbot-auto certonly --webroot --agree-tos --no-eff-email --email MY@EMAIL.COM -w /var/www/letsencrypt -d starry.info -d www.starry.info
참고: 맨앞에 /home/ubuntu/ 경로를 빼고 certbot-auto 또는 ./certbot-auto 해도되는데 이경우 현재 명령어 입력중인 폴더 위치에서 해당 프로그램을 찾을 때입니다(상대경로).

certbot-auto 로 인증서 다운로드 시작하는 명령어 입력

중간에 위처럼 Do you want to continue? 질문에는 Y 를 입력하고 엔터키(리턴키)를 눌러 계속 진행합니다.

 

성공하면 아래처럼 Congratulations! 메시지가 나타나고 /etc/letsencrypt/live/자신의도메인이름/  폴더에 인증서파일인 fullchain.pem과 개인암호키 privkey.pem 파일이 저장되었다는 것과 만료날짜( 2018년 11월 06일 )정보가 나타납니다.

SSL 인증서 다운로드 성공 메시지

그리고 https://letsencrypt.org/donate 으로 방문해서 후원금 좀 보내 달라고 나오네요. 후원금은 신용카드로도 받고 비트코인은 $1000 어치 이상만 받을 수 있다고 합니다. 우리가 공짜로 인증을 받아쓰는데 이 사람들이 망하면 안되겠죠? Let’s Encrypt가 없다면 매년 10만원 이상의 유료 갱신비를 받는 다른 공인인증기관의 인증서를 써야 HTTPS를 쓸수 있을겁니다.

 

어쨌든 저 경로에 인증서가 정말 있는지 확인해봅시다. /etc/letsencrypt/live 폴더는 root 계정으로만 접근이 가능해서 사용자 ubuntu계정으로 접속한 SFTP 클라이언트로는 볼수 없습니다. 터미널에서 root 명령어인 sudo를 붙여서 ls 명령어로 아래처럼 파일보기를 해봅시다. 

$ sudo ls /etc/letsencrypt/live
$ sudo ls -al /etc/letsencrypt/live/도메인이름으로된.폴더

etc/letsencrypt/live 폴더를 살펴보자 ssl 인증서파일이 있었다

 

위 스크린샷에서처럼 fullchain.pem과 privkey.pem을 포함한 4개의 pem파일이 있긴 하지만 이것은 심볼릭 링크(바로가기 파일)이고 원래 위치는 /etc/archive/도메인이름으로된.폴더/ 안에 각각의 파일들이 있다고 나오네요. 이렇게 ls -al 로 살펴보면 파일이름이 아래처럼 표현되어있는데요.

cert.pem -> ../../archive/starry.info/cert1.pem

 -> 화살표를 기준으로 오른쪽이 원본위치입니다.

 앞서 certbot이 알려준대로 우리는 이 심볼릭 링크위치인 /etc/letsencrypt/live/자신의도메인이름/암호키파일이름.pem  경로를 알고 있으면 됩니다.

Letsencrypt(렛츠인크립트) 인증서 만료날짜 확인 명령어

특정 SSL인증서의 만료 시간을 확인하려면 위에 말한 인증서 경로에 주의해서 아래 명령어처럼 사용하면 됩니다.

sudo openssl x509 -noout -dates -in /etc/letsencrypt/live/도메인명.폴더이름/cert.pem

openssl 명령어로 확인

위에서 notAfter=Nov 6 10:21:39 2018 GMT 처럼 GMT 시간 기준, 11월(November) 6일 10시21분39초라는 만료시간 정보가 나오는데 우리나라 기준으로는 여기에 9시간을 더해주면 됩니다.

 

서버에 설치된 모든 렛츠인크립트 인증서 만료날짜를 보고 싶거나 몇일 남았는지 알 수 있는 명령어도 있습니다. certbot-auto 프로그램 파일이 있는 위치에서 아래 명령어를 실행하면 됩니다.

cerbot-auto파일경로 certificates

그럼 아래처럼 /home/ubuntu/cerbot-auto 또는 ./certbot-auto 를 사용하겠죠.

/home/ubuntu/certbot-auto certificates

위 명령어로 나오는 결과에 대한 설명은 아래링크를 참고하시면 되겠습니다.

다음단계

아직까지는 SSL 인증서 발급만 끝났으므로 웹서버인 nginx의 설정파일을 다시 수정, 새로운 설정파일을 생성 해줘야함니다.  연재작 다음 글에서 알아봅시다.

7 댓글

  1. 안녕하세요!
    써주시는 강좌를 보면서 우와 우와 하면서
    저처럼 생판 모르는 초보도 따라할 수 있게 너무 자세하게 설명해주셔서
    너무 감사했습니다.

    여쭤볼 부분이 생겨서 염치없게도
    댓글을 쓰게 되었습니다.
    아마존 AWS LIGHTSAIL 에 TEMP 까는 강좌를 보면서 똑같이 깔고
    다음에 TEMP 에 워드프레스 설치하는 강좌까지 보면서 여기 마지막글에
    도착하게 되었는데요.

    인증서 발급을 위한 명령어를 넣으니 아래와 같은 에러가 납니다.
    구글에서 검색을 해보긴 했는데 해결 방법을 잘 모르겠습니다.
    (aaa.com은 댓글에 도메인 주소를 노출하는게 좀 그래서 임의로 바꾼 것입니다.)
    혹시 어느 부분때문에 그럴까요.
    여러번 그 전 단계 작업들을 확인해봤는데 제가 틀리게 한 부분은 없는 것 같고
    도메인으로 현재 접속도 잘 되고 있는 상황입니다.

    혹시 시간 여유 있으시다면 도와주시면 너무 감사하겠습니다.

    IMPORTANT NOTES:
     - The following errors were reported by the server:
    
    Domain: aaa.com
       Type:   unauthorized
       Detail: Invalid response from
       http://aaa.com/.well-known/acme-challenge/iP7DKBAdkKToBR2bLNkdLqMqP2hYMKagc
    JOWWaOr0rY:
       "
    
    
    
       <meta name="viewport" content="width=devi"
    
    To fix these errors, please make sure that your domain name was
       entered correctly and the DNS A/AAAA record(s) for that domain
       contain(s) the right IP address.
    
  2. 앗… 계속 해도 안되서 죄송하게도 여쭤봤는데.
    1-2시간 지나서 다시 해보니 무안하게도 잘 됩니다!
    아마도 도메인 변경한 후로 좀 시간이 걸렸나 봅니다.

    글 정말 도움 많이 되었습니다!
    이 글들이 없었으면 혼자서 도전도 못했을 겁니다.

    • 안녕하세요 안테나곰님 잘 해결됐다니 다행이네요. 아마도 DNS 설정 문제였나 봅니다. DNS는 IP 변경후 TTL 설정값만큼의 시간이 좀 걸리는 편입니다.

  3. 지금까지 잘 따라왔던 유저중 한명입니다.
    조금 웃긴 상황이 나와서 문의드리려고 합니다.
    인증서를 받지를 못해서 헤메고 있는 중인데
    서브 도메인 (www.aaa.com)은 인증서가 받아지는데
    메인 도메인 (aaa.com)은 왠지 모르게 인증서가 위에 분이 올려준 오류가 뜨면서 되지를 않습니다.
    혹시 이 경우에는 해결 방법이 있나요?
    하루 정도 기다렸으니 DNS 문제는 아니라고 생각됩니다. 도메인으로 접속도 잘 되는 상황입니다.

  4. 원인은 찾았습니다. 이유는 모르겠는데 include 문이 제대로 안넘어간거 같네요… 이것 저것 더 확인해봐야 할 것 같습니다.
    감사합니다.

댓글은 익명이나 SNS, wordpress.com 로그인 지원). 마크다운 문법 사용가능(Shift+~ 키로 특정문구 혹은 위아래 ~~~으로감싸서 여러줄을 코드블락으로 작성)