工作,学习,生活,这里将会有一些记录. 备用域名:http://meisw.wdlinux.cn 注册 | 登陆
浏览模式: 标准 | 列表分类:dns

dnsmasq

dnsmasq劫持域名IP

bogus-nxdomain=1.2.3.4
bogus-nxdomain=5.6.7.8

//为相应的IP地址

 

Bind中的SOA记录详解

Bind的SOA记录:每个Zone仅有一个SOA记录。SOA记录包括Zone的名字,一个技术联系人和各种不同的超时值。例子:

$TTL 3600
$ORIGIN texiangbao.com.cn.
@ IN SOA dns.qqdns.com. domainadmin.dnspod.com.(
1247134024 ;Serial
3600 ; Refresh ( seconds )
1800 ; Retry ( seconds )
1209600 ; Expire ( seconds )
3600 );Minimum TTL for Zone ( seconds )
;
@ IN NS dns.qqdns.com.
@ IN NS dns.ggdns.com.
www 3600 IN A 63.220.7.134
www 3600 IN A 63.220.7.134
;
;generated @ 2009-07-09 18:07:12
;end

* #Serial 
数值Serial代表这个Zone的序列号作用:供Slave DNS判断是否从Master DNS获取新数据。每次Zone文件更新,都需要修改Serial数值。RFC1912 2.2建议的格式为YYYYMMDDnn 其中nn为修订号;
* #Refresh
数值Refresh设置Slave DNS多长时间与Master Server进行Serial核对。目前Bind的notify参数可设置每次Master DNS更新都会主动通知Slave DNS更新,Refresh参数主要用于notify参数关闭时;
* #Retry
数值Retry设置当Slave DNS试图获取Master DNS Serial时,如果Master DNS未响应,多长时间重新进行检查;
* #Expire
数值Expire将决定Slave DNS在没有Master DNS的情况下权威地提供域名解析服务的时间长短;
* #Minimum
在8.2版本之前,由于没有独立的 $TTL 指令,所以通过 SOA 最后一个字段来实现。但由于 BIND 8.2 后出现了 $TTL 指令,该部分功能就不再由 SOA 的最后一个字段来负责,由 $TTL 全权负责,SOA 的最后一个字段专门负责 negative answer ttl(negative caching)
The last field in the SOA is the negative caching TTL. This controls how long other servers will cache no-such-domain(NXDOMAIN)responses from you.

 

 

管理授权记录区域以服务器授权机构的概念为基础。

 
当 DNS 服务器配置成加载区域时,它使用两种资源记录来确定区域的授权属性
首先,起始授权机构 (SOA) 资源记录指明区域的源名称,并包含作为区域信息主要来源的服务器的名称。它还表示该区域的其他基本属性。 
其次,名称服务器 (NS) 资源记录用于标记被指定为区域权威服务器的 DNS 服务器。通过在 NS RR 中列出服务器,其他服务器就认为它是该区域的权威服务器。这意味着在 NS RR 中指定的任何服务器都被其他服务器当作权威的来源,并且能肯定应答区域内所含名称的查询。 
SOA 和 NS 资源记录在区域配置中具有特殊作用。他们是任何区域都需要的记录并且一般是文件中列出的第一个资源记录。在默认情况下,使用 DNS 控制台来添加新的主要区域时,“新建区域向导”会自动创建这些记录。
SOA 资源记录
起始授权机构 (SOA) 资源记录总是处于任何标准区域中的第一位。它表示最初创建它的 DNS 服务器或现在是该区域的主服务器的 DNS 服务器。它还用于存储会影响区域更新或过期的其他属性,如版本信息和计时。这些属性会影响在该区域的权威服务器之间进行区域传输的频繁程度
SOA 资源记录包含以下信息:
字段 描述 
主服务器(所有者) 区域的主 DNS 服务器的主机名。 
负责人 管理区域的负责人的电子邮件地址。在该电子邮件名称中使用英文句点 (.) 代替“at”符号 (@)。 
序列号 该区域文件的修订版本号。每次区域中的资源记录改变时,这个数字便会增加。每次区域改变时增加这个值非常重要,它使部分区域改动或完全修改的区域都可以在后续传送中复制到其他辅助服务器上。 
刷新间隔 以秒计算的时间,它是在查询区域的来源以进行区域更新之前辅助 DNS 服务器等待的时间。当刷新间隔到期时,辅助 DNS 服务器请求来自响应请求的源服务器的区域当前 SOA 记录副本。然后,辅助 DNS 服务器将源服务器的当前 SOA 记录(如响应中所示)的序列号与其本地 SOA 记录的序列号相比较。如果二者不同,则辅助 DNS 服务器从主要 DNS 服务器请求区域传输。这个域的默认时间是 900 秒(15 分钟)。 
重试间隔 以秒计算的时间,是辅助服务器在重试失败的区域传输之前等待的时间。通常,这个时间短于刷新间隔。该默认值为 600 秒(10 分钟)。 
到期间隔 以秒计算的时间,是在区域没有刷新或更新的已过去的刷新间隔之后、辅助服务器停止响应查询之前的时间。因为在这个时间到期,因此辅助服务器必须把它的本地数据当作不可靠数据。默认值是 86,400 秒(24 小时)。 
最小(默认)TTL 区域的默认存在时间 (TTL) 和缓存否定应答名称查询的最大间隔。该默认值为 3,600 秒(1 小时)。
以下是一个默认的 SOA 资源记录的例子:

@ IN SOA nameserver.example.microsoft.com. postmaster.example.microsoft.com. (
1 ; serial number
3600 ; refresh [1h]
600 ; retry [10m]
86400 ; expire [1d]
3600 ) ; min TTL [1h]
如上所述的 SOA 记录的例子中,区域的主要或源服务器显示为 nameserver.example.microsoft.com。有关区域问题的联系人电子邮件地址为 postmaster.example.microsoft.com。
注意
在区域中写入和存储 DNS 域名时,使用英文句点代表电子邮件地址。在电子邮件应用程序中,以前例子中的地址很可能是这种形式:postmaster@example.microsoft.com 
在 SOA 资源记录中使用的括号出现在区域文件中时,用于允许记录能自动换行为多行文本。 
如果一个单独的 TTL 值被指派并应用于在区域中使用的指定资源记录,那么它将覆盖在 SOA 记录中设置的最小(默认) TTL。 
NS 资源记录
可按以下两种方式使用名称服务器 (NS) 资源记录,将授权机构指派给 DNS 域名的指定服务器: 
通过建立域的权威服务器列表,可以使请求该域(区域)信息的其他服务器知道这些服务器。 
通过为从区域委派出去的任何子域指明权威 DNS 服务器。 
在同一区域中用主机名指派服务器的情况下,相应的地址 (A) 资源记录通常在区域中使用,以将指定服务器的名称解析为他们的 IP 地址。对于使用此 RR 作为向子域的区域委派的一部分指定的服务器,NS 资源记录通常包含区域以外的名称。对于要解析的区域以外的名称,可能需要指定的区域以外服务器的 A 资源记录。当这些区域以外的 NS 和 A 记录需要用于提供委派时,被称为“粘附记录”。
说明: 将“所有者”中指定的 DNS 域名映射到在 name_server_domain_name 域中指定的运行 DNS 服务器的主机名。 
语法: owner ttl IN NS name_server_domain_name 
例如:

dnsmasq

yum install -y dnsmasq


echo 'addn-hosts=/etc/wdcdn.hosts' >> /etc/dnsmasq.conf

/etc/rc.d/init.d/dnsmasq start

 

 

 

 

 

 

一般说到dns,都会想到bind,bind虽然强大,但太复杂了,配置起来很头疼。用牛刀杀鸡倒不是鸡不死,而是怕那刀砍伤脚。dnsmasq这个小程序,使用上比dns始祖bind要简便得多,可以做正向dns代理,也可以直接做内部纯dns服务器用。

在debian/ubuntu下安装
apt-get install dnsmasq

配置
vi /etc/dnsmasq.conf
默认配置下,dnsmasq使用系统的/etc/resolv.conf并读取/etc/hosts,在配置里可以更改或者关闭,现在是修改了这两个,
其它的按默认:
resolv-file=/etc/dnsmasq.resolv.conf
addn-hosts=/etc/dnsmasq.hosts

(dnsmasq还支持dhcp服务,但一般不用搭理)

dnsmasq可以用hosts文件来设置域名:
例:test.sudone.com是不存在的域名,我在dnsmasq中指向到一个ip里:
echo "64.233.189.99 test.sudone.com" > /etc/dnsmasq.hosts
改完要重启
/etc/init.d/dnsmasq restart

做完之后,只要把本机dns指到dnsmasq的机器,就可以ping到test.sudone.com这个域名。

 

-----------------------

注意要记录查询的日志需要在配置文件里写

log-facility=/var/log/dnsmasq.log
log-queries

 

 


25
26
27
28
29
30
31
32
33
34
35
36
37
#
# Configuration file for dnsmasq acting as a caching nameserver.
#
# Format is one option per line, legal options are the same
# as the long options legal on the command line. See
# "/usr/sbin/dnsmasq --help" or "man 8 dnsmasq" for details.
#
# Updated versions of this configuration file may be available at:
#
#   http://www.g-loaded.eu/2010/09/18/caching-nameserver-using-dnsmasq/
#
#
# Basic server configuration
#
listen-address=127.0.0.1
port=53
bind-interfaces
user=dnsmasq
group=dnsmasq
pid-file=/var/run/dnsmasq.pid
#
# Logging
#
#log-facility=/var/log/dnsmasq.log
#log-queries
#
# Name resolution options
#
domain-needed
bogus-priv
no-hosts
dns-forward-max=150
cache-size=1000
#no-negcache
neg-ttl=3600
resolv-file=/etc/resolv.dnsmasq
no-poll

 

 

dns,bind

一、DNS常识
1、DNS查询:分为递归查询和迭代查询两种
  (1) 递归查询: 即客户端向本地DNS服务器请求查询域名,本地DNS服务器收到查询任务后如自身无法回答则向其他服务器查询,直到查到结果后返回结果给客户端。期间DNS服务器可能要查询很多其他DNS服务器。
(2)迭代查询:即客户端向本地服务器请求查询域名,本地DNS服务器无法回答,则给客户端返回另一个能查询域名的服务器地址,客户端再向另一服务器查询,期间可能客户端需查询多个DNS服务器,最终查到结果。

2、DNS服务器分类:

DNS服务器分为:
(1)master(主DNS服务器):拥有区域数据的文件,并对整个区域数据进行管理。
(2)slave(从服务器或叫辅助服务器):拥有主DNS服力器的区域文件的副 本,辅助主DNS服务器对客户端进行解析,当主DNS服务器坏了后,可以完全接替主服务器的工作。
(3)forward:将任何查询请求都转发给其他服务器。起到一个代理的作用。
(4)cache:缓存服务器。
(4)hint:根DNS internet服务器集。

 

【主机名或域名】ttl] [calss] [type] [orgin] [mail] 
主机名或域名:一般 用@代替。每个区域都有自已的SOA记录,此处的为指定的域名。用@表示当前的源,也可以手工指定域名。
ttl:通常省略
class:类别,SOA记录的类别对internet乖哦说缺省为IN
type:类型,SOA记录的类型就是SOA,指明哪个DNS服务器对这个区域有授权。
origin:域区文件资 源,这个域区文件源就是这个域主DNS服务器的主机名,注意这里要求是完整的主机名,后面一定要加上“."。上例中:www.29zjt.com.  而不是www.29zjt.com  如果没有加后面的点,结果将是:www.29zjt.com.29zjt.com
mail:一般指管理员的邮箱。但和一般 的邮箱不同,用"."代替了"@",尾部也 要加上“."


       2009121001  //作为版本控制,当域区文件修改时,序号就增加,辅助服务器对比发现与自已的不同后,就会做出更新,与主服力器同步
       28800  //辅助服务器与主服务器进行更新的等待时间。间隔多久与主服务器进行更新,单位为秒。
      14400    //重试间隔。当辅助服务器请求与主服务器更新失败后,再间隔多久重试传递
       720000  //到期时间。当辅助服务器与主服务器之间刷新失败后,辅助服务器还提供多久的授 权回答。因为当与主服务器失去联系一定时间后,(这个时间就是此处定义的时间),辅助服务器会把本地数据当作不可靠的数据,将停止提供查询。
如果主服务器恢复正常,则辅助服务器重新开始计时。
       86400 )  //最小TTL,即最小有效时间,表明客户端得到的回答在多长时间内有效。如果TTL时间长,客户端缓存保存时间长,客户端在收到查询结果时开始计时(TTL)时间内有相同的查询周日不再查询服输务器,直接查自已的缓存。如果TTL时间短,则缓存更新的频率快

用BIND架设DDNS Server 提供DDNS服务

作者: abelyang <abelyang{at}twnic{dot}net{dot}tw>
version: 1.0
最后修正时间
: 2007/07/28 00:10
转载时请保持此一宣告 

1.前言
目前动态 DNS 两大主流,一个是 BIND (ISC),另一个就是套接 DB DNS PowerDNS ( mydns)
 
,两种方式各有好坏,主要是因为 BIND 会有一些复杂性,但效果非常好, PowerDNS 则是很简单
,
但相对的它不能承受大量查询,主要原因在于数据库上先天的限制. 本文主要为介绍 BIND 之动态
 
DNS
做法,而这个做法之最重要重点则在于nsupdate 这个指令及
IXFR (incremental zone transfer 
request),
是不同于传统的 AXFR (full zone transfer),IXFR 在做 Zone Transfer (DNS 的同步机制
)
 
,会以差异化的部份进行同步, AXFR 则是以整个 Zone 进行同步.DDNS 主要由 RFC 2136 构成
,
建议若您要对 DDNS 有一定深入的了解,可以阅读这篇 RFC 以了解更多重要的信息

(1034 1035 1995
2136 的基础)

本文适用于对 DNS 巳有一定了解的朋友,若是不甚清楚建议您可先参考 TWNIC 所做的讲义:
http://dns-learning.twnic.net.tw/DNS94/ 

如果你想对 nsupdate + key 的方法有更深入的了解可以参考
http://www.study-area.org/tips/tipsfr1.htm
或参考 isc bind 的文件有最详细的解说
http://www.isc.org/sw/bind/arm93/Bv9ARM.pdf
本文不讨论 view 的情形,若是 view 情形您必需从 view match-client 去更新或是使用不同
key,所以建议您多参考 isb bind 的文件,虽然辛苦些,但数据绝对是最官方最正确的


2.
必要的信息及知识
本文的范例以 Shell Script 做成,重点在于原理,采用什么工具或做法完全视您个人的能力.以下
就一些重点进行说明.

2.1 BIND 动态更新
基本上在 BIND8,BIND9 都是支持 nsupdate ,但这里面要注意的是 BIND8 8.3.X 后才支援 
IXFR,
BIND9 则都支持,所以若您的 Server 8.3.0 前的版本,那就不建议了,更何况这个以

前的版本多多少少都有许多安全性的问题.

2.1.1 nsupdate: 
bind
要开 allow-update 选项,让你的程序可以来执行更新指令,allow-update 选项可以是 IP
 
key,
而本文仅就 IP进行介绍,若用 Key 对有些朋友来说可能会变得稍复杂些了

# named.conf
#
其它略

zone "dyndns.twnic.tw" {
 type master;
 file "dyndns.twnic.tw";
 allow-update {127.0.0.1;};    #
开放 127.0.0.1 进行动态更新 
 allow-transfer { slave_ip;127.0.0.1;};  # slave
主机,可能一部或多部,若无请写
none
};


以上是开放让 127.0.0.1 进行动态更新,动态更新有其指令,详细您可看看 nsupdate man page 
(man nsupdate),
以下仅以最常用的进行说明:

#nsupdate
[root@eai1 dyndns]# nsupdate
> server 127.0.0.1
> zone dyndns.twnic.tw
> update delete user1.dyndns.twnic.tw A 211.72.210.249
> update add user1.dyndns.twnic.tw A 211.72.210.251
ttl 'A': not a valid number  #
这个例子是错误示范,加一笔记录要有 TTL

> update add user1.dyndns.twnic.tw 60 A 211.72.210.251
> show
Outgoing update query:
;; ->>HEADER<<- opcode: UPDATE, status: NOERROR, id:      0
;; flags: ; ZONE: 0, PREREQ: 0, UPDATE: 0, ADDITIONAL: 0
;; UPDATE SECTION:
user1.dyndns.twnic.tw.  0       NONE    A       211.72.210.249
user1.dyndns.twnic.tw.  60      IN      A       211.72.210.251

> send
> quit


server 
指向某一台 NameServer 进行 update 操作
zone   
修改某个 zone file
update delete 
进行 update delete 动作,这个指令格式是

        update delete FQDN TYPE RDATA,
如果有多笔相同的 A
       
记录或不同的 MX 记录要删除某一笔需将 RDATA 补上
,
       
若没有 RDATA 则表示这个 FQDN 的这个 TYPE 都要删除

        (TYPE
即是 A,MX,PTR,SOA,NS..,RDATA 就是 TYPE
       
接的东西, A RDATA IP MX RDATA
       
先权 FQDN)
update add    
进行记录的增加,操作如同 delete, 但是一定要有

        TTL
,且必需明确写出 RDATA
show   
这只是操作后要显示进行了那些 update 指令

send   
这个代表要把整个 update 指令送给 server,操作 update
       
时数据不是马上送出的,所以 update 可以很多行,最后

        nsupdate
看到 send ,才会将整个所有 update 送出,
       
update 使用 port 53/udp 若送出的数据量
(DNS packet)
       
大于 512 bytes,则会 truncate 而改使用 53/tcp,这是您

       
需要注意的地方,而只要您有 send, SOA 记录的 serial
       
会自动加1,以期让 slave 来进行同步,所以过多的 send

       
能造成过多的 traffic

2.1.2 zone file 及日志文件 
如果您进行了 nsupdate 的操作,则原来 directory 所指的目录将会产生一些日志文件,这个日志文件即为
 
zone_name.jnl (directory
习惯上都设在 /var/named , 您自己必要注意 named 程序要有写入的权限
,
chroot
状况等)

# 显示 dyndns.twnic.tw zone file 内容
[root@eai1 named]# cat /var/named/dyndns.twnic.tw
$TTL 86400      ; 1 day
@         IN SOA  twnic.net.tw. snw.twnic.net.tw. (
                                2006073267 ; serial
                                7200       ; refresh (2 hours)
                                1800       ; retry (30 minutes)
                                2419000    ; expire (3 weeks 6 days 23 hours 56 minutes 40 seconds)
                                300        ; minimum (5 minutes)
                                )
                        NS      ns2.dyndns.twnic.tw.
                        NS      eai1.twnic.tw.
ns2                     A       203.73.24.204
;
如果别人在查询时,我们有这个记录则响应这个记录的 IP,若没有这个记录代表
;
这个网站没有上线,所以此时我们可以建立一笔 wildcard 记录,指向自己的说
;
明网站,以供 user 识别这个网站没有上线,而这笔 wildcard 的记录 TTL 时间
;
不能太长,以免别的 DNS Cache 了这资料
*                 0    A       211.72.210.251

# 目录里的东西
[root@eai1 named]# ls -la /var/named/
总计 128
drwxr-xr-x    2 named    named        4096  7
27 09:25 .
drwxr-xr-x   20 root     root         4096  3
13 16:50 ..
-rw-r--r--    1 named    named         451  7
27 09:25 dyndns.twnic.tw
-rw-r--r--    1 named    named      104177  7
27 10:01 dyndns.twnic.tw.jnl
-rw-r--r--    1 named    named         195  7
  4  2001 localhost.zone
-rw-r--r--    1 named    named        2851 10
17  2003 named.ca

我们可以看到这个 .jnl 的产生,这个 .jnl 档是不能随便删除,因为它等于是 dyndns.twnic.tw 的补
充数据,而这些补充资料在 DNS reload/restart , named 还会在把它读进来,所以动态更新后的数据,
并不会随着 dns 重启后而消失,如果你想让现在整个 zone 文件出现所有的记录,那可以 rndc stop 来停止
 
dns,
此时 named 会把 .jnl数据写入原来的 zone file,不过这种方式一般来说较不建议,因为我们的
zone
 file
只要存一个样版 (template),其它的东西都是临时性的. 而若你想知道现在整个 zone 的内容,在可

以做 zone transfer 的主机上(如上例为 slave_ip 127.0.0.1), dig 指令来执行 axfr:

[root@eai1 dyndns]# dig @127.0.0.1 dyndns.twnic.tw axfr

; <<>> DiG 9.3.0 <<>> @127.0.0.1 dyndns.twnic.tw axfr
;; global options:  printcmd
dyndns.twnic.tw.        86400   IN      SOA     twnic.net.tw. snw.twnic.net.tw. 2006073528 7200 1800 2419000 300
dyndns.twnic.tw.        86400   IN      NS      ns2.dyndns.twnic.tw.
dyndns.twnic.tw.        86400   IN      NS      eai1.twnic.tw.
*.dyndns.twnic.tw.      0      IN      A       211.72.210.251
ns2.dyndns.twnic.tw.    86400   IN      A       203.73.24.204
user1.dyndns.twnic.tw.  60      IN      A       211.72.210.248
user1.dyndns.twnic.tw.  60      IN      MX      10 user1.dyndns.twnic.tw.
#
以下略

...

2.设定 NameServer 仅进行差异化的同步 
Master/Slave
要进行 zone file 的同步, ddns server 若只有一部是可以不用考虑这些问题的,但是若有两

部以上的 DNS Server, 就需要考虑到同步的进行方式, zone file 的总数据量小,采用什么同步方式是无所
谓的,但若数据量多,或是经常处在变动状况,那差异化的同步就会显得很重要,因为它可以让所有的 DNS 在短时
间内全部同步完成,BIND 支持 IXFR ,其预设即是采用 IXFR, 若没有 IXFR (update) ,则采用 AXFR,所以不
需要对 IXFR 进行额外设定,但为使大家了解其参数,本处还是举例来进行说明,好让大家能够更了解


# master DNS's named.conf
key "rndc-key" {
        algorithm hmac-md5;
        secret "HpXtFRFdLaRPFjpZokIwusyezyyRNjxhcafCfmktWNyGkDFzHAXlpTZQtVLc";
};

controls {
        inet 127.0.0.1 port 953
                allow { 127.0.0.1; } keys { "rndc-key"; };
};

options {
        directory "/var/named";
        pid-file "/var/run/named/named.pid";
        allow-transfer { none; };
        provide-ixfr yes;   #
提供 slave 主机以 IXFR 同步
,default yes
        request-ixfr yes;   # slave
IXFR master 进行同步
,default yes
 recursion no;       #
不允许递归查询

};
zone "0.0.127.in-addr.arpa" {
        type master;
        file "named.local";
};
zone "." {
        type hint;
        file "named.ca";
};
zone "dyndns.twnic.tw" {
        type master;
        file "dyndns.twnic.tw";
        max-journal-size 500k;                      #
设定日志文件大小
        allow-transfer { 203.73.24.204;127.0.0.1;}; #
可做 ixfr/axfr 的来源 IP,必需写上 slave,
                                                    # 127.0.0.1
是方使我们自己查看 zone file 现况

        also-notify {203.73.24.205;211.72.210.251}; #
额外的同步主机,这可能是 hot site 备份主机
        allow-update { 127.0.0.1;};                 #
允许动态更新的来源
};


上述的东西相信只要对 BIND DNS 有一定了解的朋友应该都是没有问题的,较不常出现的项目我都加上了的批注以利
大家了解, slave 的设法都同于 master, 只有在 zone 的部份稍有不同:

# slave DNS's named.conf
#
其它设定皆同上,只有 zone ...稍有不同,同于一般的 slave zone,不需要再开
allow-update (default none)
zone "dyndns.twnic.tw" {
        type slave;
        masters {211.72.210.249;};
        file "dyndns.twnic.tw";
        allow-transfer { none;};
};


所以从上述我们可以知道 DDNS for Master/Slave 您只要对 master 进行 update,每次的 update 送出 (send) 
会使该zone 的序号加一,只要 zone 有更新 , dns 会送出 notify 讯息给所有的 NS 主机(NS 记录上所列的名称

服务器),及可能的 also-notify 对象,使 slave 主机知道要进行同步,同步时优先采用 IXFR, master 不支持 
IXFR
则改使用 AXFR,以达到即使更新,及时同步的效果


此外,有些做 DDNS 的公司可能对 IXFR 不了解,而是把所有的 zone type 都设成了 MASTER,然后对这些 NameServer
进行 nsupdate , 这种做法也是可以的,不过中间若漏了一步或那一台少做了一件事,那两边的资料就会不一致,导致

可能同一个名称会有不同的解析结果 (例如 gnway.net 做法)

--------------------------------------------------------------------------------
 abel
回复于:2006-07-28 14:52:21

3. DDNS 的前端及后台控制范例 
说是范例主要是让大家参考原理,并没有必要一定都用我的方式,只要前面讲的东西您可以了解,程控的部份

仅是末节,以下仅列出我所用的方式供大家参考

3.1 MYSQL table
主要由三个表构成,分别为 RR (Resource Record), RR_LOG (旧资料,建议您依状况适当保存),USER (user 认证)

CREATE TABLE RR (
  SN int(20) NOT NULL auto_increment,
  USERNAME varchar(64) NOT NULL default '',
  FQDN varchar(64) NOT NULL default '',
  TTL int(5) NOT NULL default '60',
  TYPE varchar(10) NOT NULL default '',
  RDATA varchar(64) NOT NULL default '',
  CREATE_TIME timestamp(14) NOT NULL,
  PRIMARY KEY  (SN),
  KEY USERNAME (USERNAME),
  KEY FQDN (FQDN),
  KEY TTL (TTL),
  KEY TYPE (TYPE),
  KEY CREATE_TIME (CREATE_TIME)
) TYPE=MyISAM;

--
-- Table structure for table 'RR_LOG'
--

CREATE TABLE RR_LOG (
  SN int(20) NOT NULL default '0',
  USERNAME varchar(64) NOT NULL default '',
  FQDN varchar(64) NOT NULL default '',
  TTL int(5) NOT NULL default '60',
  TYPE varchar(10) NOT NULL default '',
  RDATA varchar(64) NOT NULL default '',
  CREATE_TIME varchar(14) default NULL,
  PRIMARY KEY  (SN),
  KEY USERNAME (USERNAME),
  KEY FQDN (FQDN),
  KEY CREATE_TIME (CREATE_TIME)
) TYPE=MyISAM;

--
-- Table structure for table 'USER'
--

CREATE TABLE USER (
  SN int(20) NOT NULL auto_increment,
  USERNAME varchar(64) NOT NULL default '',
  PASSWD varchar(64) NOT NULL default '',
  EMAIL varchar(64) NOT NULL default '',
  MEMO varchar(255) NOT NULL default '',
  PRIMARY KEY  (SN),
  UNIQUE KEY USERNAME (USERNAME)
) TYPE=MyISAM;


3.2 dyndns.cfg
设定档 
这个设定文件主要为了给 CGI 程序及产生 nsupdate 的程序 (dyndns-cron.sh) 所使用,透过 eval 方式来执行
,
以取得共同的变量

# mysql host/db/user/password
DBHOST=localhost
DBNAME=dyndns
DBUSER=UserName
DBPASS=Your_Passwd
MYSQL="mysql $DBNAME -h $DBHOST -u $DBUSER -p$DBPASS"

# dyndns domain
DOMAIN=dyndns.twnic.tw

# Master IP
DYNDNS_MASTER=127.0.0.1

# nsupdate command file
CMD_FILE=/tmp/nsupdate.cmd

# update freqency
UPD_FREQ=15

# RR valid time (seconds),default 20 mins
RR_ALIVE=1200


3.3 dyndns.cgi CGI
程序 
这个 CGI 主要用于接收 USER 端来的信息,验证通过后即为把 USERNAME.DOMAIN 数据,A/MX 及对应 IP 存入

 Table RR
,此外这个 CGI shell script 做成,可以于多数人的环境执行 (chmod 755 及目录的 CGI
行权限 ExecCGI 莫忘)

#!/bin/sh
echo -ne "Content-Type: text/html\n\n"

if [ -n "$QUERY_STRING" ];then
#
取得 QUERY_STRING,以下这个作法是危险的,因为没有检查数据的正确性就
eval
#
我的用意只在于说明作法

        eval `echo "$QUERY_STRING" | sed "s/&/;/g"`
#
读取设定文件,这个路径您需要自行调整
        eval `cat /home/abelyang/dyndns/dyndns.cfg `
        sql0="select 1 from USER where USERNAME='$LOGIN' and PASSWD='$PASSWD'"
        res=`echo $sql0 | $MYSQL `
#
如果 USER 密码正确, ${#res} 应为2,不对则为 0
        if [ ${#res} -lt 1 ];then
                echo "Login Failure"
        else
#
取得 IP, 需判断有 Proxy 存在,但是不考虑 Proxy 后是 NAT 情形

                IP=${HTTP_X_FORWARDED_FOR:-$REMOTE_ADDR}
                FQDN="$LOGIN.$DOMAIN"
#
删除上一次的登入
                sql1="delete from RR where USERNAME='$LOGIN'"
#
预设的动态更新项目为 A/MX
                sql2="insert into RR(USERNAME,FQDN,TYPE,RDATA) values('$LOGIN','$FQDN','A','$IP')"
                sql3="insert into RR(USERNAME,FQDN,TYPE,RDATA) values('$LOGIN','$FQDN','MX','10 $FQDN')"
                echo $sql1 | $MYSQL
                echo $sql2 | $MYSQL
                echo $sql3 | $MYSQL
                echo $LOGIN login success @$IP
        fi
else
#
以下只是网页的部份,我没有做 DDNS 申请,这个部份我想只要懂网页的朋友应该都会才是

        cat <<EOF
<html>
<head>
<meta http-equiv="Content-Type" content="text/html; charset=big5" />
<link rel="stylesheet" href="./style1.css">
</head>
<body>
<BR><BR><center>
<form>
<h3>Abel Dyndns Demo </h3>
Login:<input type=text name=LOGIN ><BR>
Passwd:<input type=password name=PASSWD><BR>
<input type=submit values="Start DynDNS">
</form>
<BR></center>
</body>
</html>

EOF


fi

3.4 dyndns-cron.sh 定时产生 nsupdate 
这只程序主要进行读取 Table RR , 并产生 nsupdate 所需要的指令格式后执行 nsupdate, 程序预设

15秒执行一次(参数如上 dyndns.cfg 中的 UPD_FREQ 更新频率),您可以拿掉 while [ 1 ] 的循环,
改用 crontab 方式来跑,不过这样就较不容易控制一分钟以内的更新频率了,最后,这个程序会把
SOA 
的序号改成更新时间,这个时间是 UTC 的秒数(意即 1970/1/1 至今秒数, date +%s 可得), SOA

序号就可以知道最后的 update 时间,这个原理和 .com verisign 或是 dyndns 中的 dyndns.org/
noip.com
是相同的.

另外,根据 RR_VALID 参数, USER 的登录时间 小于 现在时间-RR_VALID (秒数),则该 Record 视同
离线,所以我们需要进行 delete 动作


#!/bin/sh

while [ 1 ]
do
#
您必需调整路径,放在 while loop 里是要让修改了设定档即可生效,若不要可放在 while 之外

        eval `cat /home/abelyang/dyndns/dyndns.cfg`
        cat <<EOF > $CMD_FILE
server $DYNDNS_MASTER
zone $DOMAIN
EOF

# 取得最后一次的更新时间, 多减一秒是为了预防程序的 delay
        last=`date -d "-$UPD_FREQ seconds -3 seconds" "+%Y%m%d%H%M%S"`
        now=`date "+%Y%m%d%H%M%S"`

# 取得这段时间内有上来更新的 USER,这个部份不检查 IP 不变动情形
#
主要因为 nsupdate 巳执行很快,而且 named 它自己会检查重复更新的东西
        echo "select FQDN,TTL,TYPE,RDATA from RR where CREATE_TIME between $last and $now" | $MYSQL| grep -v 'RDATA' | while read FQDN TTL TYPE RDATA RDATA2
        do

# 组出更新指令,主要为一个删除,一个增加
                echo "update delete $FQDN $TYPE $RDATA $RDATA2" >>$CMD_FILE
                echo "update add $FQDN $TTL $TYPE $RDATA $RDATA2" >>$CMD_FILE
        done

# 超过 RR_ALIVE (20分钟) 未有 login 数据则清除 DNS 记录
        last=`date -d "-$RR_ALIVE seconds" "+%Y%m%d%H%M%S"`
#
备份旧的数据,并清除过时数据 (看你自己要不要备份了)
#       echo "insert into RR_LOG select * from RR where CREATE_TIME<$last"|$MYSQL
#       echo "delete from RR where CREATE_TIME < $last" |$MYSQL

# 取得过期 (RR_ALIVE) 而未登录的列表进行删除动作,因为我们用了 wildcard (*),所以若别人连时
#
将会被指到 wildcard 所指的 IP ,而您可这个 Web Server 上做一些文章,例如 Offline 说明等
        echo "select USERNAME,FQDN,TYPE,RDATA from RR  where CREATE_TIME - $last < 0 order by USERNAME" | $MYSQL | grep -v 'USERNAME' | while read USERNAME FQDN TYPE RDATA RDATA2
        do
                echo "; delete $FQDN $TYPE $RDATA $RDATA2" >>$CMD_FILE
                echo "update delete $FQDN $TYPE $RDATA $RDATA2" >>$CMD_FILE
        done

# 自定更新 SOA, 主要是为了让序号字段为现在时间 (UTC)
        echo "update delete $DOMAIN SOA" >>$CMD_FILE
        echo "update add $DOMAIN 600 SOA ns1.dyndns.twnic.tw abelyang.eai1.twnic.tw $(date +%s) 900 60 604800 60" >>$CMD_FILE
        echo "send" >>$CMD_FILE
#
执行 nsupdate 指令

        nsupdate $CMD_FILE
#       echo "process ok"
        sleep $UPD_FREQ
done

3.5 登入及更新方法
所有的东西都准备好了后,我们就可以测试:

wget "http://eai1.twnic.tw/dyndns.cgi?LOGIN=abelyang&PASSWD=abelyang-dyndns" -O /tmp/dyndns-login-status 2>/dev/null


在最多等待15(我的默认值)的情况下,就可以更新到 DNS 中了

3.6 其它数据 
其它数据如 named.conf , dyndns.twnic.tw zone file 您都可以在前面的说明里找到,我于下面
link
放了一份所有的数据供大家参考,较不用费事 copy & paste ,但不保证下面 link 永远有效 (其中的
 
.tgz
即有所有档案的
tarball)
http://eai1.twnic.tw/example/


4. DDNS
再探讨 
如前言所言, DDNS 可以使用数据库来用 (意即我的范例中可以少掉 dyndns-cron.sh 那只),不过数据库

因其先天的状况,更据我的测试(PowerDNS), 5 万资 Record 的情况下,只能到达每秒 1000 次的查询,
而且此时尚不考虑同时有 update/delete/insert 等情形,主要因为受限于先天 DB select 速度所致

,
当然您可以透过微调或细部处理让这个数字变成1500 2000, 但都永不如 BIND 随便都可以透过每秒 
6000
次查询,当然用 DB 直接来做一定是可以且更简单的,不过安全性及抗压性 PowerDNS 是随时都会有

当掉的风险,至于用 BIND 倒是没有看过,主要是因为这种 Server 肯定是不递归(recursion no). 所以
著名的 DDNS 厂商都是用 BIND 而不用 DB 方式,因其抗压性不足而致风险过高.

此外,若我们看 dyndns.org/noip.com 的做法,可以知道他们也是用 BIND 来做,你可以查询其 SOA 的序
号即可以知道他每60秒更新一次,若是使用 DB 来做是没有必要顾虑序号问题的 (DB DB 同步方法, 
SOA
序号无关),此外您更可以查看 .com Verisign,他们的做法也是像 BIND 一样,而其以每15秒更新

频率在进行,所以若您使用 .com 的域名,变更DNS 大概只要15秒就可以同步到所有的 .com NameServer, 
而不是过去的2 (因为过去是 AXFR,现在是 IXFR),虽然Verigisn 仍不降低 NS 记录的 TTL (二天
),
但至少不会发生像过去最多会4 .com DNS 数据 Cache 才会过期的情况 (二天的更新频率+二天的

快取时间)


#
检查 .com NameServer (d.gtld-servers.net) SOA 信息来验证
[root@eai1 example]# for i in `seq 1 1000`;do dig +short @d.gtld-servers.net com soa;sleep 1;done
a.gtld-servers.net. nstld.verisign-grs.com. 1153990708 1800 900 604800 900
a.gtld-servers.net. nstld.verisign-grs.com. 1153990708 1800 900 604800 900
a.gtld-servers.net. nstld.verisign-grs.com. 1153990708 1800 900 604800 900
a.gtld-servers.net. nstld.verisign-grs.com. 1153990723 1800 900 604800 900 #
这里变更了, serial 即时间
a.gtld-servers.net. nstld.verisign-grs.com. 1153990723 1800 900 604800 900
a.gtld-servers.net. nstld.verisign-grs.com. 1153990723 1800 900 604800 900
a.gtld-servers.net. nstld.verisign-grs.com. 1153990723 1800 900 604800 900
a.gtld-servers.net. nstld.verisign-grs.com. 1153990723 1800 900 604800 900
a.gtld-servers.net. nstld.verisign-grs.com. 1153990723 1800 900 604800 900
a.gtld-servers.net. nstld.verisign-grs.com. 1153990723 1800 900 604800 900
a.gtld-servers.net. nstld.verisign-grs.com. 1153990723 1800 900 604800 900
a.gtld-servers.net. nstld.verisign-grs.com. 1153990723 1800 900 604800 900
a.gtld-servers.net. nstld.verisign-grs.com. 1153990723 1800 900 604800 900
a.gtld-servers.net. nstld.verisign-grs.com. 1153990723 1800 900 604800 900
a.gtld-servers.net. nstld.verisign-grs.com. 1153990723 1800 900 604800 900
a.gtld-servers.net. nstld.verisign-grs.com. 1153990738 1800 900 604800 900 #
变更序号
a.gtld-servers.net. nstld.verisign-grs.com. 1153990738 1800 900 604800 900
a.gtld-servers.net. nstld.verisign-grs.com. 1153990738 1800 900 604800 900

5. 结语 
我所写的 script 都是以简单的角度来出发,以供大家参考,至于用户及域名管理这个有待想要用的人自行

开发, shell script 有利于多数人阅读及了解原理,细节的东西唯有您自己做了后才更能体会.
对多数的公司来说使用 DDNS 是没有意义的,除了 Registy (.com/cn/tw/jp/hk...),或是以 DDNS 做为营

运的公司, DDNS其实是不难的,但是网络上较缺乏这方面的介绍文章,所以在此为大家介绍一下这些东西
的细节, 以利想要研究的朋友能初窥门径. 有任何意见都非常欢迎大家多多交流


:
此外,有些做 DDNS 的公司可能对 IXFR 不了解,而是把所有的 zone type 都设成了 MASTER,然后对这些
 
NameServer
进行 nsupdate , 这种做法也是可以的,不过中间若漏了一步或那一台少做了一件事,那两边

的数据就会不一致,导致可能同一个名称会有不同的解析结果 (例如 gnway.net 做法,我猜测),而像 dyndns.org
/noip.com
和花生壳(vicp.net,oray.net) 等的做法是一样的(也就是和本文所提的做法一样). 而有些

公司则使用 PowerDNS/Mydnl..等套接 DB DNS ,虽然可用,而且方式更简单,但是这些 DDNS 服务肯定
无法负荷大量的查询,因为每次的 dns 查询会在其内产生 N 次的 Select 指令,数据库处理 select
速度肯定是比不上 dns flooding 的速度

bind 查询日志与一般启动日志分离保存

logging{
        channel query_log{
                file "/var/log/named/query.log" versions 3 size 256m;
                #severity warning;
                print-time yes;
                print-severity yes;
                print-category yes;
        };
        category queries{
                query_log;
        };

        channel default_log{
                file "/var/log/named/bind.log" versions 3 size 256m;
                #severity warning;
                print-time yes;
                print-severity yes;
                print-category yes;
        };
        category default{
                default_log;
        };
};

 

-----------------------

在日志中主要有两个概念:通道(channel)和类别(category)。通道指定了应该向哪里发送日志数据:是发送给syslog,还是写在一个文件里,或是发送给named的标准错误输出,还是发送到位存储桶(bit bucket)。类别则规定了哪些数据需要记录。下面我们主要介绍一下文件通道和类别。

在定义通道的语句中,severity是指定记录消息的级别。在bind中主要有以下几个级别(按照严重性递减的顺序):

critical
error
warning
notice
info
debug [ level ]
dynamic

定义了某个级别后,系统会记录包括该级别以及比该级别更严重的级别的所有消息。比如定义级别为error,则会记录critical和error两个级别的信息。一般情况下,我们记录到info级别就可以了。print-time是设定在日志中是否需要写入时间,print-severity是设定在日志中是否需要写入消息级别,print-category是设定在日志中是否需要写入日志类别。

category语句是指定哪一种类别的数据使用哪个或者哪几个已经定义了的通道。在bind9中类别有:

default 类别匹配所有未明确指定通道的类别,但是不匹配不属于任何类别的消息。这些不属于任何类别的消息属于下面列出的这些类别。

general 包括所有未明确分类的BIND消息。

client 处理客户端请求。

config 配置文件分析和处理。

database 同BIND内部数据库相关的消息,用来存储区数据和缓存记录。

dnssec 处理DNSSEC签名的响应。

lame-servers 发现错误授权。

network 网络操作

notify 异步区变动通知。

queries 查询日志

resolver 名字解析,包括对来自解析器的递归查询的处理。

security 认可/非认可的请求。

update 动态更新事件。

xfer-in 从远程名字服务器到本地名字服务器的区传送。

xfer-out 从本地名字服务器到远程名字服务器的区传送。

例如要记录queries消息,就可以如下配置(把以下语句添加到named.conf中就可以了):

这样服务器会在工作目录(directory语句所指定的目录,通常为:/var/named)下创建query.log这个文件,并把运行过程产生的queries消息写如到query.log文件中,如下:

Nov 28 16:04:55.516 queries: client 192.168.0.113#32770: query: dns.andy.com IN A

另外解释一下“file “query.log” versions 3 size 20m;”语句中“version”和“size”的意义:

version是指定允许同时存在多少个版本的该文件,比如指定3个版本(version 3),bind9会保存query.log、query.log0、query.log1和query.log2。

Size是指定文件大小的上限,如果只设定了size而没有设定version的话,当文件达到指定的文件大小上限时,服务器停止写入该文件。如果设定了version的话,服务器会进行循环,比如把query.log变成query.log1,query.log1变成query.log2等,然后建立一个新的query.log进行写入。

收集一些DNS IP 列表

收集一些DNS IP 列表

广州 202.96.128.166,202.96.128.86

茂名 202.103.176.22

dns扩容记

这个智能DNS也用了有两年多了,还算用得稳定。
之前配置的是主辅两台,且自动解析区分电信网通。
而且,数据是同步的。也就是说,修改了主DNS后,资源记录数据会自动同步到辅DNS上。无需手工修改。
因当时没有作详细的记录文档,也找不到。当时是参考网上的别人的文档来做成的。
所以,这两天要扩容,也就是增加几台机器。
想法是这样。
一台主,四台辅,这样,就算主有问题仍有多台辅,或一机房的主辅有问题,仍有其它机房的顶住。因为当前的两台都在同一机房,所以,是为安全着想,增加几台。也是公司业务发展的需要了。

也因一时找不到文档了。像之前搬迁那样,直接安装,将配置文件等直接拷贝过去。然后修改记录,增加NS记录
但启动后,数据不能同步,是新增的三台不行,以前的那台辅正常可以同步。
便GG了一下。看到些好笑的议论
有些人说,直接拷贝或上传,再重起
有些人说,用rsync同步,再重起
更有人说,这样做同步很懒什么的(看到这句,便想到马云先生语录里对于懒的说法,很精辟的)。


回归正题,上面说到数据不能同步,是重新启动或载入时,主的数据不能同步的其它的辅上。
因为之前的两台是,修改完主,重启,重载,就会自动同步的辅上。现在就新加的三台不行
但有个奇怪的问题。昨天装好后不行,就丢在那了,其实是忙其它的事了
后来看来看到有数据同步的记录,只是失败了。
今天早上来到一看,那些数据都同步了。但修改后,重起,重载,还是不行。奇怪了。难不成一定要他们自己想同步的时候才可以?哈哈

再继续观察和查找问题...

还有一个问题,在之前的那台辅DNS上,能看到一些新增的辅发来的同步信号。
zone domain/IN/view_any: refused notify from non-master: IP#32769
拒绝了,但怎么不是发到主DNS上,发到辅DNS这来
在新增的辅DNS上,看到的记录,是主DNS的IP
在主的DNS上,能看到若是其中两台的同步记录。


上面这些,也写了有一些天了。我的这个一主多辅的智能DNS也搞了一些天,断断续续的搞。
今天再搞,似乎一切都正常了,有点高兴和郁闷,高兴的是怎么突然就好了,郁闷的是,怎么前些天都不行。唯一的不正常,是在每台辅DNS上都会有一个类似这样的记录
zone domain/IN/view_any: refused notify from non-master: IP#32769
每台辅DNS都能收到自身或其它辅DNS的notify请求,但在配置是没有设置这个的呀。还没搞懂原因何在。先留着吧。

想想在这中间有两个关键点
一 是同步KEY设置,就是同步信号的问题
二 是IP匹配的问题,notify,transfer,match-clients 这些的IP设置

 

下面是一些文件的部分
primary
options {
        recursion no;
        listen-on { 127.0.0.1;ip;};
        allow-notify { slave ip list;};
        allow-transfer { slave ip list;};
};

include "ip_tables_tel.txt";

view "view_tele" {
key "tele" {
algorithm hmac-md5;
secret "SWrRvyqCssGsbq25CFezrg==";
};
allow-transfer { key tele; };
match-clients  { key tele;!slave ip list;TEL; };//IP前面要加!才能同步
server slave ip { keys tele; };
.
.
.

zone "." {
type hint;
file "named.root";
};

zone "0.0.127.IN-ADDR.ARPA" {
type master;
file "localhost.rev";
};

include "master/telecom.def";//电信的域名zone文件
};

//网通视图
view "view_cnc" {
..........//格式和上面一样,只是把zone文件分开
}

上面是主的文件,对于辅的文件
只需要修改notify,allo-transfer,match-clients,server,还有zone文件里的type

options {
        recursion no;
        listen-on { 127.0.0.1;ip;};
        allow-notify { primary ip;};
        allow-transfer { none;};
};
view "view_tele" {
key "tele" {
algorithm hmac-md5;
secret "SWrRvyqCssGsbq25CFezrg==";
};
allow-transfer { none; };
match-clients  { key tele;!primary ip;TEL; };
server primary ip  { keys tele; };

zone "." {
type hint;
file "named.root";
};

zone "0.0.127.IN-ADDR.ARPA" {
type master;
file "localhost.rev";
};

include "master/telecom.def";
};

Records:20123