Category Archives: Uncategorized

blog.

This [blog] has been an idea on the back burner for a very long time. Reasons for this include:

  • What will I use? (WordPress, GitHub Pages, etc.)
  • What will the domain name be?

As you can tell, I have decided to use WordPress and this subdomain. Maybe one day I will get creative and flip everything around but this is the lane that I have chosen to drive in (for now).

Delegate ACME challenges to another nameserver

I have been using Let’s Encrypt’s DNS-01 challenge to prove that I control DNS for domain names. However, obtaining certificates and renewing them have been a manual process where I added scripts to getssl to tell me the TXT record(s) to add for that domain. I did it this way because I did not like the idea of giving a script full capability (at the time) to play with my DNS records. I do not remember where, but I learned that we can CNAME TXT records which means that a TXT record can be a CNAME pointing at another record that can be updated. Neat.

Plan

  • Set up a BIND 9 server
    • Set up a dynamic zone for acme.example.net
    • Generate ddns keys for servers that host a service that uses an SSL certificate
  • Update DNS
    • Add A and NS records such that acme.example.net queries are handled by another nameserver
    • Add CNAME records for _acme-challenge.foo.example.net to point at _acme-challenge.foo.acme.example.net
  • Request certificates for a given set of domains

Most of what I did was influenced by Dan Langille’s post at https://dan.langille.org/2019/02/01/acme-domain-alias-mode/.

BIND 9

Install

On Debian, installing BIND 9 was done by executing sudo apt install bind9.

Disable recursion

One of the things that we need to do is to disable recursion such that our nameserver is not an open resolver. Recursion is disabled by adding the following to the options block in /etc/bind/named.conf.options

recursion no;

Set up a dynamic zone

Copy /etc/bind/db.empty to /var/lib/bind/db.acme.example.net and edit accordingly.

$TTL	86400
@	IN	SOA	a.ns.example.net. no-reply.acme.example.net. (
		    2020010700 	; Serial
			  43200 	; Refresh
			   7200	; Retry
			2419200	; Expire
			  86400 )	; Negative Cache TTL
;
@	IN	NS	a.ns.example.net.

db.acme.example.net will be light since it is a dynamic zone.

Update /etc/bind/named.conf.local with the dynamic zone

zone "acme.example.net." {
	type master;
	file "/var/lib/bind/db.acme.example.net";
};

ddns key

We will now generate a dynamic DNS key that will allow our ACME client of choice to dynamically update the dynamic zone we have created.

On Arch Linux, I used the following ddns-confgen invocation to generate a ddns key

ddns-confgen -a hmac-sha512 -k one.example.net. -q > one.example.net.key

The contents of one.example.net.key

key "one.example.net." {
	algorithm hmac-sha512;
	secret "iXdUnXCbxJqcr3rgxYVdvHVqLmJkHW6mNZEDsXwDXtvxIfVmoABHWjN4ko4+Rz2uEmgOk+IFfqgEVGrAYTWaIA==";
};

Now that we have a ddns key, we will need to make BIND 9 aware of it.

In /etc/bind/named.conf, we will add an include for a new file at /etc/bind/named.conf.keys

include "/etc/bind/named.conf.keys";

The content of /etc/bind/named.conf.keys will be the contents of one.example.net.key. Setting it up this way allows us to add named.conf.keys to .gitignore if we’re using configuration management such as Ansible.

Last but not least, we will update the zone configuration in /etc/bind/named.conf.local with an update-policy that says this key (one.example.net.) is permitted to update this zone:

zone "acme.example.net." {
	type master;
	file "/var/lib/bind/db.acme.example.net";
	update-policy {
		grant one.example.net. zonesub TXT;
	};
};

With the above configuration, the one.example.net. key would be able to update any TXT record within the acme.example.net zone. If desired, we could restrict the key to a domain such as assets.example.net, we would replace the grant line with the following:

grant one.example.net. name _acme-challenge.assets.acme.example.net. TXT;

Add DNS records

To delegate the _acme-challenge record to a subdomain, I added the following DNS records to the nameserver serving example.net:

a.ns IN A 192.168.26.42
acme IN NS a.ns.example.net.

Now for each domain I want to delegate the _acme-challenge record to, I added a CNAME like the following:

_acme-challenge.subdomain IN CNAME _acme-challenge.subdomain.acme.mydomain.net.

Request Certificates

At this point, we upload one.example.net.key to our box. I stash mine as /root/nsupdate.key. Then I use the following acme.sh invocation to request a certificate for one.example.net.
NSUPDATE_SERVER and NSUPDATE_KEY are environment variables to clue acme.sh to the name server to update and the key to use.

# NSUPDATE_SERVER=a.ns.example.net NSUPDATE_KEY=/root/nsupdate.key acme.sh --issue --dns dns_nsupdate -d one.example.net --challenge-alias one.acme.example.net --server letsencrypt --reloadcmd 'systemctl reload nginx'

With acme.sh we could use letsencrypt_test as the --server so that we can test to make sure things are working as expected.

INSTALL_VERIFICATION_FAILED_ALERT_INFO Error with Office 365 and macOS

While installing Office 365 (16.25.19051201) for a client (macOS High Sierra 10.13.6), Microsoft AutoUpdate (MAU) pops up with an error saying “INSTALL_VERIFICATION_FAILED_ALERT_INFO”. Clicking OK would open the browser and it would proceed to download the latest AutoUpdate to install. However, at the end of the install the error comes up again. Repeat until annoyed.

While going through many Q & A pages, I recall running into a folder that I couldn’t access without elevated privileges. I don’t know macOS internals that well so I didn’t have the slightest idea as to the purpose of that folder.

It turns out that the permissions on /Library/PrivilegedHelperTools were borked. Unfortunately, I didn’t capture what the state was but it was probably something along the lines of rwx------.

Comparing with two devices I had access to, the permissions were the following:

# ls -ld /Library/PrivilegedHelperTools
drwxr-xr-t  13 root  wheel  416 Feb 22 18:32 /Library/PrivilegedHelperTools

As root, I semi-sorted the permissions with # chmod 755 /Library/PrivilegedHelperTools and rebooted. Upon reboot, the permissions were rwxr-xr-t and MAU and friends appeared to be happy.