Dynu OpenWRT ACME LET'S ENCRYPT

First as all of you just ought to know by now - before we begin - " The Into " - remember to - https://www.youtube.com/watch?v=gnsqvz9iIlA and the lyrics to sing along -
https://genius.com/Dj-kool-let-me-clear-my-throat-live-lyrics - while I take you back and forth - https://www.youtube.com/watch?v=krTLRQOOFAw - once again naturally - the lyrics to sing / hum along - https://genius.com/Audio-two-top-billin-lyrics - Now that the obligatory prerequisites have been satisfied
Let's begin the tutorial - Dynu is far superior to DuckDns - I find that Dynu works first time and every time -- most reliable Cost-Free DDNS Service out there IMHO.

OpenWRT DYNU ACME LET'S ENCRYPT - first we have to install DYNU DDNS service before we get down to issuing our certificates. In order to do this - let's get started.

1 - Go to https://www.dynu.com/en-US/ControlPanel/CreateAccount - and create an account - the page is self explanatory. You also have the option to sign up with your Google or Twitter account. Once you have verified your account - Log into your account. Go to > DDNS Services > Click " ADD " > Option 1: Use Our Domain Name
From the Drop Down Menu choose a " Top Level " Dynu Domain ( for this example I choose mywire.org ) - enter a hostname - I chose babybaby - click green " ADD "
button below - Done. My Dynu domain is now - babybaby.mywire.org Note : some of the domains marked " Members Only are not free - and you must pay for. Now - let's install and configure DDNS. The username is - apple75 and the password is - lebron23 for this fictional account. once you have established your Dynu domain - click on symbol next to " Search " to the right at the top of the page - the click on " API Credentials " - then go to " OAuth2 " - you will see " Client ID: " and " Secret: " - go along
that Boxed Column to the right - click on the Binoculars symbol to view these codes - copy and save them for later. Here are my fictional examples below :

Client ID: 4cd64505-a7db-4871-8f06-5e61f997d961
Secret: 636g5TbWd3dc43f6b3VV4a444U62af

2 - Set up your router for Dynu DDNS and Let's Encrypt -
A- Go to System > Hostname ( enter name of your choice - I am using " freedom " here ) then Network > DHCP and DNS > Local domain ( here enter your Dynu domain which you created earlier - babybaby.mywire.org ( for this example ). Your full domain ( for Let's Encrypt Certificate ) is now - freedom.babybaby.mywire.org . Now, let's set up Dynu DDNS and ACME Let's Encrypt.

3 - Install DDNS and ACME later on - now - first as always - opkg update - then follow below :

Dynu DDNS

A - opkg update ; opkg install socat ncat luci-app-acme luci-i18n-acme-en acme-dnsapi acme coreutils-stat ddns-scripts luci-app-ddns luci-i18n-ddns-en luci-app-uhttpd uhttpd tcpdump-mini bind-tools drill knot-host bind-host knot-dig haveged 

B - Dynu DDNS - Dynu DDNS SCRIPT SECTION:
I use a script to update Dynu DDNS service.
See here : https://www.bytebang.at/Blog/Find+public+IP+address+for+OpenWRT+via+Script# - I have modified the script so it works more reliably.
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 : ( url includes Dynu hostname
and account password found above ) ## make sure to use Dynu domain/ hostname only :

#!/bin/sh
# sample script for detecting the public IP
wget -q -O - "https://api.dynu.com/nic/update?hostname=babybaby.mywire.org&password=lebron23"  

## then make it executable :

# chmod 755 /usr/lib/ddns/getPublicIp.sh 

## test it by entering command :

# /usr/lib/ddns/getPublicIp.sh

C - Setup Dynu DDNS Config File -
Replace The IPV4 Configuration Section With The Contents Below:

## enter command

# nano /etc/config/ddns

config service 'dynu'
        option enabled '1'
        option domain 'babybaby.mywire.org'
        option username 'apple75'
        option use_https '1'
        option cacert '/etc/ssl/certs/ca-certificates.crt'
        option use_logfile '1'
        option check_interval '10'
        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://api.dynu.com/nic/update?hostname=babybaby.mywire.org&password=lebron23'
        option password 'lebron23'
        option interface 'WAN'
        option use_bind_network 'WAN'
        option force_dnstcp '1'
        option force_ipversion '1'
        option service_name 'dynu.com'
        option lookup_host 'babybaby.mywire.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 dynu 

You may then go to Services > Dynamic DNS > Services and make sure the DDNS Client is running and updated. If not - then do the following as outlined below :

( 1 ) # /usr/lib/ddns/./getPublicIp.sh ( 2) # /etc/init.d/ddns restart  
# then ( 3 ) go to System > Startup > Restart Your DNS Resolver 
( dnsmasq / unbound ) - then restart DDNS
Note : In order to issue / renew Let's Encrypt Certificates - 
disable your VPN ( if running ) - and make sure Port 80 
is free / open / unblocked.

4- Now - Dynu ACME / Let's Encrypt -
A - The packages are already installed. You now need to issue this command below in order to issue your Let's Encrypt Certificate for the full Domain Name
which we set up at the beginning - freedom.babybaby.mywire.org - Note - that this includes the hostname which we added on our router. Our Dynu " API Credentials "

Fake API Credentials from above -
Client ID: 4cd64505-a7db-4871-8f06-5e61f997d961
Secret: 636g5TbWd3dc43f6b3VV4a444U62af

See here for ACME on OpenWRT https://github.com/acmesh-official/acme.sh/wiki/How-to-run-on-OpenWRT
and here : https://github.com/acmesh-official/acme.sh/wiki/dnsapi scroll down to Section 24. Use Dynu API /
Issue this command below :

# Dynu_ClientId="4cd64505-a7db-4871-8f06-5e61f997d961" Dynu_Secret="636g5TbWd3dc43f6b3VV4a444U62af" /usr/lib/acme/acme.sh --insecure --issue -d freedom.babybaby.mywire.org --keylength 4096 --dns dns_dynu 

The issuance takes 20 seconds to complete after acme challenge ;
when finished You can locate the certificate and key files in
/root/.acme.sh/ directory, 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/freedom.babybaby.mywire.org/freedom.babybaby.mywire.org.cer
/root/.acme.sh/freedom.babybaby.mywire.org/freedom.babybaby.mywire.org.key

B - Notice that I set login port is to " 10445 "
Now edit /etc/config/uhttpd file thusly as demonstrated below:

config uhttpd 'main'
        list listen_http '0.0.0.0:80'
        list listen_http '[::]:80'
        list listen_https '0.0.0.0:10445' # changed port to 10445
        list listen_https '[::]:10445' # changed port to 10445
        option redirect_https '1'
        option home '/www'
        option max_requests '3'
        option max_connections '100'
        option cert '/root/.acme.sh/freedom.babybaby.mywire.org/freedom.babybaby.mywire.org.cer'
        option key '/root/.acme.sh/freedom.babybaby.mywire.org/freedom.babybaby.mywire.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/freedom.babybaby.mywire.org/freedom.babybaby.mywire.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://freedom.babybaby.mywire.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.
5 - 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 'freedom.babybaby.mywire.org' # full router domain for Let's Encrypt
        option use_staging '0'
        option dns 'acme.sh --insecure --issue --dns dns_dynu -d freedom.babybaby.mywire.org' # full router domain here too
        list credentials 'export Dynu_ClientId="4cd64505-a7db-4871-8f06-5e61f997d961"'
        list credentials 'export Dynu_Secret="636g5TbWd3dc43f6b3VV4a444U62af"'


### Use API Credentials which you used to issue Let's Encrypt Certificate

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 !

6 - BONUS :

In order to preserve your Let's Encrypt Certificates -
use WINSCP and go into default directory.
In this case open directory : /root/.acme.sh/freedom.babybaby.mywire.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, HNYMAN ( R7800 ) puts out new SnapShots every
3- 4 days and Divested-WRT ( WRT Series ) puts out new builds
every 4 - 5 days. 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 below :

# mkdir -p /root/.acme.sh/freedom.babybaby.mywire.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 Dynu DDNS - installed necessary ACME packages
and follow all the instructions above EXCEPT for
creating a new certificate as you have a valid certificate which you
have saved already. Do not forget this command either:

chmod 400 /root/.acme.sh/freedom.babybaby.mywire.org/freedom.babybaby.mywire.org.key

Once Again As Stated Above :

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://freedom.babybaby.mywire.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.

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

As I said, Let's Encrypt Certificates are valid for 90 days - you may renew
after 60 days. You can find your exact expiration date for your certificate
by click on the " green padlock " on your router's encrypted login page -
https://freedom.babybaby.mywire.org:10445 - In order to renew your
OpenWRT Dynu registered Let's Encrypt Certificate do the following

A - Setup your DDNS as detailed above ( Step 3 in this tutorial above )
B - WINSCP your current certificates as detailed above
C - Setup Let's Encrypt ( Steps 4 & 5 ) above
D - Make sure that your VPN is off / disabled - and DDNS address is updated and current
E - then issue the command below in order to renew your certificate :

# Dynu_ClientId="4cd64505-a7db-4871-8f06-5e61f997d961" Dynu_Secret="636g5TbWd3dc43f6b3VV4a444U62af" /usr/lib/acme/acme.sh --insecure --issue -d freedom.babybaby.mywire.org --keylength 4096 --dns dns_dynu --force --renew

You only use the " --force --renew " option on previously issued
Let's Encrypt Certificate - otherwise you will receive an error.

Peace Stay Safe and Healthy and God Bless All Always

2 Likes

But...you don't control the root domain.

Does Let's Encrypt allow a cert for a subdomain whose root you do not control?

1 Like

yes they do

2 Likes