151 lines
No EOL
4.9 KiB
Markdown
151 lines
No EOL
4.9 KiB
Markdown
# 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:
|
|
|
|
```toml
|
|
[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].
|
|
|
|
[account profile]: https://dash.cloudflare.com/profile/api-tokens
|
|
|
|
### `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:
|
|
|
|
```toml
|
|
[[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`].
|
|
|
|
[`cargo-deb`]: https://github.com/kornelski/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. |