Ubuntu의 Nginx 환경에서 Letsencrypt를 통해 SSL인증서를 발급받는 방법을 소개합니다.
Letsencrypt를 통해 SSL 적용
Letsencrypt에서 SSL인증서를 발급받았습니다. Ubuntu16.04 환경에서 certbot와 nginx를 이용하였습니다. Letsencrypt와 nginx에 대해서 잘 몰라서 많은 시간 헤멨네요...
Letsencrypt에서 인증서를 발급 받는 방법 중에 standalone과 webroot 방식이 있는데요. 80포트 서비스가 실행 중인 상태에서도 사용 가능한 방법이 webroot라고 해서 webroot를 시도해보았는데 실패해서 standalone으로 했습니다.
webroot으로 SSL 인증
아쉽게도 여러번 시도해봤지만 webroot로 SSL인증서를 받지 못했습니다. history를 기록차원에서 실패 로그를 남깁니다. 나중에 성공하면 다시 업데이트 할께요.
webroot는 80포트가 서비스 중인 상태에서도 인증이 가능한 방법이라고 합니다. 특정 위치에 key를 저장하고 Letsencrypt가 이 파일의 key를 읽어 도메인의 소유자를 인증하는 것 같습니다. Nginx를 이용하여 특정 위치에 key를 저장할 수 있도록 세팅하였습니다.
Nginx에서 SSL 설정
예를들어 자신의 도메인이 first.com
라고 한다면 미리 서버의 IP를 DNS에 등록해둡니다.
그리고 http://first.com/.well-known/acme-challenge/
와 같은 경로에 파일 접근이 가능한 상태가 되도록 nginx를 설정해야 합니다.
nginx를 설치했다면, 아래 명령어로 다음과 같은 경로에 폴더를 생성합니다.
$ mkdir /var/www/first
그리고 /etc/nginx/sites-available/first.conf
파일을 생성하고 아래처럼 설정합니다.
자신의 도메인의 root 경로를 /var/www/first
로 설정하겠다는 의미입니다.
server {
listen 80 default_server;
listen [::]:80 default_server ipv6only=on;
server_name first.com www.first.com;
root /var/www/first;
index index.html;
location / {
try_files $uri $uri/ =404;
}
}
사용하지 않는 default 설정 파일을 지우고, ../sites-enabled
에 first.conf에 대한 링크를 만듭니다.
그리고 nginx를 실행하고 서버가 정상적으로 실행되는지 상태를 확인합니다.
$ sudo rm /etc/nginx/sites-available/default
$ sudo rm /etc/nginx/sites-enabled/default
$ sudo ln -s /etc/nginx/sites-available/first.conf /etc/nginx/sites-enabled/first.conf
$ sudo nginx -t
$ sudo systemctl stop nginx
$ sudo systemctl start nginx
$ sudo systemctl status nginx
nginx설정은 끝났습니다. 테스트로 /var/www/first/.well-known/acme-challenge/test.txt
경로에 파일을 생성하고 아무 text를 입력합니다.
http://first.com/text/.well-known/acme-challenge/test.txt
에 접근해서 자신이 입력한 text가 보이는지 확인합니다.
Certbot으로 SSL 인증서 발급
certbot 이라는 프로그램을 이용하면 쉽게 SSL인증서 발급을 할 수 있다고 합니다.
아래 명령어로 certbot을 설치합니다.
$ wget https://dl.eff.org/certbot-auto
$ chmod a+x certbot-auto
certbot을 실행해서 의존성 파일들을 설치합니다.
$ sudo ./certbot-auto
그리고 아래 명령어를 입력하면 SSL 인증서를 얻을 수 있습니다.
$ sudo ./certbot-auto certonly --webroot -w /var/www/letsencrypt -d first.com
Congratulations~
라는 text로 인증서를 발급받았다고 나오면 성공한 것인데, 저는 실패했습니다.
원인을 찾아봐도 몰라서 그냥 standalone으로 발급받았습니다.
standalone 방식으로 인증서 발급
webroot 방식이 잘 안되서 standalone으로 인증서를 발급받았습니다. 80포트가 서비스 중인 상태에서 standalone 방식을 사용할 수 없습니다.
먼저 nginx를 중단합니다.
$ service nginx stop
다음과 같은 명령어를 입력하고, 아래처럼 성공 로그가 보인다면 인증서를 발급 받은 것입니다.
$ certbot-auto certonly --standalone -d first.com
# 성공 로그
IMPORTANT NOTES:
- Congratulations! Your certificate and chain have been saved at:
....
인증서는 /etc/letsencrypt/live/first.com/
처럼 도메인 이름의 폴더가 생성되고 그 안에 인증서 파일이 있습니다.
nginx에 SSL 적용
nginx에 인증서를 적용해보았습니다.
저는 elasticsearch 서버를 구축하고 있었고 /etc/nginx/nginx.conf
파일을 아래처럼 수정했습니다.
upstream elasticsearch {
server 127.0.0.1:9200;
keepalive 15;
}
server {
listen 8443;
location / {
proxy_pass http://elasticsearch;
proxy_http_version 1.1;
proxy_set_header Connection "Keep-Alive";
proxy_set_header Proxy-Connection "Keep-Alive";
}
}
server {
listen 443;
ssl on;
server_name first.com;
ssl_certificate /etc/letsencrypt/live/first.com/fullchain.pem;
ssl_certificate_key /etc/letsencrypt/live/first.com/privkey.pem;
location / {
proxy_pass http://elasticsearch;
proxy_http_version 1.1;
proxy_set_header Connection "Keep-Alive";
proxy_set_header Proxy-Connection "Keep-Alive";
}
}
인증서 자동갱신
Letsencrypt는 3달마다 갱신이 필요하다고 합니다. 아래 명령어를 입력하면 서버에서 인증받은 도메인에 대해서 갱신을 합니다.
$ certbot-auto renew
기간이 많이 남은 경우 갱신이 되지 않습니다.
Processing /etc/letsencrypt/renewal/first.com
- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
Cert not yet due for renewal
아래 옵션으로 강제로 갱신할 수 있습니다.
$ certbot-auto renew --dry-run
하지만 80포트가 열려있는 경우 standalone은 실패를 합니다. nginx를 종료하고 시도해야 합니다.
Problem binding to port 80: Could not bind to IPv4 or IPv6.. Skipping.
renew하기 전/후에 ngix 종료/실행하도록 hook을 설정하였습니다. standalone은 이렇게 하니 편하네요.
$ certbot-auto renew --pre-hook "service nginx stop" --post-hook "service nginx start" --dry-run
갱신일이 궁금하다며 다음 명령어로 확인이 가능합니다.
$ echo | openssl s_client -connect localhost:443 2>/dev/null | openssl x509 -noout -dates
참고
Related Posts
- Python - Yaml 파일 파싱하는 방법
- Python - pip와 requirements.txt로 패키지 관리
- 유튜브 쇼츠(Shorts) 자막 끄기/켜기
- SOLID 원칙, 객체지향 설계 5가지 원칙
- Ubuntu 20.04 - Nginx로 React를 배포하는 방법
- 애드센스 '구글 검색 기능' 블로그에 추가
- 트위터 이메일 안오게, 알림 끄기
- 인스타그램 동영상, 사진 저장 방법
- Git 설치 방법 (Ubuntu, Windows)
- Python pip 설치 (Ubuntu / Windows)
- 마우스 우클릭 복사 방지 해제 방법 (크롬)
- Python 에러 해결, 'conda' 용어가 cmdlet, 함수, 스크립트 ... 인식되지 않습니다.
- Python 에러 해결, AttributeError: module 'jwt' has no attribute 'encode'
- Atom - 코드 자동 정렬
- Sublime Text - 코드 자동 정렬, 단축키 설정
- VSCode에서 탭 간격 설정 (Tab to 4 spaces)
- Visual Studio Code에서 코드 자동 정렬
- 구글 검색 기록 삭제, 자동 저장 끄기 (PC, 모바일)
- 안드로이드 개발자 옵션 활성화, USB 디버깅 켜기
- 유튜브 채널 차단, 해제 방법 (PC, 모바일)
- 유튜브 미리보기 자동재생 끄기 (자동 소리 끄기/켜기)
- PC에서 유튜브 모바일 버전(m.youtube.com)으로 보기
- 모바일에서 유튜브 PC버전으로 보기
- 유튜브 시간 링크 만들기, 댓글에 시간 태그 입력하기
- 유튜브 스크립트 함께 보기, 자막 추출 방법
- 유튜브 알고리즘 초기화, 검색 기록과 시청 기록 삭제
- 유튜브 '싫어요' 숫자 다시 보이게 하기
- 구글 크롬, 방금 닫은 탭 다시 열기
- Maven으로 Java프로젝트 build하는 방법
- node.js, npm 버전 확인 방법 (터미널, cmd 명령어)
- GitLab - 'pre-receive hook declined' 에러 해결
- Javacript Heap Out Of Memory 문제 해결
- SSH key 생성하고 GitHub에 등록
- GMT, UTC의 차이점
- Linux(Ubuntu)에 Adobe Photoshop, Illustrator 설치하는 방법