[RUBY] Sync cPanel DNS zones with Linode DNS

I currently have a Linode with a cPanel install that uses a local DNS server as a master and sets the Linode DNS servers up as slaves. This allows me to fully utilize Linode's redundant DNS setup along with cPanel's familiar interface.

Here is a Ruby script that will create slave zones on Linode's DNS server pointing to your Linode's IP address. It is very basic, but gets the job done. If you are running many websites on your cPanel install, I'd recommend optimizing it.

This script will remove all DNS zones on Linode that do not already exist in cPanel.

Make sure you have the Gems necessary:

gem install linode lumberg

Create the file /scripts/rebuildlinodezones including your Linode and cPanel API keys:

#!/usr/bin/env ruby

############################################################################################
# SETUP:
# => gem install linode lumberg
############################################################################################

require 'lumberg'
require 'linode'

# Configuration information
CPANEL_KEY = "AABBCCDDEEFFGG"
LINODE_KEY = "AABBCCDDEEFFGG"

# Server IP
IP = `hostname -i`

############################################################################################
############################################################################################

# Connect to frameworks
cpanel  = Lumberg::Whm::Server.new(:host => '127.0.0.1', :hash => CPANEL_KEY)
linode  = Linode.new(:api_key => LINODE_KEY)

# Finds all DNS zones in cPanel/Linode
linode_zones = cpanel.dns.list_zones[:params]
cpanel_zones = linode.domain.list

# Iterate over each DNS Zone in Linode
linode_zones.each do |lin|
  # Find any zones in cPanel with a matching domain
  result = cpanel_zones.select { |cpl| cpl.domain == lin[:domain] }

  # If there aren't any matches, create the zone in Linode
  if result.count < 1 then
    linode.domain.create(:domain => lin[:domain], :type => "slave", :master_ips => IP)
  end
end

# Finds all DNS zones in cPanel/Linode
linode_zones = cpanel.dns.list_zones[:params]
cpanel_zones = linode.domain.list

# Iterate over each cPanel DNS Zone
cpanel_zones.each do |cpl|
  # Find any Linode zones with the same domain
  result = linode_zones.select { |lin| lin[:domain] == cpl.domain }

  # If there aren't any matches, delete the zone from Linode
  if result.count < 1 then
    linode.domain.delete(:domainid => cpl.domainid)
  end
end

Make sure it's executable:

chmod +x /scripts/rebuildlinodezones

Make sure you have named.conf setup to allow Linode nameservers to AXFR:

    allow-transfer {
        69.164.199.240;
        69.164.199.241;
        69.164.199.242;
        69.93.127.10;
        65.19.178.10;
        75.127.96.10;
        207.192.70.10;
        109.74.194.10;
    };

I currently set up this script to run from these hooks to automate the zone creation:

(NOTE: You should probably rewrite the script to selectively add and delete zones rather than completely rebuilding all entries, as this is pretty inefficient but gets the job done)

ln -s /scripts/rebuildlinodezones /scripts/postwwwacct
ln -s /scripts/rebuildlinodezones /scripts/postkillacct
ln -s /scripts/rebuildlinodezones /usr/local/cpanel/hooks/addondomain/addaddondomain
ln -s /scripts/rebuildlinodezones /usr/local/cpanel/hooks/addondomain/deladdondomain
ln -s /scripts/rebuildlinodezones /usr/local/cpanel/hooks/subdomain/addsubdomain
ln -s /scripts/rebuildlinodezones /usr/local/cpanel/hooks/subdomain/delsubdomain
ln -s /scripts/rebuildlinodezones /usr/local/cpanel/hooks/park/park
ln -s /scripts/rebuildlinodezones /usr/local/cpanel/hooks/park/unpark

After creating the hooks, be sure to run:

/usr/local/cpanel/bin/register_hooks

Now you'll have Linode's DNS server automatically update whenever you create or destroy a DNS zone on your cPanel server! Cool! I even set up my custom nameservers to point to the Linode IPs so it appears as if I'm running my own redundant and highly available nameservers :)

(of course anyone curious enough will be able to figure out they're hosted at Linode)

9 Replies

Thanks for posting this, helped me out massivley.

There is a small problem though, i cant run 2 of the ln lines cause they dont exist on my cpanel install.

ln -s /scripts/rebuildlinodezones /usr/local/cpanel/hooks/addondomain/addaddondomain

ln -s /scripts/rebuildlinodezones /usr/local/cpanel/hooks/addondomain/deladdondomain

Thanks again,

Pieh0

EDIT: Dont worry, im an idiot :P.

Needed to make the addondomain dir, now it works like a charm!

Glad to hear, Pieh0! Let me know if you run into any issues. I can't guarantee this won't break anything, but I've been running it for a bit and it seems to do the trick.

I am seriously impressed with this Tristan - thank you for sharing.

Perhaps it's something that could be included in the Linode library so that it doesn't get lost over time?

I should point out the few negatives of this method:

  • If you add or delete a DNS zone directly from the zone editor in cPanel, it won't be deleted in Linode. This is because zones are only created on Linode when you create domains. I couldn't find any hooks specifically for DNS zones creation or deletion.

  • Ideally the script would only make changes to the specific zone in question, rather than modifying every Linode zone when one cPanel zone is modified. This would allow you to create custom zones in Linode that don't correlate to cPanel.

It's still mighty useful. I would prefer that I didn't use Ruby though since it's sort of a niche language and not many people will have it installed on their server.

Like I said if you have any problems or requests with this, let me know

And thank you, by the way :) I'm glad I could help out.

I'm pretty sure anyone using cpanel will have ruby installed along with a whole bunch of other crap. However, it could easily be ported to awk or perl. But ruby blocks look pretty.

thanks for this script

unfortunately having a few errors to do with Type Errors

Symbol as array index (TypeError)

currently got: ruby 1.8.7 (2011-02-18 patchlevel 334) [x86_64-linux]

lumberg-1.0.0

linode-0.6.3

on a 4gb box running centos5.6 with cpanel

initially i was getting these errors:

/scripts/rebuildlinodezones:8:in `require': no such file to load -- lumberg (LoadError)

but then by running this:````
export RUBYOPT=rubygems

i got past that and then stuck at````
/scripts/rebuildlinodezones:36:in `[]': Symbol as array index (TypeError)
    from /scripts/rebuildlinodezones:36
    from /scripts/rebuildlinodezones:30:in `each'
    from /scripts/rebuildlinodezones:30

does anyone have any updated version that works with current versions of the gems?

Hi,

I have gone through all of these setup steps but unfortunately nothing gets updated in the Linode DNS when I create a new account in WHM.

I've gone over everything several times just to check but nothing stands out. I don't see any errors when I add a new account either.

When you insert the WHM Remote Access Key do you remove the returns after each line so its one long string?

The only other thing of note is when I look at Ruby in WHM (Software >> Module Installers >> Ruby) i see > !!!! At this time Rails 3.0 is not supported and can cause a broken ruby/rails environment. !!!! .

OS Centos 5.6

ruby 1.8.7

Rails 2.3.12

linode 0.7.5

lumberg 1.0.0

Is there a way to test the script?

Many thanks,

Kevin

Got it!!

I ran /scripts/rebuildlinodezones SSH and found this -

/scripts/rebuildlinodezones:8:in `require': no such file to load -- lumberg (LoadError)

So I applied anthonysomerset's fix

export RUBYOPT=rubygems

and it now works!

I wonder if you may ever update this to include Deletes and Edits?

Reply

Please enter an answer
Tips:

You can mention users to notify them: @username

You can use Markdown to format your question. For more examples see the Markdown Cheatsheet.

> I’m a blockquote.

I’m a blockquote.

[I'm a link] (https://www.google.com)

I'm a link

**I am bold** I am bold

*I am italicized* I am italicized

Community Code of Conduct