ddns를 활용해 OpenWrt에서 웹서버 구동시 무료 SSL 인증서로 인기있는 Let's Encrypt ssl 인증서 발급방법에 대해 설명합니다.
사전준비
- ddns 설정을 하지 않았다면 ddns설정을 참고하세요. (아래 예시는 duckdns.org를 사용합니다.)
패키지 설치
opkg update
opkg install luci-ssl-openssl acme luci-app-acme acme-dnsapi
인증서 발급
duckdns.org에 로그인해서 호스트명(예 : myhost.duckdns.org) 및 토큰(예 : f7r7sx98-9bd8-46b3-8709-4c9dbe905xyu)을 확인하고 아래와 같은 형태로 ssh 명령줄에 입력해 인증서를 발급 받습니다.
DuckDNS_Token="f7r7sx98-9bd8-46b3-8709-4c9dbe905xyu" /usr/lib/acme/acme.sh --issue -d myhost.duckdns.org -k ec-256 --dns dns_duckdns
[email protected]:~# DuckDNS_Token="f7r7sx98-9bd8-46b3-8709-4c9dbe905xyu" /usr/lib/acme/acme.sh --issue -d myhost.duckdns.org -k ec-256 --dns dns_duckdns
[Wed Dec 2 19:44:56 KST 2020] Create account key ok.
[Wed Dec 2 19:44:56 KST 2020] Registering account
[Wed Dec 2 19:44:58 KST 2020] Registered
[Wed Dec 2 19:44:59 KST 2020] ACCOUNT_THUMBPRINT='BJieVVT13LX684jCvgTwdI1Ewax8tzTdsfd5TusWrDYY'
[Wed Dec 2 19:44:59 KST 2020] Creating domain key
[Wed Dec 2 19:44:59 KST 2020] The domain key is here: /root/.acme.sh/myhost.duckdns.org/myhost.duckdns.org.key
[Wed Dec 2 19:44:59 KST 2020] Single domain='myhost.duckdns.org'
[Wed Dec 2 19:44:59 KST 2020] Getting domain auth token for each domain
[Wed Dec 2 19:45:02 KST 2020] Getting webroot for domain='myhost.duckdns.org'
[Wed Dec 2 19:45:02 KST 2020] Adding txt value: #2SSXSAGSDX_coR-NATmQV2LGfflSqPE3nkTMZS-oZD05M for domain: _acme-challenge.myhost.duckdns.org
[Wed Dec 2 19:45:02 KST 2020] Trying to add TXT record
[Wed Dec 2 19:45:12 KST 2020] TXT record has been successfully added to your DuckDNS domain.
[Wed Dec 2 19:45:12 KST 2020] Note that all subdomains under this domain uses the same TXT record.
[Wed Dec 2 19:45:12 KST 2020] The txt record is added: Success.
[Wed Dec 2 19:45:12 KST 2020] Let's check each dns records now. Sleep 20 seconds first.
[Wed Dec 2 19:45:33 KST 2020] Checking myhost.duckdns.org for _acme-challenge.myhost.duckdns.org
[Wed Dec 2 19:45:34 KST 2020] Domain myhost.duckdns.org '_acme-challenge.myhost.duckdns.org' success.
[Wed Dec 2 19:45:34 KST 2020] All success, let's return
[Wed Dec 2 19:45:34 KST 2020] Verifying: myhost.duckdns.org
[Wed Dec 2 19:45:39 KST 2020] Pending
[Wed Dec 2 19:45:42 KST 2020] Pending
[Wed Dec 2 19:45:45 KST 2020] Pending
[Wed Dec 2 19:45:48 KST 2020] Success
[Wed Dec 2 19:45:48 KST 2020] Removing DNS records.
[Wed Dec 2 19:45:48 KST 2020] Removing txt: 2SSXSAGSDX_coR-NATmQV2LGfflSqPE3nkTMZS-oZD05M for domain: _acme-challenge.myhost.duckdns.org
[Wed Dec 2 19:45:48 KST 2020] Trying to remove TXT record
[Wed Dec 2 19:45:49 KST 2020] TXT record has been successfully removed from your DuckDNS domain.
[Wed Dec 2 19:45:49 KST 2020] Removed: Success
[Wed Dec 2 19:45:49 KST 2020] Verify finished, start to sign.
[Wed Dec 2 19:45:49 KST 2020] Lets finalize the order, Le_OrderFinalize: https://acme-v02.api.letsencrypt.org/acme/finalize/1094347988/192099868767
[Wed Dec 2 19:45:50 KST 2020] Download cert, Le_LinkCert: https://acme-v02.api.letsencrypt.org/acme/cert/0989787888888c1cbc3485111114344fc61e57e23
[Wed Dec 2 19:45:52 KST 2020] Cert success.
-----BEGIN CERTIFICATE-----
MIIFKTCCBBGgAwIBAgISA5UyllwcvDSFEDFDRPxh5X4jMA0GCSqGSIb3DQEBCwUA
......
......
......
+bQJP7b2+ztHzCoy8bVELzFK7OBVYNc15Y28BlM=
-----END CERTIFICATE-----
[Wed Dec 2 19:45:52 KST 2020] Your cert is in /root/.acme.sh/myhost.duckdns.org/myhost.duckdns.org.cer
[Wed Dec 2 19:45:52 KST 2020] Your cert key is in /root/.acme.sh/myhost.duckdns.org/myhost.duckdns.org.key
[Wed Dec 2 19:45:52 KST 2020] The intermediate CA cert is in /root/.acme.sh/myhost.duckdns.org/ca.cer
[Wed Dec 2 19:45:52 KST 2020] And the full chain certs is there: /root/.acme.sh/myhost.duckdns.org/fullchain.cer
[email protected]:~#
uhttpd 설정변경
/etc/config/uhttpd 화일의 아래와 같이 변경합니다.
- list listen_https 0.0.0.0:80
- list listen_https 0.0.0.0:443
- option redirect_https 1
- option rfc1918_filter 0
- option cert /root/.acme.sh/muhost.duckdns.org/myhost.duckdns.org.cer
- option key /root/.acme.sh/myhost.duckdns.org/myhost.duckdns.org.key
# Server configuration config uhttpd main ...... # HTTP listen addresses, multiple allowed # list listen_http 192.168.1.1:80 list listen_http 0.0.0.0:80 # list listen_http [::]:80 # HTTPS listen addresses, multiple allowed # list listen_https 192.168.1.1:443 list listen_https 0.0.0.0:443 # list listen_https [::]:443 # Redirect HTTP requests to HTTPS if possible option redirect_https 1 ...... # Reject requests from RFC1918 IP addresses # directed to the servers public IP(s). # This is a DNS rebinding countermeasure. option rfc1918_filter 0 ...... # Certificate and private key for HTTPS. # If no listen_https addresses are given, # the key options are ignored. option cert /root/.acme.sh/myhost.duckdns.org/myhost.duckdns.org.cer option key /root/.acme.sh/myhost.duckdns.org/myhost.duckdns.org.key ......
방화벽 설정
/etc/config/firewall 에서 tcp 80, 443 포트를 개방합니다.
config rule option name 'Allow-http/https' option src 'wan' option proto 'tcp' list dest_port '80' list dest_port '443' option target 'ACCEPT' option enabled '1'
웹서버 및 방화벽 재시작
/etc/init.d/uhttpd restart
/etc/init.d/firewall restart
웹서버 및 방화벽을 재시작 후 웹브러우저로 https://myhost.duckdns.org 형태로 luci 에 접속해서 https 보안연결이 이상이 없음을 확인합니다. (웹서버 구동 목적이 아니라면 테스트 이후 개방한 tcp 80, 443포트 닫습니다.)
인증서 자동갱신을 위한 acme 구성
/etc/config/acme를 다음과 같이 편집하고 acme를 재시작합니다.
config acme option state_dir '/root/.acme.sh' option account_email '[email protected]' option debug '1' config cert 'example' option use_staging '0' option keylength 'ec-256' option update_uhttpd '1' list domains 'myhost.duckdns.org' option dns 'acme.sh --insecure --issue --dns dns_duckdns -d myhost.duckdns.org' option credentials 'export DuckDNS_Token="f7r7sx98-9bd8-46b3-8709-4c9dbe905xyu"' option enabled '1'
/etc/init.d/acme restart
인증서 설치 위치를 바꿀 방법은 없나요?
acme.sh 설치시 기본 위치는 $HOME/.acme.sh 입니다.
변경을 원할 경우 --cert-home /path/to/install 을 추가하면 됩니다.
ex)
DuckDNS_Token="f7r7sx98-9bd8-46b3-8709-4c9dbe905xyu"
/usr/lib/acme/acme.sh --issue -d myhost.duckdns.org --dns dns_duckdns --cert-home /etc/acme