Unique Marketing, Guaranteed Results.

Setting PowerDNS To Ignore Records For Downed Web Sites

June 10th, 2009 by Aaron Murphy

If you are using PowerDNS for round robin on multiple websites, you can set it up so that it will return only the records for sites that are up. I set up a Ruby daemon to monitor sites and connect to the PowerDNS MySQL table used by PowerDNS on Rails. You can use any language or system you like. It just needs to be able to access your PowerDNS database.

First add the following line to /etc/powerdns/pdns.conf:

 gmysql-any-query=select content,ttl,prio,type,domain_id,name from records where name='%s' and (prio<>-1 or prio is null)

Thats the trickiest part. If you mess up on the sql query, PowerDNS may not return any results for your domain.
Then restart pdns. I use CentOS so I type

service pdns restart

Now you just need a daemon to monitor your websites. Something like the following might work for you:

#!/usr/bin/env ruby
require 'net/http'
require 'rubygems'
require 'activerecord'
 
SITE_ADDRESSES = %w( www.yourdomain.com www.example.com )
SITE_THAT_IS_ALWAYS_UP = "" # some well known site that is always up
 
class Record < ActiveRecord::Base
  ActiveRecord::Base.establish_connection(:adapter => "mysql",
    :encoding => "utf8", :database => "powerdns_production",
    :username => "your_mysql_username", :password => "your_secret_password_here",
    :host => "ns1.your_isp.com")
  set_inheritance_column :ruby_type
end
 
$running = true
 
def signal_trap_exit(signal_name)
  puts "#{Time.now} received #{signal_name} signal"
  $running = false
end
 
our_exit_signals = ["TERM", "INT", "KILL", "HUP"]
for exit_signal_name in our_exit_signals
  Signal.trap(exit_signal_name, "signal_trap_exit('#{exit_signal_name}')")
end
 
def check_internet
  begin
    Timeout::timeout(5) do
      Net::HTTP.get_response(SITE_THAT_IS_ALWAYS_UP, "/", 80) do |response|
        return response.code.match(/2|3\d{2}/)
      end
    end
  rescue => e
    puts "#{Time.now} Error connecting to internet: #{e}"
    return false
  end
end
 
def get_site_ip_addresses
  begin
    Record.find(:all, :conditions => ["type = ? and name in (?)", "A", SITE_ADDRESSES])
  rescue => e
    puts "#{Time.now} Error finding all records: #{e}"
    return []
  end
end
 
def make_inactive(ip_record)
  Record.update_all("prio=-1", "name='#{ip_record.name}' and content='#{ip_record.content}'")
end
 
def make_active(ip_record)
  Record.update_all("prio=1", "name='#{ip_record.name}' and content='#{ip_record.content}'")
end
 
while($running) do
  get_site_ip_addresses.each do |ip_address|
    begin
      Timeout::timeout(5) do
        Net::HTTP.get_response(ip_address.content.to_s, "/", 80) do |response|
          puts "#{Time.now} Response code for #{ip_address.content.to_s}: #{response.code}"
          make_active(ip_address) if ip_address.prio == -1
        end
      end
    rescue => e
      puts "#{Time.now} Error connecting to #{ip_address.content.to_s}: #{e}"
      if check_internet
        make_inactive(ip_address) unless ip_address.prio == -1
      end
    end
  end
 
  sleep 15 if $running
end
Be Sociable, Share!
Filed under: IT,Programming — Tags: , , , , — Aaron Murphy @ 4:15 pm on June 10, 2009

1 Comment

  1. [...] Setting PowerDNS To Ignore Records For Downed Web Sites « PMA Media Group (tags: monitoring network) [...]

    Pingback by links for 2009-06-28 | blog/shl@INTERDOSE — December 22, 2009 @ 5:01 am

RSS feed for comments on this post. TrackBack URL

Leave a comment

Copyright © 2005-2011 PMA Media Group. All Rights Reserved