Differences

This shows you the differences between two versions of the page.

Link to this comparison view

Both sides previous revision Previous revision
Next revision
Previous revision
userguide:let_s_encrypt_acme-dns [2018/08/11 07:41]
Dan Brown [Issuing the certificate]
userguide:let_s_encrypt_acme-dns [2020/03/19 08:17] (current)
Marc [Conclusion]
Line 9: Line 9:
 The effect of this is that if you can create NS and CNAME records on your DNS provider, you can then use acme-dns to automate the DNS updates needed to get and renew your certificates (whether wildcard or not). The effect of this is that if you can create NS and CNAME records on your DNS provider, you can then use acme-dns to automate the DNS updates needed to get and renew your certificates (whether wildcard or not).
 ==== Background and Theory ==== ==== Background and Theory ====
-acme-dns will act as the authoritative DNS server for a subdomain of your domain. ​ If your domain is ''​example.com'',​ that subdomain will be ''​acme.example.com''​. ​ The acme-dns software will generate random hostnames within this subdomain (one random hostname for each FQDN you want to obtain a cer for), of the form ''​32f5274d-51e3-466d-bf38-eb9980e7bcf3.acme.example.com''​. ​ You'll add a CNAME record for ''​%%_acme-challenge.example.com%%'',​ pointing to the random hostname. ​ When Let's Encrypt tries to validate domain control over example.com,​ it'll look for DNS records for %%_acme-challenge.example.com%%,​ see the CNAME to 32f5274d-51e3-466d-bf38-eb9980e7bcf3.acme.example.com,​ and then query for text records for %%_acme-challenge.32f5274d-51e3-466d-bf38-eb9980e7bcf3.acme.example.com%%. ​ At that point, acme-dns will serve the challenge that your client told it to serve, validation will succeed, and Let's Encrypt will issue the cert.+acme-dns will act as the authoritative DNS server for a subdomain of your domain. ​ If your domain is ''​example.com'',​ that subdomain will be ''​acme.example.com''​. ​ The acme-dns software will generate random hostnames within this subdomain (one random hostname for each FQDN you want to obtain a cert for), of the form ''​32f5274d-51e3-466d-bf38-eb9980e7bcf3.acme.example.com''​. ​ You'll add a CNAME record for ''​%%_acme-challenge.example.com%%'',​ pointing to the random hostname. ​ When Let's Encrypt tries to validate domain control over example.com,​ it'll look for DNS records for %%_acme-challenge.example.com%%,​ see the CNAME to 32f5274d-51e3-466d-bf38-eb9980e7bcf3.acme.example.com,​ and then query for text records for %%_acme-challenge.32f5274d-51e3-466d-bf38-eb9980e7bcf3.acme.example.com%%. ​ At that point, acme-dns will serve the challenge that your client told it to serve, validation will succeed, and Let's Encrypt will issue the cert.
  
 **Note:** Once you've set up acme-dns, you can use it for any domain you control. ​ In other words, you can use a single instance to validate control over any number of domains or subdomains, just by setting individual CNAME records for each desired (sub)domain. **Note:** Once you've set up acme-dns, you can use it for any domain you control. ​ In other words, you can use a single instance to validate control over any number of domains or subdomains, just by setting individual CNAME records for each desired (sub)domain.
Line 25: Line 25:
 </​code>​ </​code>​
 You're done with DNS records for the time being. You're done with DNS records for the time being.
 +
 +==== Important Upgrade Note ====
 +If you've installed a previous version (before version 0.8) of acme-dns, and activated HTTPS for the API, you **must** remove the DNS CNAME record you created for %%_acme-challenge.acme.example.com%%. ​ Acme-dns now handles its own certificate using DNS validation, but this record will conflict with that process.
  
 ==== Installing acme-dns ==== ==== Installing acme-dns ====
Line 44: Line 47:
  
 === Testing === === Testing ===
-To confirm that your acme-dns instance is up and running, run ''​%%curl -s -X POST http://localhost:​8675/​register | python -m json.tool%%''​. You should get something like this as your output:+== TLS Certificate == 
 +By default, this module is configured to obtain a TLS certificate from the Let's Encrypt staging server, in order to avoid exceeding the Let's Encrypt rate limits. ​ To ensure that a certificate has been issued, run ''​%%openssl s_client -connect localhost:​8675%%''​. ​ At the beginning of the output, you should see this: 
 +<​code>​ 
 +[root@neth staging]# openssl s_client -connect acme.example.com:​8675 
 +CONNECTED(00000003) 
 +depth=1 CN = Fake LE Intermediate X1 
 +verify error:​num=20:​unable to get local issuer certificate 
 +--- 
 +Certificate chain 
 + 0 s:/​CN=acme.example.com 
 +   ​i:/​CN=Fake LE Intermediate X1 
 + 1 s:/CN=Fake LE Intermediate X1 
 +   ​i:/​CN=Fake LE Root X1 
 +--- 
 +</​code>​ 
 +The inclusion of "Fake LE Root X1" and "Fake LE Intermediate X1" in the certificate chain shows that acme-dns is using a certificate from the staging environment,​ which further shows that all the steps in the issuance process are working. ​ To change to using a "​production"​ certificate,​ run ''​config setprop acme-dns-api TLSType letsencrypt''​ followed by ''​signal-event nethserver-acme-dns-update''​. ​ Then re-run the ''​openssl''​ command from above. ​ The output should now look like this: 
 +<​code>​ 
 +[root@neth ~]# openssl s_client -connect localhost:​8675 
 +CONNECTED(00000003) 
 +depth=2 O = Digital Signature Trust Co., CN = DST Root CA X3 
 +verify return:1 
 +depth=1 C = US, O = Let's Encrypt, CN = Let's Encrypt Authority X3 
 +verify return:1 
 +depth=0 CN = acme.example.com 
 +verify return:1 
 +--- 
 +Certificate chain 
 + 0 s:/​CN=acme.example.com 
 +   ​i:/​C=US/​O=Let'​s Encrypt/​CN=Let'​s Encrypt Authority X3 
 + 1 s:/​C=US/​O=Let'​s Encrypt/​CN=Let'​s Encrypt Authority X3 
 +   ​i:/​O=Digital Signature Trust Co./CN=DST Root CA X3 
 +--- 
 +</​code>​ 
 +The presence of "​Let'​s Encrypt Authority X3" shows that you now have a certificate from the production server. 
 + 
 +== Testing the API == 
 + 
 +To confirm that your acme-dns instance is up and running, run ''​%%curl -s -X POST https://acme.example.com:​8675/​register | python -m json.tool%%''​. You should get something like this as your output:
 <​code>​ <​code>​
 { {
Line 60: Line 100:
 Certbot doesn’t know, on its own, how to set DNS entries on acme-dns. Fortunately,​ the author of acme-dns has provided a [[https://​github.com/​joohoi/​acme-dns-certbot-joohoi|script]] to handle this. Download the script by doing ''​%%curl -o /​etc/​letsencrypt/​acme-dns-auth.py https://​raw.githubusercontent.com/​joohoi/​acme-dns-certbot-joohoi/​master/​acme-dns-auth.py%%''​ followed by ''​chmod 0700 /​etc/​letsencrypt/​acme-dns-auth.py''​. Certbot doesn’t know, on its own, how to set DNS entries on acme-dns. Fortunately,​ the author of acme-dns has provided a [[https://​github.com/​joohoi/​acme-dns-certbot-joohoi|script]] to handle this. Download the script by doing ''​%%curl -o /​etc/​letsencrypt/​acme-dns-auth.py https://​raw.githubusercontent.com/​joohoi/​acme-dns-certbot-joohoi/​master/​acme-dns-auth.py%%''​ followed by ''​chmod 0700 /​etc/​letsencrypt/​acme-dns-auth.py''​.
  
-You’ll need to edit the script. Near the top, change ACMEDNS_URL to ''​%%http://localhost:​8675%%''​. No other changes need to be made.+You’ll need to edit the script. Near the top, change ACMEDNS_URL to ''​%%https://acme.example.com:​8675%%''​. No other changes need to be made.
  
 ==== Issuing the certificate ==== ==== Issuing the certificate ====
Line 84: Line 124:
 </​code>​ </​code>​
 You’ll need to once again log into your DNS host and add the record specified. ​ You'll only need to do this once for each hostname. ​ Wait a few minutes, then press Enter. You’ll need to once again log into your DNS host and add the record specified. ​ You'll only need to do this once for each hostname. ​ Wait a few minutes, then press Enter.
- 
-===== Enabling HTTPS for the acme-dns API ===== 
-As noted above, once you have acme-dns running, you can use it to validate any domain you control, as long as you can set the appropriate CNAME records. ​ But if you're going to be accessing its API remotely, you should really secure its API using HTTPS. 
- 
-==== Get a certificate ==== 
-We just created a wildcard certificate above, so we could use that, but it's better practice to use a unique certificate for this service. ​ To issue that certificate,​ run the following: 
-<​code>​ 
-certbot certonly --manual --manual-auth-hook /​etc/​letsencrypt/​acme-dns-auth.py \ 
-   ​--preferred-challenges dns --debug-challenges --post-hook "​systemctl restart acme-dns"​ \ 
-   -d acme.example.com 
-</​code>​ 
-Also as above, you’ll be told to create a CNAME record with your DNS host. Do that, wait a couple of minutes, then press Enter. Your certificate will be generated. 
- 
-==== Configure acme-dns for HTTPS ==== 
- 
-You’ll need to make just a few configuration changes: 
-<​code>​ 
-config setprop acme-dns-api FullchainPath /​etc/​letsencrypt/​live/​acme.example.com/​fullchain.pem 
-config setprop acme-dns-api KeyPath /​etc/​letsencrypt/​live/​acme.example.com/​privkey.pem 
-config setprop acme-dns-api access red,green 
-signal-event nethserver-acme-dns-update 
-</​code>​ 
- 
-==== Configure the hook script ==== 
- 
-You’ll also need to update the hook script. Edit ''/​etc/​letsencrypt/​acme-dns-auth.py''​ and change ''​ACMEDNS_URL''​ to ''​%%https://​acme.example.com:​8675%%'',​ then save and exit. 
  
 ===== Renewal ===== ===== Renewal =====
Line 125: Line 139:
 Note that, in this configuration,​ anyone on the Internet can access the API of your acme-dns instance. If the other hosts that might be using it are on your LAN, you might want to change the access property above to just green rather than red,green. Note that, in this configuration,​ anyone on the Internet can access the API of your acme-dns instance. If the other hosts that might be using it are on your LAN, you might want to change the access property above to just green rather than red,green.
  
-{{tag>​userguide ht_v7 ht_application}}+{{tag>​userguide ht_v7 ht_application ​module}}