Let's Encrypt SSL 인증서를 발급받기 위해서 라즈베리파이 호스트 머신에 직접 certbot을 설치하고 수작업으로 인증서를 받을 수도 있다. 물론 certbot도 자동화된 도구이며, apt 명령으로 간단히 설치가 가능하기는 하다.
그러나, letsencrypt docker를 이용하면 간단한 환경설정 만으로 인증서 발급 및 갱신까지 자동으로 이루어진다. 오늘은 letsencrypt SSL 인증서 발급을 위한 단계에 대해 설명하도록 하겠다.
1. 사전 작업
1-1. duckdns 가입 및 dnszi와 연결하기
인증서를 발급 받기 전 어떤 서브 도메인까지 인증서가 필요할지 미리 생각해 두어야 한다. 예를 들어 codesarang.com과 www.codesarang.com, blog.codesarang.com에 대한 인증서를 발급 받는 경우와 서브 도메인 전체(*.codesarang.com)를 통자로 발급 받는 경우와는 접근 방법이 다르기 때문이다.
여기서는 *.codesarang.com처럼 와일드카드(wildcard) 도메인에 대한 인증서 발급 받을 예정이다. letsencrypt docker에서 와일드카드(wildcard) 인증서 발급을 위해서는 duckdns 가입이 필수적이다. duckdns 회원 가입 방법은 매우 간단하기 때문에 따로 설명하지는 않도록 하겠다.
duckdns 가입을 하게되면 개인별로 아래와 같은 토큰값이 발급된다. 이 토큰은 가입한 도메인에 대한 원격 제어 권한을 갖으므로 외부에 노출되지 않도록 주의해야 한다.
이제 서브도메인에 자신이 원하는 도메인 값을 입력하고 "add domain" 버튼을 눌러 자신만의 도메인을 생성하도록 한다. 여기서 생성한 도메인은 codesarang.duckdns.org 이다.
이제, 자신의 도메인 관리 페이지에 접속, 내 도메인과 duckdns에서 발급받은 도메인을 연동해 주어야 한다. 나의 경우 dnszi에서 도메인을 관리 하므로, dnszi에 로그인 하였다.
만일, 이전에 letsencrypt 인증서를 발급받은 경력이 있다면 TXT 필드에 _acme-challenge.codesarang.com에 해당하는 값이 저장되어 있을 수도 있다. 이럴 경우, 해당 값을 미리 모두 삭제해 주어야 한다.
이제 CNAME 메뉴로 이동, "_acme-challenge.codesarang.com" 도메인을 아까 만든 duckdns 도메인으로 연결시켜 준다. 여기서는 "codesarang.duckdns.org"이다.
아래 그림에서는 "_acme-challenge.codesarang.duckdns.org"로 연결시켜 주었으나, "codesarang.duckdns.org"도 무방하다.
참고로, duckdns의 경우 내가 만든 도메인(codesarang.duckdns.org)에 대한 서브 도메인(_acme-challenge.codesarang.duckdns.org)이 모두 허용된다.
1-2. letsencrypt 이미지 가져오기
Porainer 왼편의 "Images"메뉴를 선택하고 아래처럼 "linuxserver/letsencrypt" 이미지를 가져오도록 한다.
1-3 SSL 인증서 저장 영역 확보
이제 SSL 인증서 저장용 공유 폴더를 생성한다.
1-4 기존 사용 포트 변경
letsencrypt docker 컨테이너가 80 및 443 포트 사용한다. 따라서, 기존 80 및 443 포트를 사용하는 어플리케이션이 있다면 해당 포트를 변경해 주어야 한다. 우선 OVM가 80포트를 사용하므로, 8080등 다른 포트로 변경해 주도록 한다.
또한, NextCloud가 사용하는 443포트도 임시로 막아 주도록 한다.
2. letsencrypt 컨테이너 설치 및 환경설정
컨테이너 리스트에서 "Add container" 버튼을 클릭, 아래처럼 컨테이너 이름, 이미지, 포워딩할 포트를 지정해 준다.
"Volumes" 탭으로 이동, 이까 만들어둔 공유폴더의 절대 경로를 컨테이너의 "/config"로 매핑 시킨다.
아래처럼 환경 변수를 미리 지정해 준다. wildcard 인증서 발급을 위해서는 아래처럼 duckdns 옵션(VALIDATION, DUCKDNSTOKEN)을 사용해 주어야 한다.
환경 변수 설정 정보는 아래와 같다.
-p 443 | Https port |
-p 80 | Http port (required for http validation and http -> https redirect) |
-e PUID=1000 | for UserID - see below for explanation |
-e PGID=1000 | for GroupID - see below for explanation |
-e TZ=Europe/London | Specify a timezone to use EG Europe/London. |
-e URL=yourdomain.url | Top url you have control over (customdomain.com if you own it, or customsubdomain.ddnsprovider.com if dynamic dns). |
-e SUBDOMAINS=www, | Subdomains you'd like the cert to cover (comma separated, no spaces) ie. www,ftp,cloud. For a wildcard cert, set this exactly to wildcard (wildcard cert is available via dns and duckdns validation only) |
-e VALIDATION=http | Letsencrypt validation method to use, options are http, dns or duckdns (dns method also requires DNSPLUGIN variable set) (duckdns method requires DUCKDNSTOKEN variable set, and the SUBDOMAINS variable must be either empty or set to wildcard). |
-e DNSPLUGIN=cloudflare | Required if VALIDATION is set to dns. Options are aliyun, cloudflare, cloudxns, cpanel, digitalocean, dnsimple, dnsmadeeasy, domeneshop, gandi, google, inwx, linode, luadns, nsone, ovh, rfc2136, route53 and transip. Also need to enter the credentials into the corresponding ini (or json for some plugins) file under /config/dns-conf. |
-e PROPAGATION= | Optionally override (in seconds) the default propagation time for the dns plugins. |
-e DUCKDNSTOKEN= | Required if VALIDATION is set to duckdns. Retrieve your token from https://www.duckdns.org |
-e EMAIL= | Optional e-mail address used for cert expiration notifications. |
-e DHLEVEL=2048 | Dhparams bit value (default=2048, can be set to 1024 or 4096). |
-e ONLY_SUBDOMAINS=false | If you wish to get certs only for certain subdomains, but not the main domain (main domain may be hosted on another machine and cannot be validated), set this to true |
-e EXTRA_DOMAINS= | Additional fully qualified domain names (comma separated, no spaces) ie. extradomain.com,subdomain.anotherdomain.org |
-e STAGING=false | Set to true to retrieve certs in staging mode. Rate limits will be much higher, but the resulting cert will not pass the browser's security test. Only to be used for testing purposes. |
-v /config | All the config files including the webroot reside here. |
마지막으로 "Restart policy"를 "Always"로 설정하고 "Deploy the container"를 수행한다.
3. 오류 수정
이제 컨테이너 생성이 완료하고 docker에서 알아서 인증서를 받아 올 것으로 기대했으나, 그 기대는 여지없이 무너졌다. 컨테이너 실행 후 https로 접속을 시도해 보면 아래처럼 접속되지 않는다는 메시지가 출력된다.
각각의 컨테이너 실행 로그는 로그 링크를 눌러 확인할 수 있다.
letsencrypt 로그를 살펴보면 duckdnstoken 수행시 도메인 유효성 확인 과정에서 에러가 발생하였고, 해당 스크립트는 "/app/duckdns-txt"에 위치한다.
"/app/duckdns-txt" 스크립트는 duckdns의 내 도메인에 TXT 필드를 추가시켜 주는 역할을 수행한다. 인증서를 받고자 하는 내 도메인(codesarang.com)과 TXT 필드를 추가할 duckdns 도메인(codesarang.duckdns.org)이 다르다 보니 생기는 문제이다. 아래처럼, 스크립드 중 "${CERTBOT_DOMAIN}"을 "codesarang.duckdns.org"으로 강제 설정해 주면 이 문제가 해결된다.
이제 letsencrypt 컨테이너를 재시작 하도록 한다.
약간의 시간이 흐른 후 공유 폴더에 아래처럼 인증서가 발급되어 저장된 모습을 볼 수 있다.
또한, 웹 브라우져 접속시에도 정상적인 인증서로 접속이 가능하다. 참고로 이 인증서의 유효기간은 90일 이며, 무제한 갱신이 가능하다.
4. 인증서 갱신 주기 변경
letsencrypt 콘솔로 접속, "crontabs -e" 명령을 수행하여 crontabs 설정을 살펴보면 매일 02:08에 인증서를 갱신하도록 되어있다. letsencrypt의 인증서 발급 유효기간이 3개월(90일) 이므로 굳이 매일 인증서를 갱신할 필요가 없다.
따라서, 아래 그림처럼 매월 1일 02:08에 인증서를 갱신하도록 주기를 변경해 주도록 한다.
# crontabs -e
'라즈베리파이' 카테고리의 다른 글
docker에 SSL 인증서 적용하기 - nginx Reverse Proxy (1) | 2020.06.16 |
---|---|
NextCloud에서 Internal Server Error 발생시 해결 방법 (0) | 2020.06.09 |
NextCloud에서 untrusted domain 오류 발생시 해결 방법 (0) | 2020.06.02 |
OMV5(OpenMediaVault 5)에 토렌트 클라이언트(transmission) 설치하기 (0) | 2020.06.02 |
OMV5(OpenMediaVault 5)에 NextCloud 설치하기 - 종합 (0) | 2020.06.01 |