4.9 KiB
DDNS for Cloudflare
Small binary to update Cloudflare DNS entries via a config file.
How does it work
This system is split into two portions, the binary itself and an external timer that periodically executes the binary.
To install the binary, either build your own .deb
file or find a release. More
distro support is appreciated but not currently promised.
An external timer can be a system provided one or something like crontab
.
For convenience, a systemd
system and timer file is provided that activates it
on an hourly interval. This is automatically installed if you use the .deb
.
The binary contains various subcommands:
Subcommand | Description |
---|---|
run |
Reads from a config file and calls into Cloudflare's API |
list |
Read the config file to list information about your zones |
This binary must be activated at your preferred interval via an external timer.
This only supports updating one IP address to any number of zones and DNS entries. For another IP address, install and run this on the machine with different IP address.
Installation
First, create an initial file at /etc/cloudflare-ddns.toml
. Set the permissions
so that it is readable and writable by root
only:
# sudo touch /etc/cloudflare-ddns.toml
# chmod 600 /etc/cloudflare-ddns.toml
Populate it with the following:
[account]
email = "your@email.com"
api_key = "aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa"
[ip_reflector]
ipv4 = "https://what.is.my.ipv4.example"
ipv6 = "https://what.is.my.ipv6.example"
[zone."example.com"]
id = "deadbeefdeadbeefdeadbeefdeadbeef"
account
section
The email
should be the email associated with your Cloudflare account.
The api_key
field should be populated with your Global API Key. This is found
at on your account profile.
ip_reflector
section
The ipv4
and ipv6
fields should be populated with a URL that when provided
a GET
request, returns the IP address in the body as a string, without a
newline.
For example, curl
should return something similar to this:
$ curl https://what.is.my.ipv4.example
1.2.3.4%
The %
is added by curl
to indicate no line ending.
zone
section
Each zone subsection should contain a website registered to your account. Each
zone needs an id
, which can be found on the Overview tab of the respective
website.
Once you've populated all fields, run cloudflare-ddns list
to list the ids of
each DNS entry:
example.com (deadbeefdeadbeefdeadbeefdeadbeef)
+--------------------+------+--------------------------+---------+----------------------------------+
| Name | Type | IP Address | Proxied | Id |
+--------------------+------+--------------------------+---------+----------------------------------+
| example.com | A | 6.6.6.6 | false | fefefefefefefefefefefefefefefefe |
+--------------------+------+--------------------------+---------+----------------------------------+
| irys.example.com | A | 6.6.6.6 | true | c0ffeec0ffeec0ffeec0ffeec0ffeec0 |
+--------------------+------+--------------------------+---------+----------------------------------+
| suisei.example.com | AAAA | 1111:11::1111 | true | 1337c0d31337c0d31337c0d31337c0d3 |
+--------------------+------+--------------------------+---------+----------------------------------+
This lists all relevant data necessary for dynamically updating each DNS entry.
For each DNS entry for example.com
you want to dynamically update, create an
entry as follows:
[[zone."example.com".record]]
name = "@" # Use @ for the root domain
id = "fefefefefefefefefefefefefefefefe"
proxy = false
type = "A"
[[zone."example.com".record]]
name = "irys"
id = "c0ffeec0ffeec0ffeec0ffeec0ffeec0"
proxy = true
type = "A"
[[zone."example.com".record]]
name = "suisei"
id = "1337c0d31337c0d31337c0d31337c0d3"
proxy = true
type = "AAAA"
A full example config can be found in the repo.
At this point, you can run cloudflare-ddns run
to verify that everything
works. If you run into issues, you can provide --log=debug
or --log=trace
for more information.
If successful, attempt to trigger it via the external timer. If that is successful, installation is complete.
Building packages
A .deb
package is created via cargo-deb
.
Security
This project attempts to take security seriously. Please note the following hardening notes applied by default.
Hardened systemd
service configuration
In principle, this service needs very little access to a host, and needs access
to the internet. As a result, the default systemd
service configuration
aggressively restricts the capabilities of the binary to a minimum set of
features, namely access to the internet and dependency to do so. If you believe
more directives could be provided, please create a PR.