Skip to content
terrakernelPublic

About

Keep a DNS record pointed at a cloud instance's ephemeral public IP (Cloudflare / Google Cloud DNS)

Resources

Stars

0 stars

Watchers

0 watching

Forks

Repository files navigation

dnssense

Keeps a DNS record pointed at a cloud instance whose public IP changes on every restart. Supports Cloudflare and Google Cloud DNS, A and (optionally) AAAA records.

On each run it:

  1. Detects the public IP: the cloud metadata server first (GCE, AWS, Azure, DigitalOcean, Hetzner), then public echo services (ipify, icanhazip, Cloudflare). Private or wrong-family answers are rejected.
  2. Reads the current record from the provider and writes only if the IP or TTL differs.

Install (Linux + systemd)

On the VM, from a checkout of this repo:

sudo ./install.sh                 # builds, asks for hostname/provider/credentials, enables at boot

Or non-interactively (e.g. from cloud-init / a startup script):

sudo ./install.sh --hostname vm1.example.com --provider cloudflare --cf-token-file /root/cf-token
sudo ./install.sh --hostname vm1.example.com --provider gcloud   # uses the VM's service account
sudo ./install.sh --binary ./dnssense ...                         # skip the build, use a prebuilt binary
sudo ./install.sh --mode watch ...                                # keep running instead of once per boot

The script:

  1. Builds with cargo, running as the user who invoked sudo, or uses --binary.
  2. Installs /usr/local/bin/dnssense.
  3. Writes /etc/dnssense/config.toml, with secrets in mode 600 files. An existing config is kept.
  4. Enables dnssense.service (boot) or dnssense-watch.service (watch).
  5. Does a dry run to check the config and credentials, then starts the service.

Re-running it upgrades the binary and switches mode safely. sudo ./install.sh --uninstall [--purge] removes it. See ./install.sh --help for all options.

Useful afterwards:

dnssense detect                   # what IP would be used, and where it came from
sudo dnssense --dry-run           # what would change in DNS
journalctl -u dnssense            # logs

Commands

Command
dnssense [sync] [--retries N] Update once and exit (default). Retries with backoff (default 5 attempts) while the network comes up.
dnssense watch [--interval S] Loop forever. Only calls the provider when the IP changes, plus an hourly re-check that repairs hand-edited records.
dnssense detect [--source auto|metadata|public] Print detected IPv4/IPv6 and exit. Doesn't need a config.

Global flags: -c/--config PATH (or DNSSENSE_CONFIG), -n/--dry-run, -v / -vv.

Provider setup

Cloudflare

Create an API token with Zone → DNS → Edit on the zone. Also grant Zone → Zone → Read unless you set zone_id. Supply it as api_token, api_token_file, or CLOUDFLARE_API_TOKEN.

Google Cloud DNS

Credentials are tried in this order:

  1. credentials_file in the config
  2. GOOGLE_APPLICATION_CREDENTIALS
  3. The VM's attached service account, via the metadata server. The VM needs the cloud-platform or ndev.clouddns.readwrite access scope.

Supported files are service account keys and gcloud auth application-default login credentials. The identity needs roles/dns.admin on the project, or a custom role with dns.changes.create, dns.resourceRecordSets.* and dns.managedZones.list.

project defaults to the key file's project or the VM's project. managed_zone defaults to the public zone whose DNS name contains hostname.

Notes

  • If several records of the same type exist for the hostname, only one is managed (a warning is logged).
  • Cloudflare proxied records always get TTL "auto".
  • Building needs a C compiler and CMake (used by aws-lc-rs, the TLS/crypto backend).

License

MIT. See LICENSE.

About

Keep a DNS record pointed at a cloud instance's ephemeral public IP (Cloudflare / Google Cloud DNS)

Resources

Stars

0 stars

Watchers

0 watching

Forks

Releases

Packages

Contributors

Languages