Skip to content

Instantly share code, notes, and snippets.

Embed
What would you like to do?
Script to update a Google Domains DNS record
#!/bin/bash
### Google Domains provides an API to update a DNS "Syntheitc record". This script
### updates a record with the script-runner's public IP, as resolved using a DNS
### lookup.
###
### Google Dynamic DNS: https://support.google.com/domains/answer/6147083
### Synthetic Records: https://support.google.com/domains/answer/6069273
USERNAME=""
PASSWORD=""
HOSTNAME="yoursubdomain.yourdomain.here"
# Resolve current public IP
IP=$( dig +short myip.opendns.com @resolver1.opendns.com )
# Update Google DNS Record
URL="https://${USERNAME}:${PASSWORD}@domains.google.com/nic/update?hostname=${HOSTNAME}&myip=${IP}"
curl -s $URL
@mbbackus

This comment has been minimized.

Copy link

@mbbackus mbbackus commented Aug 11, 2018

Might want to add --insecure option to the curl request as I was unable to get it run otherwise (no ca-certificates on my router).

@jslay88

This comment has been minimized.

Copy link

@jslay88 jslay88 commented Oct 10, 2018

@mbbackus, that is a really terrible idea for the fact that your credentials are being passed in this request. Not just any credentials, credentials which gives access to the domains. Which is basically like giving the keys away to the business.

It would be much safer to add the CA cert to the router (this is relatively easy for most routers).

Mainly posting this so others don’t see the comment and just blindly disable SSL verification.

@drewchapin

This comment has been minimized.

Copy link

@drewchapin drewchapin commented Mar 9, 2019

You can also use Google Domains to get your public IP address.
IP=$(curl -s "https://domains.google.com/checkip")

In my Gist, I fetch the current record Google has, and compare it to my public IP before trying to submit an update. I also examine the response and echo out a more detailed status update.

@ghzgod

This comment has been minimized.

Copy link

@ghzgod ghzgod commented Mar 16, 2019

How do I use this if I have more than 1 subdomain?

@raceybe

This comment has been minimized.

Copy link

@raceybe raceybe commented Jun 19, 2019

For the record, all of this is based on the Dyn API developed in the 90s and most vendors support it for dynamic updates. You can check for details here:

https://help.dyn.com/remote-access-api/

@rafaelfranco-vera

This comment has been minimized.

Copy link

@rafaelfranco-vera rafaelfranco-vera commented Aug 22, 2019

Should it work the same way if my agent has a n IPv6 address? Because it doesn't seem to work for me.

@cyrusboadway

This comment has been minimized.

Copy link
Owner Author

@cyrusboadway cyrusboadway commented Aug 22, 2019

The documentation suggests the API supports IPv6 updates.

https://support.google.com/domains/answer/6147083

You may need to modify the script to url-encode the ip address (the colons in particular). Rather than composing the Url as a single string, you could add the data parameters component through curl's method, which will do the encoding:

curl --data-urlencode "myip=${IP}" https://domains.google.com/etc.

https://curl.haxx.se/docs/manpage.html#--data-urlencode

@rafaelfranco-vera

This comment has been minimized.

Copy link

@rafaelfranco-vera rafaelfranco-vera commented Aug 22, 2019

Thanks for the quick response.
The .sh script works and returns "good 'my IPv6 address'".
However my domain only works if I am connected in the same network as the server. But is a type my IPv4 address in a browser on a device that is not in the same network it actually works.

I don't know what's the problem.

@n0v1c3

This comment has been minimized.

Copy link

@n0v1c3 n0v1c3 commented Sep 9, 2019

@rafaelfranco-vera

This will make it IP4
IP=$( curl -4s "https://domains.google.com/checkip" )

Bonus! Clean output
curl -sw '\n' $URL

@wluo

This comment has been minimized.

Copy link

@wluo wluo commented Oct 5, 2019

I think it would be slightly more secure to do this so your username and password are not in plain text (url) provided you're making an HTTPS request:
curl --user ${USERNAME}:${PASSWORD} -s $URL

@rafex

This comment has been minimized.

Copy link

@rafex rafex commented Oct 23, 2019

I did something similar with python, avoiding calls from google domains. Today I have the script running every 5 minutes.

https://github.com/rafex/updateGoogleDomains

@jaddriggers

This comment has been minimized.

Copy link

@jaddriggers jaddriggers commented Dec 20, 2019

I'm getting badagent when trying to run in macosx terminal
Nevermind fixed it. Changed to use Google domains to get IP

@rip057

This comment has been minimized.

Copy link

@rip057 rip057 commented Feb 10, 2020

only posting here because i was drawn in by the search engine... never transmit your username and password in anything but TLS and proper TLS... dont be a fool its not worth it in the end.
you can use this for ip address retrieval

currentipaddress="$(wget -q -O - checkip.dyndns.org | sed -e 's/.Current IP Address: //' -e 's/<.$//')"

or you can use this if you are directly connected... change to your correct network interface though

currentipaddress="$(ifconfig eth1 | grep -o "inet addr:([0-9]{1,3}.){3}[0-9]{1,3}" | sed 's/inet addr://')"

and this is the curl request that i have formed and it works perfectly everytime.

curloutput=$(curl -s --data-urlencode "hostname=@.domain.com" --data-urlencode "myip=$currentipaddress" -H "Host: domains.google.com" -u "$username:$password" "https://domains.google.com/nic/update")

echo "$curloutput" to wherever you want

@AdamKearn

This comment has been minimized.

Copy link

@AdamKearn AdamKearn commented May 20, 2020

I know this is an old thread but you can just send a request to the URL and not include the IP just pass the username and password.
The API will then use the IP the request was sent from.

e.g.
curl https://username:password@domains.google.com/nic/update?hostname=subdomain.yourdomain.com

For more details see the section at the bottom of this page labelled "Using the API to update your Dynamic DNS record"
https://support.google.com/domains/answer/6147083?hl=en-GB

@fmlatghor

This comment has been minimized.

Copy link

@fmlatghor fmlatghor commented Dec 8, 2020

I had to change line 15 to IP=$( curl ifconfig.me ). Other than that the script works.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment