Wrote this for my squid boxes. They’re built with lots of redundancy – I can fail over to a different NIC/IP address in the event of a connectivity failure.
Written and tested on Solaris, runs as a Ruby daemon.
#!/usr/local/bin/ruby require 'net/smtp' require 'daemons' # # defaultroute_failover.rb runs as a daemon. # # $ ruby myproc_control.rb start # (myproc.rb is now running in the background) # $ ruby myproc_control.rb restart # (...) # $ ruby myproc_control.rb stop # # For testing purposes you can even run myproc.rb without forking in the background: # # $ ruby myproc_control.rb run # ########################### # LOCAL CONFIGS # router_a = "161.201.128.1" router_b = "62.50.202.65" admin_email="noc@foo.com" sleep_interval=60 debug=false mail_enabled=true # ########################### hostname = `hostname`.chomp active_defaultrouter = "" backup_defaultrouter = "" def get_defaultrouter return `netstat -rn | grep '^default' | awk '{ print $2 }'`.chomp end def ping(host) system "/usr/local/sbin/fping -r 5 -t 1000 -p 3000 -q #{host} >/dev/null 2>&1" if ($?.exitstatus == 0) return true else return false end end def mail_admin(msg) if mail_enabled from = "root@#{hostname}.foo.com" to = admin_email Net::SMTP.start('localhost') do |smtp| smtp.send_message msg, from, to end end end def switch_defaultrouter `route delete default #{active_defaultrouter}` `route add default #{backup_defaultrouter}` end ############################################################################################################################# Daemons.run_proc('defaultroute_failover.rb') do loop do active_defaultrouter = get_defaultrouter() if active_defaultrouter == router_a backup_defaultrouter = router_b elsif active_defaultrouter == router_b backup_defaultrouter = router_a else msg = "Active default router is an unrecognized IP address: #{active_defaultrouter}. Exiting with no actions." puts msg if debug mail_admin msg exit 1 end if debug puts "router_a = #{router_a}" puts "router_b = #{router_b}" puts "active_defaultrouter = #{active_defaultrouter}" puts "backup_defaultrouter = #{backup_defaultrouter}" end if ! ping(active_defaultrouter) puts "I canont ping the active default router at #{active_defaultrouter}!!!" if debug if ping(backup_defaultrouter) puts "I can ping the backup default router at #{backup_defaultrouter}." if debug switch_defaultrouter if !debug msg = "#{hostname} proxy defaultrouter unpingable. switched defaultrouter from #{active_defaultrouter} to #{backup_defaultrouter}." puts msg if debug mail_admin msg else puts "I can NOT ping the backup default router at #{backup_defaultrouter}!!!" if debug msg = "#{hostname} proxy defaultrouter and backup defaultrouter unpingable." puts msg if debug mail_admin msg end else puts "I can ping the active default router at #{active_defaultrouter} with no issues." if debug end sleep sleep_interval end end