I own a lot of domains, and keeping track of where all of them are pointing can be more than a little tricky. I found a tool that helps me keep everything in sync with a single point of truth.
After mixing in the 1Password command-line tool, I had everything I need to keep my domains up to date and pointing where I want them, without having to worry about my credentials being stored unsafely.
For creatives and online professionals, we’ve all been there. We think of an idea or concept and say: “Oh, that’s a good domain name”, click, repeat. Eventually, you end up with your domain registrar looking a little something like this.
Not only do I have it bad here, I’ve got three other name registrars chock full with domains between them. I’ve been managing them mostly by moving them into a single nameserver provider, but for various reasons, I keep a few on a separate nameserver provider.
I’m constantly seeking a better way of managing them and a few weeks ago, a friend of mine pointed me in the direction of DNSControl. This was the magic I was looking for, as now I can write all of my DNS settings in a single domain-specific language, and push them to my various nameserver locations.
This has made managing this registration mess much easier, as I no longer have to toggle between Cloudflare / Linode / Porkbun to configure various domains. I can configure a new domain in my Fastmail account and use it for Masked Email with only a few lines of DNSControl’s domain-specific language.
It’s changed the way I buy (and then forget about) domains.
Of course, for DNSControl to work, you need some API keys. DNSControl uses a creds.json
file, so initially my repository just had this in the folder, excluded by .gitignore
.
This was great when I was just working on my laptop, but as I use multiple devices, one of the nice things about DNSControl is it’s a single executable. So no matter whether I’m on macOS or Windows, I just need the single executable to manage my DNS entries.
Then, I started to think about my options. Since this is a private repository on my GitHub account, I could have just committed the credentials to the repo, but that just feels wrong, even if there was minimal risk of my credentials getting anywhere.
I work at 1Password and here, poor security hygiene isn’t an option. DNSControl has the ability to import environment variables into the credentials file, but that still requires managing the secrets between my devices as well. Additionally, if my device were potentially compromised, any other software running on my device would be able to access the environment variable and steal the secret.
Enter CLI
I remembered that we have an app for that! I hadn’t messed around much with the 1Password command-line tool prior to getting started with this project, but I was able to wrap my head around it quickly. Templating my file was easy (and even easier with our new Visual Studio Code extension).
I initially created a template file that I could then use op inject
with and output a creds.json
file. This was great, but I was still writing secrets to disk in plaintext. I wasn’t committing them to Git, but they were still existing on my hard drive, and I didn’t want secrets stored anywhere in plaintext, so I wasn’t quite done yet.
Contributing to the community
This is where the fun part really starts. DNSControl currently has a method of running a shell script that would print to stdout
a properly formatted JSON file containing the credentials, and if I only worked on one operating system, that likely would have worked well enough for me.
I switch between my Windows desktop and my MacBook, though, and there’s no good way to have a single script that works in both PowerShell and fish. I didn’t want to keep multiple scripts in sync if I were to add an additional provider. I took a quick look at where the code was for running the credential file, and with only a bit of work and reading through documentation, I was able to add the ability to run any arbitrary command, rather than just execute a script.
Now I can run dnscontrol push --creds “!op inject -i creds.json”
to inject my credentials into my template file, return it on stdout
and make the changes to my domains, all without my credentials ever touching the disk. And it works on all my computers, as long as I have both the DNSControl executable as well as the 1Password command-line tool installed.
We want everyone to be secure, no matter how you choose to store your secrets, and no matter where you use those secrets. Encouraging the wider ecosystem to allow for options of getting credentials into scripts and tools safely helps everyone.
Tweet about this post