• Stars
    star
    100
  • Rank 340,703 (Top 7 %)
  • Language
    Shell
  • License
    Other
  • Created about 11 years ago
  • Updated 11 months ago

Reviews

There are no reviews yet. Be the first to send feedback to the community and the maintainers!

Repository Details

Dynamic DNS shell script for Gandi

gad

This script is intended to be used as a cron job to maintain the accuracy of multiple A or AAAA records in a Gandi.net zonefile. External IP address discovery is done via a network interface, OpenDNS, or a custom command piped to standard input. The result is compared to the value in the active version of the zonefile of each record in RECORD-NAMES.

Prerequisites

If you are on Gandi's legacy DNS platform, your domain needs to be using a zone that you are allowed to edit. The default Gandi zone does not allow editing, so you must create a copy. There are instructions on Gandi's wiki to create an editable zone. You only need to perform the first two steps. There is a FAQ regarding this here.

If you are on Gandi's new v5/LiveDNS platform, you do not need to perform these steps.

Requirements

If you're using an OS that doesn't include the ifconfig or dig commands you have three options:

  • Install a package that provides the dig command, commonly bind-tools or dnsutils (to use IP discovery via OpenDNS)
  • Install a package that provides the ifconfig command, commonly net-tools (to use IP discovery via a network interface)
  • Use the -s flag and pipe a custom command that outputs your external IP address to gad, e.g., curl ipinfo.io/ip | gad -s -a APIKEY -d EXAMPLE.COM -r "RECORD-NAMES"

Installation

The simplest way to install gad is to clone this repository. You can optionally add the repository folder to your PATH environment variable to make running gad easier, but you should specify its full path when creating a crontab entry. Personally, I have a ~/bin folder that is already in my PATH where I create a symlink for gad, and a ~/git folder that I clone the repository into:

git clone https://github.com/brianreumere/gandi-automatic-dns.git ~/git/gandi-automatic-dns
ln -s /home/brian/git/gandi-automatic-dns/gad /home/brian/bin/gad

There is a package available for Arch Linux here, thanks to @majewsky.

To set up a crontab entry to run gad on a schedule, store your API key in the file ~/.gandiapi (run chmod 600 ~/.gandiapi to make sure no other users have permissions to this file), and then run crontab -e and add a line similar to the following (this example will run gad every 15 minutes and update the @ and www records of your domain):

0,15,30,45 * * * * /home/brian/bin/gad -5 -i em0 -d EXAMPLE.COM -r "@ www"

If you have issues with the openssl s_client command hanging, and you have access to the timeout utility from coreutils, you can precede the path to the gad command with something like timeout -k 10s 60s (to send a TERM signal after 60 seconds and a KILL signal 10 seconds later if it's still running).

There is no documentation of rate-limiting on the v5/LiveDNS API, but the legacy API has a limit of 30 requests every 2 seconds, documented here, so you should be able to run gad more frequently than every 15 minutes (gad makes a maximum of 5 API calls to update a single DNS record: 1 API call to get the active zonefile for the domain, 1 API call per record to check its accuracy, 1 API call to create a new version of the zonefile if needed, 1 API call per record to update or create it if needed, and 1 API call to activate the new version of the zonefile).

For Gandi's legacy platform, request an API key here. For the new LiveDNS platform, generate an API key by logging into the account admin panel and clicking on Security.

See the next section for more information about command-line options.

Command-line usage

$ gad [-5] [-6] [-l TTL] [-f] [-t] [-e] [-v] [-s] [-i EXT_IF] [-a APIKEY] -d EXAMPLE.COM -r "RECORD-NAMES"

-5: Use Gandi's new LiveDNS platform
-6: Update AAAA record(s) instead of A record(s)
-l: Set a custom TTL on records (only supported on LiveDNS)
-f: Force the creation of a new zonefile regardless of IP address or TTL discrepancy
-t: On Gandi's legacy DNS platform, if a new version of the zonefile is created, don't activate it. On LiveDNS, just print the updates that would be made if this flag wasn't used.
-e: Print debugging information
-v: Print information to stdout even if an update isn't needed
-s: Use stdin instead of OpenDNS to determine external IP address
-i: Use ifconfig instead of OpenDNS to determine external IP address
-a: Specify a Gandi API key on the command line instead of loading from the ~/.gandiapi file

TTL: The custom TTL value (in seconds) to set on all records
EXT_IF: The name of your external network interface
APIKEY: Your API key provided by Gandi (loaded from the file ~/.gandiapi if not specified)
EXAMPLE.COM: The domain name whose active zonefile will be updated
RECORD-NAMES: A space-separated list of the name(s) of the A or AAAA record(s) to update or create

Function syntax

rpc "methodName" "datatype" "value" "struct" "name" "datatype" "value"

The rpc function can accept an arbitrary number of datatype/value pairs and structs and their member name/datatype/value tuples. structs must be last! Valid method names can be found in the Gandi API documentation. Note that the APIKEY value from the command line is automatically included as the first parameter.

rest "verb" "apiEndpoint" "body"

The rest function can call arbitrary endpoints of Gandi's LiveDNS REST API. If the verb is not GET, the function expects a third parameter to use as the body of the POST or PUT request. Valid API endpoints can be found in the LiveDNS API documentation. Your Gandi API key from the command line or the ~/.gandiapi file is automatically included as an HTTP header.