Last active
January 18, 2025 00:42
-
-
Save sixtyfive/ef1480538a4cf6928ff690ca8dc5dfad to your computer and use it in GitHub Desktop.
DIY dDNS service script using Hetzner's DNS API
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
#!/usr/bin/env ruby | |
# on OpenRC systems, place into e.g. /etc/periodic/15min | |
# (or create /etc/periodic/1min and add line to root's crontab) | |
# on systemd systems, install it as a timer | |
# create/find these in Hetzner's DNS admin interface at https://dns.hetzner.com/ | |
API_TOKEN_NAME="..." | |
API_TOKEN="..." | |
ZONES=["...", "..."] # TLD; must be registered at https://robot.hetzner.com/domain | |
RECORDS=["...", "..."] # list of subdomains, also specified there | |
# will be a bit faster if specified | |
# ZONE_ID="..." | |
# RECORD_ID="..." | |
require 'json' | |
require 'socket' | |
ZONES.each do |zone| | |
@zone_id = ZONE_ID ? ZONE_ID : ( | |
json = JSON.parse `curl -s "https://dns.hetzner.com/api/v1/zones" -H "Auth-API-Token: #{API_TOKEN}"` | |
zones_json = json.delete('zones') | |
zones_json.find{|x| x['name']==zone}['id'] | |
) | |
json = JSON.parse `curl -s "https://dns.hetzner.com/api/v1/records?zone_id=#{@zone_id}" -H "Auth-API-Token: #{API_TOKEN}"` | |
records_json = json.delete('records') | |
RECORDS.each do |record| | |
record_json = records_json.find{|x| x['name']==record} | |
@record_id ||= record_json['id'] | |
current_record_ip = record_json['value'] | |
current_wan_ip = Socket.getifaddrs | |
.map{|iface| [iface.name, iface.addr.ip_address] if iface.addr.ipv4? if iface.addr} | |
.compact | |
.find{|x| x[0]=='ppp0'}[1] | |
next if current_record_ip == current_wan_ip | |
system %Q( | |
curl -X "PUT" "https://dns.hetzner.com/api/v1/records/#{@record_id}" \\ | |
-H "Content-Type: application/json" \\ | |
-H "Auth-API-Token: #{API_TOKEN}" \\ | |
-d $'{ | |
"value": "#{current_wan_ip}", | |
"ttl": 60, | |
"type": "A", | |
"name": "#{record}", | |
"zone_id": "#{@zone_id}" | |
}' | |
) | |
end | |
end |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment