DuckDNS LET'S ENCRYPT CERTIFICATES MADE SIMPLE

Dear treefiddy,
Hello - and I hope that you are well. This is how to get and setup Let's Encrypt Certificate using DuckDNS on OpenWrt. If you follow these instructions you should have no problems at all. I picked DuckDns because - it allows you five Domains ( read sub-domains ) and supports Let's Encrypt on OpenWrt. First go to https://www.duckdns.org/ - Log in or create account. I use reddit to sign in - DuckDNS also offers Google, Twitter, GitHub, or Persona logins to create an account. You are allowed five sub domains - create one - name it would you like - something like secureone. Your full sub domain is now- secureone.duckdns.org - Click on " install " on the top banner - go to " first step - choose a domain " and from the drop down menu - select the sub-domain you just created - secureone.duckdns.org - then under " Routers " - select " OpenWrt " - you will then get these instructions: find them below the DuckDNS DDNS SCRIPT SECTION.

Before You Begin You Should Make HOSTNAME under System something like cryptorouter ( or whatever you like ) and under Network > DHCP and DNS > Local domain - enter something like - home.secureone.duckdns.org When you are done this is the FQDN that your Let's Encrypt Certificate will named - in this example it is as follows : cryptorouter.home.secureone.duckdns.org
First Install Necessary DDNS Packages:

opkg update && opkg install ddns-scripts luci-app-ddns 
## Davidc502 SnapShots Come With This Pre-Installed

DuckDNS DDNS SCRIPT SECTION:
Second, I use a script to update DuckDNS DDNS service. See here : https://www.bytebang.at/Blog/Find+public+IP+address+for+OpenWRT+via+Script#
To implement this script, please follow these instructions below:

touch /usr/lib/ddns/getPublicIp.sh
nano /usr/lib/ddns/getPublicIp.sh

enter this script below in the new file :

#!/bin/sh
# sample script for detecting the public IP
wget -q -O - "https://www.duckdns.org/update?domains=secureone&token=f8be3d28-104e-45d2-a5a9-e95599b84ae2&ip"

then make it executable =  
chmod +x /usr/lib/ddns/getPublicIp.sh
check script by issuing command below
#  /usr/lib/ddns/./getPublicIp.sh
you should get return messgae " OK " in your shell

edit the config at /etc/config/ddns

nano /etc/config/ddns ## Replace The IPV4 Configuration With The Contents Below:

config service 'duckdns'
option enabled '1'
option username 'secureone'
option domain 'secureone.duckdns.org'
option password 'f8be3d28-104e-45d2-a5a9-e95599b84ae2' ## Use Your Own DuckDNS
#PassWord - This one is a fake
option interface 'wan'
option check_interval '5'
option check_unit 'minutes'
option force_interval '24'
option force_unit 'hours'
option ip_source 'script'
option retry_interval '60'
option retry_unit 'seconds'
option ip_script '/usr/lib/ddns/./getPublicIp.sh'
option update_url 'https://www.duckdns.org/update?domains=secureone&token=f8be3d28-104e-45d2-a5a9-e95599b84ae2&ip'
option use_https '1'
option cacert '/etc/ssl/certs/ca-certificates.crt'
option lookup_host 'secureone.duckdns.org'
option service_name 'duckdns.org'


Now Start DDNS : run commands ( a -e ) in order as listed below

( a ) # sh
( b ) # . /usr/lib/ddns/dynamic_dns_functions.sh   # note the leading period
( c ) # start_daemon_for_all_ddns_sections "wan"
( d ) # exit     ## Very Important To Exit 
we can now test the script by running the command
( e ) # /usr/lib/ddns/dynamic_dns_updater.sh duckdns

Then Check DDNS under Services Is Up And Running.
Now that you have DuckDNS Service running on your OpenWrt Router - let us install Let's Encrypt Certificate.
First you must issue these commands:

uci delete uhttpd.main.listen_http
uci set uhttpd.main.redirect_https=1
uci set uhttpd.main.rfc1918_filter='0'  ## This allows you to login with public sub-domain
uci commit
/etc/init.d/uhttpd restart

Now install necessary Let's Encrypt packages as follows :

opkg update ; opkg install socat ncat luci-app-acme acme-dnsapi acme coreutils-stat  ##   acme-dnsapi is themost important one

Then issue certificate with this command: ## Token is your DuckDNS Password & Please Note FQDN Placement

DuckDNS_Token="f8be3d28-104e-45d2-a5a9-e95599b84ae2" /usr/lib/acme/acme.sh --issue -d cryptorouter.home.secureone.duckdns.org --dns dns_duckdns

The issuance takes 120 seconds to complete after acme challenge ;
when finished You can locate the certificate and key files in
./.acme.sh/your.domain/, and then in the uHTTPd settings
point the certificate and key path to them respectively
This means that the two main files you need are found here :

/root/.acme.sh/cryptorouter.home.secureone.duckdns.org/cryptorouter.home.secureone.duckdns.org.cer
/root/.acme.sh/cryptorouter.home.secureone.duckdns.org/cryptorouter.home.secureone.duckdns.org.key

**Now edit /etc/config/uhttpd file thusly as demonstrated below:

Notice that I set https ONLY earlier and now the login port is set to " 10445 "**

nano /etc/config/uhttpd

config uhttpd 'main'
        list listen_https '0.0.0.0:10445'
        list listen_https '[::]:10445'
        option redirect_https '1'
        option home '/www'
        option max_requests '3'
        option max_connections '100'
        option cert '/root/.acme.sh/cryptorouter.home.secureone.duckdns.org/cryptorouter.home.secureone.duckdns.org.cer'
        option key '/root/.acme.sh/cryptorouter.home.secureone.duckdns.org/cryptorouter.home.secureone.duckdns.org.key'
        option cgi_prefix '/cgi-bin'
        list lua_prefix '/cgi-bin/luci=/usr/lib/lua/luci/sgi/uhttpd.lua'
        option script_timeout '60'
        option network_timeout '30'
        option http_keepalive '20'
        option tcp_keepalive '1'
        option ubus_prefix '/ubus'
        option rfc1918_filter '0'

config cert 'defaults'
        option days '730'
        option bits '4096'
        option country 'US'
        option state 'Texas'
        option location 'Austin'
        option commonname 'OpenWrt'

then issue this command :

chmod 400 /root/.acme.sh/cryptorouter.home.secureone.duckdns.org/cryptorouter.home.secureone.duckdns.org.key

At this point DO NOT !! - I REPEAT DO NOT !! -
DO NOT RESTART " uhttpd " for any reason whatsoever.
Instead clear your browser - close - clean cookies and all
that good stuff. Actually after clearing your web browser
it is best to reboot your router in order to make sure to
that you can login to your router with your new valid certificate.
After reboot, open your browser and login with - https://cryptorouter.home.secureone.duckdns.org:10445 -
as per this example. You should not be prompted by
" insecure warning " any longer - and the green padlock
will appear in the address bar. Click on it and see the certificate details if you wish.

NEXT CONFIGURE ACME FOR AUTOMATIC RENEWAL edit /etc/config/acme as below:

nano /etc/config/acme

config acme
        option state_dir '/root/.acme.sh/'
        option account_email 'cryptorouter@gmail.com'  ## Fake E-mail Too
        option debug '1'

config cert 'example'
        option keylength '4096'
        option update_uhttpd '1'
        option enabled '1'
        option webroot '/www'
        list domains 'cryptorouter.home.secureone.duckdns.org'
        option use_staging '0'
        option dns 'acme.sh --insecure --issue --dns dns_duckdns -d cryptorouter.home.secureone.duckdns.org'
        list credentials 'export DuckDNS_Token="f8be3d28-104e-45d2-a5a9-e95599b84ae2"'

Then issue this command :

/etc/init.d/acme enable  - at this point it is best to reboot your router - I have found that if you restart ACME at this point via command line you may unintentionally reissue your Let's Encrypt Certificate - so as I said, REBOOT YOUR ROUTER !

BONUS :
In order to preserve your Let's Encrypt Certificates -
use WINSCP and go into default directory. In this case open : /root/.acme.sh/cryptorouter.home.secureone.duckdns.org/
on the right side of the window. You will see all the certificates
and associated files. Save them to a folder on your desktop
USB or what have you in case you need to upgrade or install new
OpenWrt - for instance, Dave puts out new SnapShots every
two weeks approximately. As you know, Let's Encrypt Certificates
are good for 90 days and you do not want to abuse this
free service. You can reuse them via WINSCP - make sure to
create and install them to proper directory on
new install as follows- issue command:

mkdir -p /root/.acme.sh/cryptorouter.home.secureone.duckdns.org/

Then WINSCP the saved Let's Encrypt Files from
your previous storage desktop directory or USB into
this newly created router directory. That is after you
setup DuckDNS - installed necessary ACME packages
and follow all the instructions above EXCEPT for
creating a new certificate. Do not forget this command either:

chmod 400 /root/.acme.sh/cryptorouter.home.secureone.duckdns.org/cryptorouter.home.secureone.duckdns.org.key

Remember all of this was done using " fictional " hostname,
local domain - DuckDNS token and so on for illustration
purposes only ; however, it does illustrate how to get
you going. I find DuckDNS very easy to implement and manage.
I also use DuckDNS on pfSense and OPNsense.

12 Likes

Very useful for a newbie like me, I had the DDNS service working without problems but with the certificate, everything looks better, hehehe, thank you @directnupe.

Only one question (maybe a newbie's question), if I set the "country, state and location" fields at different way (in my case ES, Madrid, Madrid), these changes, can be problematic?

And one last thing, is there any way to make a 4096 certificate?, I ask it because the server certificate it's only 2048.

Thank you so much again for your tutorial.