1. DDNS应用场景

    一个平台有一组MYSQL集群服务器,该组服务器通过域名解析进行提供服务。如果其中一台服务器宕机,可以通过DDNS将其中出现故障的服务器踢出该集群,避免访问到该台服务器的用户受到影响;当该集群的平均负载过高,可以自动从备用的机器中,拉出一台机器,添加到该集群,降低该集群的负载。

  2. dnspython

    dnspython 是python的一个DNS工具包。它支持几乎所有的记录类型。它可以用于查询、区域转移和动态更新。它支持TSIG验证信息和ENDS0.

    我主要用到它的动态更新功能,给大家分享一下动态更新功能。


  3. 安装和配置bind   

   1. 安装bind
      yum install bind
   2. 配置bind
      vim   /etc/named.conf
      options {
            directory "/var/named";
            statistics-file "/var/named/stats";
            listen-on port 53 { 127.0.0.1; 10.58.102.198; };
      };

      zone "." IN {
            type hint;
            file "named.ca";
       };

       zone "localhost" IN {
            type master;
            file "localhost.zone";
        };
        
        #此段密钥是通过dnssec-kengen  进行生成
        key "davidddns" {
	    algorithm  hmac-md5;
	    secret "xcj4wgrtSwkXlHOKTlozvw==";
        };

        zone "david.com" IN {
            type master;
            file "david.com.zone";
            allow-update { key davidddns; };
        };

        zone "0.0.127.in-addr.arpa" IN {
            type master;
            file "named.local";
        };

        zone "10.in-addr.arpa" IN{
            type master;
            file "david.local";
            allow-update { key davidddns; };
        };

        #通过rndc-kengen 生成
# Use with the following in named.conf, adjusting the allow list as needed:

        key "rndc-key" {
	    algorithm hmac-md5;
	    secret "v4goHeKLu3V/rqzEID5Vnw==";
        };

        controls {
	    inet 10.58.102.98 port 953
	    allow { any; } keys { "rndc-key"; };
        };
# End of named.conf

      3.配置zone
        vim /var/named/david.com.zone
 
          $ORIGIN .
          $TTL 600	; 10 minutes
          david.com		IN SOA	ns.david.com. admin.david.com. (
				2014052103 ; serial
				3600       ; refresh (1 hour)
				600        ; retry (10 minutes)
				86400      ; expire (1 day)
				604800     ; minimum (1 week)
				)
			NS	ns.david.com.
			NS	ns2.david.com.
          $ORIGIN david.com.
          ns			A	10.58.102.198
          ns2			A	10.58.102.199
          www			A	10.58.102.198
          
      4. 使用rndc管理bind
         rndc-config > /etc/rndc.key    
         将该文件的key和controls复制到named.conf文件,具体内容看上面配置文件(named.conf)
         
      5. 使用dnssec-kengen 生成密钥文件
         dnssec-kengen -a HMAC-MD5 -b 128 -n USER davidddns
           -a HMAC-MD5:采用HMAC-MD5加密算法
           -b 128: 生成的密钥长度为128位
           -n USER davidddns: 密钥的用户名为davidddns
          
          该命令会在/var/named目录下生成两个密钥文件,Kdavidddns.+157+50923.key 和 Kdavidddns.+157+50923.private
          
          然后将密钥的key复制到named.conf,详细内容请看如上named.conf配置文件
          
      6.修改权限
          chown -R named:named /var/named/
          chown named:named /etc/named.conf
          
      7.启动服务
          service named  restart

4.安装dnspython

  pip install dnspython


5.使用dnspython自动更新david.com 记录 

#!/usr/local/bin/python2.7

from optparse import OptionParser
import dns.tsigkeyring
import dns.update
import dns.query 

SERVER_IP='10.58.102.198'

def opt():
    parser = OptionParser(usage="usage: %prog [options] [comm1 comm2]")
    parser.add_option('-a','--Action',
            dest="Action",
            action="store",
            default="add",
            help="Action.")
    parser.add_option("-z","--zone",
            dest="zone",
            action="store",
            default="david.com",
            help="domain zone name.")
    parser.add_option("-n","--name",
            dest="name",
            action="store",
            default="www",
            help="Host name.")
    parser.add_option("-t","--ttl",
            dest="ttl",
            action="store",
            default="21600",
            help="TTL times.")
    parser.add_option("-T","--type",
            dest="type",
            action="store",
            default="A",
            help="Record exmple:A MX TXT NS")
    parser.add_option("-i","--ipaddr",
            dest="ipaddr",
            action="store",
            default="127.0.0.1",
            help="Client IP addr.")
    return parser.parse_args()

def up():
    opts, args = opt()
    ttl = opts.ttl
    zone = opts.zone
    type = opts.type
    ip = opts.ipaddr
    name = opts.name
    action = opts.Action
    
    try:
        #davidddns 是在dns配置文件的davidddns
        #key 是dns配置文件的key
        keyring = dns.tsigkeyring.from_text({'davidddns':'xcj4wgrtSwkXlHOKTlozvw=='})
    	up = dns.update.Update(zone, keyring=keyring)
	
	if action == 'add':
	    up.add(name, ttl, type, ip)
	    dns.query.tcp(up, SERVER_IP)
	elif action == 'delete':
	    up.delete(name)
            dns.query.tcp(up, SERVER_IP)
    except err:
        print err


if __name__ == "__main__":
    up()

6.测试

  > 查看帮助

   wKioL1N9TueyG2TQAAHCFVhm4hQ907.jpg

  > 添加一条记录

   wKiom1N9T6XxEcYFAAP4d6x1KGA577.jpg > 删除一条记录

 wKiom1N9UCbD8AURAANl7k16Dz4713.jpg


  dnspython 是一个很强大的类库,还有其它更加强大的功能。可以结合自己的线上业务进行使用!