Skip to content

Instantly share code, notes, and snippets.

@dot
Created June 27, 2011 10:23
Show Gist options
  • Save dot/1048634 to your computer and use it in GitHub Desktop.
Save dot/1048634 to your computer and use it in GitHub Desktop.
Dynamic DNS updater by dot for Zerigo
#!/usr/bin/env ruby
# -*- coding: utf-8 -*-
# Dynamic DNS updater by dot for Zerigo
#
# need gem 'net-dns'
require 'yaml'
require 'ipaddr'
require 'open-uri'
require 'logger'
require 'pp'
require 'timeout'
configpath = File.expand_path('info.yml', File.dirname(__FILE__))
unless File.exists? configpath
File.open(configpath, 'w+') do |f|
f.write({}.to_yaml)
end
end
config = YAML.load_file(configpath) || {} rescue {}
API_KEY = 'myzerigoapikey' # your Zerigo API key
USER = '[email protected]' # your Zerigo username
NS = 'a.ns.zerigo.net' # Zerigo nameserver to query
HOSTS = ['test.example.com', 'test.example.jp'] # the host you want to dynamically update
# for get local grobal ip
URLS = ['http://dyn.value-domain.com/cgi-bin/dyn.fcg?ip',
'http://ieserver.net/ipcheck.shtml']
logger = Logger.new('./update.log')
logger.level = Logger::INFO
# ---
current_ip = config[:current_ip]
new_ip = nil
dns_ip = nil
# diff ipaddr local store
URLS.each do |uri|
begin
new_ip = IPAddr.new(open(uri).read)
break
rescue StandardError, Timeout::Error => e
logger.warn(e)
next
end
end
if !new_ip
logger.info('cannot get wan address.')
exit
elsif new_ip.to_s == current_ip
logger.debug('not necessary to change wan address.')
exit
end
# Load more libraries
require 'resolv'
require 'rubygems'
require 'net/dns/resolver'
# Resolving the IP address stored in the DNS server
ns_ip = Resolv.getaddress(NS).to_s
res = Net::DNS::Resolver.new(:nameservers => ns_ip)
failures = []
HOSTS.each do |host|
begin
# make sure you query the right Nameserver
res.search(host).each_address { |ip| dns_ip = ip }
if new_ip.to_s != dns_ip
url = "http://update.zerigo.com/dynamic?host=#{host}&user=#{USER}&password=#{API_KEY}"
puts open(url).read
end
rescue => e
failures << host
logger.error(e)
end
end
if failures.empty?
config[:current_ip] = new_ip.to_s
config[:updated_at] = Time.now
File.open(configpath, 'w+') do |f|
f.write(config.to_yaml)
end
puts "Succeeded ip address updateing: #{current_ip} to #{new_ip.to_s}"
else
puts "at #{failures.inspect}: update ip failure (see logs)"
end
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment