Last Updated on August 15, 2022 by Thiago Crepaldi
If you are like me and don’t want unencrypted data flowing on your network or maybe even on Internet, than this post is for you! I will adopt CloudFlare DNS as it has API to integrate with Let’s Encrypt SSL services through the ACME plugin. Both CloudFlare and Let’s Encrypt are free, so that is a good start!
CloudFlare setup
Here I assume you have chosen CloudFlare as your DNS provider, and configured your domain’s Registrar to point to CloudFlare name servers. In future posts I can cover this topic in more depth, but their page has an intuitive wizard that goes through the basics and get you going in a few minutes.
For issuing Let’s Encrypt certificates, you have to login to your CloudFlare account and collect some information. At the overview page, you can collect Zone ID and Account ID. Take note of the email you used to create your CloudFlare, as you will need it too.
Next, click on Get your API Token. In the API Tokens page there will be two information you need. The first one is the Global API Key inside the API Keys section; just click the View button.
The second one is the API Token, which we must generate with appropriate permissions. To generate it, click on Create Token button at the API Tokens section. A table with several templates will be listed. Click on Use template at the Edit Zone DNS row. In the next page, at the Permissions section, there will be three fields to be set. Select Zone, DNS and Edit in the three fields. The next section is Zone Resources and requires two fields to be set. Select Include and All zones. You can leave IP address Filtering and TTL blank and click Continue to summary. A confirmation page will be displayed and you have to click on Create token button. In the next step, you have to copy the generated token and save somewhere safe. It will never be displayed again, so don’t lose it!
Optional: DNS CAA record
A Certification Authority Authorization (CAA) record is used to specify which certificate authorities (CAs) are allowed to issue certificates for a domain. We can use that to make sure a compromised CA issues certificates for your domain by accident.
In order to allow Let’s Encrypt and Let’s encrypt only to issue certificates for your domain, from CloudFlare dashboard, click on your domain name and then on DNS button. In the DNS page, click on Add record and do as follows
- Type: CAA
- Name: @
- TTL: Auto
- Tag: Only allow specific hostnames
- CA domain name: letsencrypt.org
Finish the process by clicking Save. If you are using wildcard certificates, you need a second CAA record with Tag Only allow wildcards. A CAA entry for wildcard does not replace the CAA for specific hostnames, such as the root domain! In the rare case that a subdomain is using a different CA, you may have to change Name to something different than @, such as subdomain1, etc.
At this point, you have all information to configure ACME on your pfSense. Let’s get to it!
pfSense ACME setup
On your pfSense, go to System >> Package Manager >> Available Packages. At the Packages table, click on the Install button for the acme package. After clicking confirm button, installation should start.
Go to Services >> Acme certificates page. From there, click on Account keys and fill in Name, Description, E-mail address with your info. Pick Let’s Encrypt Staging ACME v2 (for TESTING purposes) as ACME Server during tests. Click on Create new account key, click on Register ACME account key and finally click on Save to finish the account creation process on Let’s Encrypt.
With a valid Let’s Encrypt account configured, it is time to create the certificates. Click on Certificates tab and click on Add and fill in the form as bellow:
- Name: Anything that helps you identify your certificate. Must be unique. You can use the URL for the certificate, such as abc.domain.com
- Description: is an optional free text field and… pretty much self explanatory
- Status: Active
- Private key: 2048-bit RSA
- OCSP Must Staple: leave unchecked
- For Domain SAN list, you have to create one entry for each certificate you want to issue. Here we will create just one, but you can create more.
- Mode: Enabled
- Domain name: FQDN for the certificate, such as ‘abc.domain.com’
- Method: DNS-Cloudflare
- Key: Refers to the Global API Key from CloudFlare account
- Email: E-mail used to create your CloudFlare account
- Token: Refers to the API Token you generated on CloudFlare
- Account ID: Refers to the Account ID from CloudFlare
- Zone ID: Refers to the Zone ID also from CloudFlare
- Enable DNS alias mode: Leave blank
- Enable DNS domain alias mode: Leave blank
- DNS-Sleep: If your pfSense is blocking DNS over HTTPS, ACME plugin might not be able to verify the domain using DNS challenges. In that case, set DNS-Sleep to 300s
- Actions list: Leave blank
- Certificate renewal after: Leave blank
Click and Save and you will be redirected to the certificate list page. Click on Issue/Renew button on the row which contains your newly created certificate. A spinning gear icon will show up and after some time your certificate should be issued. A green text box will show up with details of your certificates. Sometimes the UI will show an icon similar to a broken chain link, meaning something went wrong. Refresh the page and look at the Last renewed column. If the date is current, then everything went well and you can disregard the alarming icon.
You can repeat the steps above and create multiple Certificates for different devices/domains, such as one for your pfSense (e.g. pfsense.lan.domain.com), another for the UDM Pro (e.g. unifi.lan.domain.com) and/or your Synology NAS (synology.lan.domain.com). This is useful as the internal devices won’t be able to issue their own certificates, as Let’s Encrypt needs port 80 and you can have a single device using it
Once the certificate is generated, you can see it at System >> Cert. Manager >> Certificates page. You can also find it at /cf/conf/acme/certificate_name.* on your pfSense filesystem.
Remember you have chosen to issue a Staging certificate in the beginning, meaning this is a fake certificate, just for testing purposes. Now that everything is working, delete the staging certificate on this page by clink on the trash button, go to Services >> Acme certificates >> Account Keys page and click in the edit icon for your Let’s Encrypt account. Change ACME Server to Let’s Encrypt Production ACME v2, then click on Generate new account key button, then click on Register ACME account key and finish the changes by clicking Save. Go to the Certificates tab and click Issue/Renew button again, to replace the existing staging certificate by a production one. If you go to System >> Cert. Manager >> Certificates page, you can see the new production certificate. Yay!
Automatic Certificates renewal
Now that you have your Let’s Encrypt certificate, they will be valid for about 90 days. in order to automate the renewal process – and that is why we have chosen to use DNS challenges as opposed to other simpler approaches, we have to make an extra step. Go to Services >> Acme >> Settings page and check the cron Entry box and click Save. That is it!
Optional: Preparing for automation
This is an optional steps that enables pfSense to save the certificates in a configuration directory that we can then use for future automation, such as installing Let’s Encrypt certificates to your Synology NAS or UDM-Pro appliance. Go to Services >> Acme >> Settings page and check Write certificates and Save. That is it, from now on you can copy the latest certificates from /conf/acme/certificate_name.*.
The target directory for ACME certificates is actually under /cf/config/acme/. At least on my installation, /tmp/acme does not even exist. Just a heads up. I’m assuming the file location was changed after a recent update.
Thanks for the heads up. I’ve just did another clean installation and verified the change. The post is updated too!
I’ve created a domain and host name for my pfsense but I can’t use the url I created for it without using the port number too. when I use the url without the port number I get an SSL error
Do you have the error message? when you type https as URL, that already implies port 443. Maybe you are not using default SSL port on your setup?
Good Post!
One question i am unable to issue certificate using ACME, Do we need to create Firewall rule to communication with Let’s Encypt. Already open WAN interface 443 for this?
Thanks in advance!
Hi Sha, port 80 and 443 on your pfSense must be open and connecting to Internet. Make sure your ISP does not block those ports
Hi Thiago Crepaldi,
Very good explanation!
Could you please help me out, i have two pfsese in HA-Availability, one is master node and second one is backup node.
With CARP IP HA sync is also working i am using package HAProxy and ACME, if i create some rule (Fronted and Backened) for HAProxy it immediately replicate to backup node, till here as expected.
But when i create certificate on Master Node after successful creation i see on the log even i go to location /tmp/acme and /conf/acme certificate created.
Why this two location /tmp/acme and /conf/acme i thought initially when certifcate not created with some issue it goes to /tmp/acme but this is not the case.
But my question is why this certificate not replicate to Backup node with High Availability Sync even sync option is Certificate Authorities, Certificates, and Certificate Revocation Lists selected.
Is there any way that after creating certificate on Maser node replicate to Backup node automatically or do we need to manually copy and paste to backup.
Thanks in advance.
Happy to hear from you soon!
Hi Sha, I never used use HA on pfSense, so I am afraid I cannot help with it. In the worst case, you can always create a CRON job to copy from master to the slave on a schedule.
I did get a second Netgate, so soon I might start playing with HA. Stay tuned