#route53 #ddns

app ddns-route53

DDNS client for (AWS) Route53

9 releases (breaking)

0.7.0 Apr 25, 2026
0.6.0 Apr 2, 2026
0.5.0 Sep 29, 2025
0.4.0 Jul 20, 2025
0.1.1 Mar 31, 2025

#538 in Network programming

MIT/Apache

160KB
3.5K SLoC

ddns-route53

ddns-route53 is a utility for creating a Dynamic DNS ("DDNS") solution for zones hosted by AWS Route53. Other hosting providers are not supported.

Overview

ddns-route53 works by first attempting to identify the public IPv4 or IPv6 address it is running at, using several possible algorithms set in its configuration. Once its address(es) are determined, it compares the result with the DNS resource records in a Route53-hosted zone and, if they differ, update the zone to match.

Installing the easy way

  1. Install the rust compiler, using either your distribution's sources or by following https://www.rust-lang.org/tools/install.
  2. Run this command:
    cargo install ddns-route53
    
  3. Once done, you'll find the utility at ~/.cargo/bin/ddns-route53 (where ~ refers to your home directory).

Building/installing (manually)

If you want to build and install it manually, follow these steps instead:

  1. Install the rust compiler, using either your distribution's sources or by following https://www.rust-lang.org/tools/install.
  2. Download the ddns-route53 source from GitHub, or check it out using git:
    git clone https://github.com/johnboy2/ddns-route53.git
    
  3. Enter into the directory where you downloaded it, and run
    cargo build --release
    
  4. Wait for it to download dependencies and compile the tool (this can take a few minutes).
  5. Once done, you'll find the utility at target/release/ddns-route53.

Optional build features:

native-decode

The native-decode feature changes the decoding behavior of any plugin IP address algorithms you have configured.

By default (i.e., without this feature), any plugin output decoding is done as follows:

  1. If the algorithm provides an encoding option, that will be used to decode the plugin's output.
  2. If the output begins with a byte-order mark for any of UTF-8, UTF-16LE, or UTF-16BE, the output will be decoded using the indicated encoding.
  3. If the first two bytes can be decoded as a valid UTF-16 code unit, and if the resulting code-point is in the range U+0000-U+00FF, then the plugin's output will be decoded with UTF-16 using the system's native byte-order.
  4. Finally, if all else fails, UTF-8 will be used.

With this feature installed, however, the fourth step instead becomes:

  1. Depending on your operating system:
    • On Unix (including Linux and MacOS), the LC_ALL, LC_CTYPE, and LANG environment variables are read, in that order, for the first to specify a codeset component. (For a list of available codesets on your system, you can often use the iconv -l command.) If a supported codeset is found, that will be used to decode the plugin output using the native iconv library. If no codeset is found, decoding falls back on UTF-8.
    • On Windows, the active code page (i.e., the output from running the chcp command from a terminal window) will be used to decode the plugin output using Windows' native API. There is no fallback from this case, since Windows systems always have an active code page.
    • For all other systems, UTF-8 remains the fallback decoder (i.e., just as if this feature wasn't installed).

AWS configuration

Querying and updating a Route53 zone requires an IAM identity with appropriate permissions. See the AWS IAM documentation for details.

Example Route53/IAM playbook

The following example shows one way to create an IAM user with limited permissions for exclusive use by ddns-route53.

  1. Determine the "Zone ID" for your Route53-hosted DNS zone:
    1. Log into the Route53 console as a user with sufficient administrative rights.
    2. In the Dashboard, click on "Hosted zones".
    3. Select the DNS zone for which you want Dynamic-DNS updates.
    4. Expand "Hosted zone details" (near the top of the page).
    5. Make note of the "Hosted zone ID" — you'll need it again later.
  2. Create an IAM user that can update the zone:
    1. Log into the IAM console as a user with sufficient administrative rights.

    2. In the Dashboard, find "Access Management" and click on "Policies".

    3. Click "Create policy".

    4. Under the Policy editor, click on "JSON", and replace the default content with the following:

      {
          "Version": "2012-10-17",
          "Statement": [
              {
                  "Effect": "Allow",
                  "Action": "route53:ChangeResourceRecordSets",
                  "Resource": "arn:aws:route53:::hostedzone/Z01234567890ABCDEFGHI",
                  "Condition": {
                      "ForAllValues:StringEquals": {
                          "route53:ChangeResourceRecordSetsNormalizedRecordNames": "home.example.com",
                          "route53:ChangeResourceRecordSetsRecordTypes": [
                              "A",
                              "AAAA"
                          ]
                      }
                  }
              },
              {
                  "Effect": "Allow",
                  "Action": "route53:ListResourceRecordSets",
                  "Resource": "arn:aws:route53:::hostedzone/Z01234567890ABCDEFGHI"
              },
              {
                  "Effect": "Allow",
                  "Action": "route53:GetChange",
                  "Resource": "arn:aws:route53:::change/*"
              }
          ]
      }
      

      Replace home.example.com in the IAM policy above with the fully-qualified domain name of the record you want maintained.

      The first two "Resource" entries above must be updated to give the "ARN" of your zone, which is comprised of the prefix, "arn:aws:route53:::hostedzone/", followed by your zone ID. For example, if your Zone ID is Z12345, then its ARN is "arn:aws:route53:::hostedzone/Z12345" — so that's what you should put under the first two "Resource" sections of the IAM policy above.

    5. Click "Next".

    6. Set a suitable policy name; e.g. DynamicDNS-home.example.com.

    7. Scroll down to the bottom and click "Create Policy".

    8. In the Dashboard, find "Access Management" and click on "Users".

    9. Click on "Create user".

    10. Enter a suitable name into the "User name" field; for example ddns-user. Then click "Next".

      Other options on this page can be skipped.

    11. On the "Set Permissions" page under "Permissions options", select "Attach policies directly".

    12. Under "Permissions policies", enter the policy name you chose above; that will filter the list of available policies to just those containing the name you gave; find your policy, and place a checkmark in the box next to its name.

    13. Click "Next".

    14. Click "Create user".

  3. Create an access key for your IAM user:
    1. Log into the IAM console as a user with sufficient administrative rights.
    2. In the Dashboard, find "Access Management" and click on "Users".
    3. Click on the user you created.
    4. Click on the "Security credentials" tab.
    5. Under "Access keys", click on "Create access key".
    6. Under use case, select "Other", and click "Next".
    7. (Optionally) Set a description, such as DDNS update key.
    8. Click "Create access key".
    9. Make note of the "Access key" and the "Secret access key", or use the "Download .csv file" button — you'll need these to setup the client configuration (below).

      Always keep your AWS IAM credentials confidential!

Client configuration

A template configuration file is available at example/ddns-route53.conf. This file uses a TOML-based format. You should copy this file to another location and edit it to match your needs.

At a minimum, you should set the following:

  • The host_name value, which should be a fully-qualified domain name within a Route53-hosted zone.
  • The aws_route53_zone_id of your zone.

    This value is technically optional, because ddns-route53 can determine this dynamically; however that requires the ListHostedZones permission (which the example above omits). See the AWS IAM documentation for help in adding this permission if desired.

  • You'll either need to specify the aws_access_key_id and aws_secret_access_key values for the IAM user you created, or else you'll need to make them available to the local user under which you will run ddns-route53 by following standard AWS SDK credential practices.

Various other configuration options exist; see example/ddns-route53.conf for more information.

Running

Configuration file path

ddns-route53 is usually setup with a configuration file -- so it needs to know where it is located in order to run. You can do this via either of two ways:

  1. Provide the path to the file explicitly, or
  2. Rely on the utility locating the configuration file automatically.

To provide the path explicitly, invoke the command with the -c argument followed by the path. For example:

ddns-route53 -c /path/to/config/file

If an explicit path is not given, the utility will automatically use the first file to be found in one of the following locations:

  1. ddns-route53.conf (i.e., a file in the current working directory)
  2. If running on a Posix system (e.g., Linux, Mac, or other Unix):
    1. ~/.config/ddns-route53.conf
    2. ~/.local/share/ddns-route53.conf
    3. ~/.ddns-route53.conf
    4. /usr/local/etc/ddns-route53.conf
    5. /etc/opt/ddns-route53.conf
    6. /etc/ddns-route53.conf
  3. If running on a Windows system:
    1. %LOCALAPPDATA%\ddns-route53.conf
    2. %ProgramData%\ddns-route53.conf

Alternatively, you can also explicitly specify no configuration file by passing -c -. (This forces use of CLI options only.)

Runtime behavior

This tool is a simple, "fire and forget" utility. That is, it checks your current IP address right now and updates the Route53 record if it differs. It does not recheck later.

If you want to run it periodically, you can use a third-party scheduler to do so. For example, the Windows Task Scheduler, Mac iCal, Mac launchd, Unix/Linux cron jobs, and Linux systemd can all be configured to run ddns-route53 periodically.

See the example folder in the source distribution for available scheduling examples.

License

MIT or Apache-2.0 at the user's choice.

SPDX-License-Identifier: [MIT] OR Apache-2.0

Dependencies

~42–64MB
~1M SLoC