Chinaunix首页 | 论坛 | 博客
  • 博客访问: 116884
  • 博文数量: 45
  • 博客积分: 0
  • 博客等级: 民兵
  • 技术积分: 315
  • 用 户 组: 普通用户
  • 注册时间: 2014-09-22 18:55
文章存档

2015年(45)

我的朋友

分类: LINUX

2015-08-21 12:11:02

    grep named /etc/passwd
    tail /var/log/messages
 
在众多Internet服务器当中﹐有一种服务是所有服务的基础﹐就是DNS服务.DNS可以说是一个不容易弄清楚的概念﹐尤其是其运作原理。无论如何﹐在您进一步阅读下面文章之前﹐请您先确定能正确回答如下的问题﹕ 

  什么是DNS的授权模式﹖是怎样进行的?
  请解释zone和domain的差别: 其实zone其实和domain,在概念上没有什么区别,但是zone都会对应一个zone文件。
  么是DNS正解和反解?
  什么是DNS的查询模式﹖查询过程是怎样进行的?
   忠告﹕请不必急着知道怎样设定DNS花点时间将DNS的原理弄明白非常重要﹐尤其是授权模式和查询模式的正确理解。在日后的DNS架设和管理中﹐是否能正确理解这些DNS原理﹐往往是成败的关键所在﹗ 
  探索NAMED 
  在Linux上面﹐提供DNS服务的套件是叫 bind﹐但执行服务程序名称则是named。请您确定系统上装有bind﹑bind-utils﹑以及caching-nameserver这几个套件﹐同时用chkcnofig确定named被选择为开机服务。 
  首先﹐让我们设定一个最重要的dns设定档﹐它就是/etc/named.conf.以下是对该文档的解释。
//generated by named-bootconf.pl这里是对整个DNS服务器运行状态的配置
options{ 
directory "/var/named"; 
/* 
*If there is a firewall between you and nameservers you want ;
*to talk to, you might need to uncomment the query-source ;
*directive below(指令如下). Previous versions of BIND always asked ;
*questions using port 53, but BIND 8.1 uses an unprivileged; 
*port by default. 
*/ 
//query-source address * port 53; 
}; 
 
先让我们了解这个档案上面用来做批注的符号是“//”﹐而不是一般shell script的“#”﹔另外﹐“/*”与“*/”之间则批注一整段文字.同时﹐每一个完整的设定都以“ ﹔”结尾﹐请不要少了它﹗(这是因为其实BIND是用C语言编写的,所以就可以用C语言的风格进行编写
 
上面的部份是在这个档案开头的options设定﹐首先用directory指定named的资源记录(RR-Resource Record)档案目录所在位置为﹕“/var/named”﹔也就是说﹐它会到这个目录下面寻找 DNS 记录档案。所以﹐我们在这个档案后面部份所指定的档案﹐就无需使用绝对路径了﹐但它们一定要放在这个目录下面。 
  接下来﹐有一段文字﹐如果您仔细阅读一下﹐它大致是说﹕如果您要设定的DNS服务器和client之间是隔着火墙的话﹐要将“//query-source address * port 53;”前面的批注符号“//”拿掉(当然﹐您也必须要设定好您的火墙啦)。不过﹐这只对早期的版本有影响﹐而在bind8.1之后则无需担心这个设定。 
接下来再让我们看下一段句子﹕
//a caching only nameserver config 
// 
zone "." IN {
type hint; 
file "named.ca"; 
}; 
  透过这几行﹐我们为named定义DNS系统中的根区域“.”(root zone) 的设定﹐同时它是一个internet(IN)的区域类别(class)这里还指定了root zone的服务器种类(type)为“hint”(也只有这个zone会使用这样的种类)。最后用file指定这个区域记录文件也就是为﹕“named.ca”。
  “/var/named/named.ca”档案。虽然named.ca这个档案中的‘ca’是cache的意思﹔但如果您了解DNS的运作﹐就应该知道这个暂存盘的作用﹐同时﹐为什么我们会把root zone放在这里。(嗯﹖想想看﹖尤其是查询非本机区域的时候:这里就会知道其实在这个文件中会创建一些) 
  在 root zone 后面﹐您应该还会看到如下这两段﹕ 
zone "localhost" IN { 
type master; 
file "localhost.zone"; 
allow-update { none; }; 
}; 
zone "0.0.127.in-addr.arpa" IN { 
type master; 
file "named.local"; 
allow-update { none; }; 
};
    这里是定义出关于本机名称的DNS解释﹕第一个zone是localhost的正解,zone﹐其服务器种类是master﹐记录文件名称是localhost.zone (在 /var/named 目录下面),是localhost.zone (在/var/named目录下面),但这个zone不允许客户主机(或服务器)自行更新DNS的记录(当然﹐client 主机必须能支持DNS submit功能才行)。 
    而第二个zone则是本机区域的反解zone。不过﹐这部份的解释我想留到后面的真实例子中再作说明﹐请您留意就是了。上面的句子﹐当您安装好caching-nameserver 套件之后就被建立起来的﹐相信您不用劳什么心力。在档案最后﹐您或许还看到下面这段设定﹕ 
key "key" { 
algorithm hmac-md5; 
secret "coqJswFdBMdNAItnLOpkmGgmJtccFsoNZZciWqxlGZBMUTOUxb0geYMFRyTT"; 
}; 
    现在﹐我们暂时不要修改named.conf设定档﹐请退出它﹐然后转到/var/named目录﹐最起码﹐您会看到如下三个档案﹕ 
named.ca 
localhost.zone 
named.local 
   没错,刚才在named.conf里面﹐每一个zone所指定的file都出现在这里。在/var/named中的RR(记录名)记录文件里面的批注符号﹐和/etc/named.conf的批注符号不一样。
    在上面这个named.ca档案里面﹐您如果将所有的批注行拿掉﹐您会发现一共有13行是以‘.’开头的﹐那就是所谓的root zone了﹗然后﹐第二栏都是‘ 3600000 ’﹐这是 TTL (Time To Live) 设定,也就是在cache中保留的时间,以秒为单位(所以这里是100小时)。‘NS’是“Name Server”的意思﹐是DNS记录名称之一﹐也就是负责这个记录的name server是哪一台主机(这里一共由13台主机共同负责root zone的NS服务)。 
    虽然我们这里用NS指定了name server的主机名称﹐但对计算机系统来说﹐这些名称必须能解释为IP地址才有用。所以﹐这里用13个‘A’记录﹐也就是Address的意思﹐解释 [A-M].ROOT-SERVER.NET. 这些主机各自的IP地址所在。 
    如果您了解DNS的查询模式﹐您会知道DNS服务器在查询非自己管辖的zone的时候﹐首先会向root查询下一级的zone在哪里﹐然后逐级查询下去。但问题是﹕当named刚启动的时候﹐在cache里面一片空白﹐它怎么知道root zone的servers在哪里呢﹖这不是一个矛盾吗﹖所以﹐就必须靠这个档案告诉named关于root zone的servers有哪些﹖以及在哪里﹖ 
    因为这个文件是以静态的方式维护的﹐很难保证这个档的内容永远都正确﹐如果root zone的记录发生改变了怎么办(虽然这机会不大)﹖或许﹐您已经在档案的开头批注那里得知﹐您可以在任何时候透过ftp或gopher取得这个档案的最新版本。如果您还没读过那些批注﹐那就请带着字典读一下吧。如果您真的有需要更新这个named.ca檔﹐那可以按如下步骤进行﹕ 
ftp FTP.RS.INTERNIC.NET 
anonymous (登录名
your_account@your.mail.server(登陆密码) 
cd domain 
get named.root 
bye 
cp /var/named/named.ca /var/named/named.ca.bak 
cat named.root > /var/named/named.ca 
    除了刚才的named.ca之外﹐第二个zone的记录文件是localhost.zone。从named.conf中您应该知道它是zone"localhost" 的记录文件﹐它的内容如下﹕ 

RR文件解读
$TTL 86400 (定义出这个记录文件里面的各项记录的预设TTL值为86400秒(刚好是一天
    记录文件或许没有这行﹐事实上没什么关系﹐您可以自己补上﹐否则﹐在启动 named 的时候会碰到一些警告﹐无伤大雅的﹔但如果您的确在意那些警告﹐那就加上这行
$ORIGIN localhost. (ORIGIN设定﹐说明下面的记录源出何处(这里是源出localhost.的记录))
   加倍留意最后的一个小数点“.”﹐少了它或多了它﹐记录名称完全不一样﹗在DNS记录中﹐我们称这样以小数点结尾的名称为“ 全域名称 ”即FQDN( Fully Qualified Domain Name)
 
就会将所属的 ORIGIN ( @ ) 附加在记录名称后面﹔而这 ORIGIN 就是上一个 $ORIGIN 宣告之后的名称﹐如果在前面找不到 $ORIGIN 宣告﹐那就以 /etc/named.conf 中定义的 zone 名称为基准。以目前的例子来说﹐如果没有这个小数点的话﹐“localhost”会变成“localhost.localhost”﹔但如果有小数点的话 “localhost.”就只能是“localhost.”。
@    1D IN SOA @.root 然后﹐第三行﹐是一个SOA记录的设定﹐在这里我们看到一个特殊字符“ @ ”﹐它就是ORIGIN的意思﹐也就是刚纔所定义的$ORIGIN localhost.内容﹐您可以写成localhost.也可以用@来代替。假如这个档前面没有定义$ORIGIN的话﹐那这个@的值就以named.conf里的zone为准。
    在IN之后就是这行RR的记录类别名称﹐这里是SOA﹐也就是“Start Of Authority”的意思﹐表示目前区域的授权记录开始。每一个记录文件只能有一个SOA 不得重复﹐而且必须是所负责的zone中第一个“记录”。 
    
紧接 SOA 后面﹐指定了这个区域的授权主机和管理者的信箱﹐这里分别是“@”和“root”﹐也就是localhost.主机和root信箱。这里要注意的是SOA的主机名称必须能够在DNS系统中找到一个A记录 (以后会提到)﹔另外﹐我们平时使用的信箱通常是“user@host”这样的格式﹐但因为“@”在 DNS 记录中是个保留字符(刚才已经提过)﹐所以在SOA中就用“.”来代替了“@”。目前这个信箱是root(并没有主机地址)﹐也就是本机﹐您可以写成 “root.localhost.”但不能写成“root@localhost.”。
    接下来的SOA设定﹐是被括在“( )”之间的5组数字﹐主要作为和slave服务器同步DNS数据所使用的数据﹕ 

    42 ; serial(d. adams)      Serial﹕其格式通常会是“年月日+修改次序”(但也不一定如此﹐您自己能够记得就行)。当slave要进行数据同步的时候﹐会比较这个号码。如果发现在这里的号码比它那边的数值“大”﹐就进行更新﹐否则忽略。
    3H ; refresh         Refresh﹕这里是是告诉slave要隔多久要进行数据同步(是否同步要看 Serial 的比较结果)。
    15M ; retry          Retry﹕如果slave在进行更新失败后﹐要隔多久再进行重试
    1W ; 
expiry         expire﹕这是记录逾期时间﹕当slave一直未能成功与master取得联络﹐那到这里就放弃retry﹐同时这里的数据也将标识为过期(expired)
    1D  
minimum ) ;  Minimum﹕这是最小预设 TTL 值﹐如果您在前面没有用“$TTL”来定义﹐就会以此值为准
    

上的数字都是以秒为单位﹐但您也可以用 H(小时)﹑D(天)﹑W(星期)来做单位﹐如﹕3H 和 259200 是一样的。但要值得一提的是﹕我在 RH6.2 版本中曾测试过使用 netconf 这工具来设定 DNS ﹐发现只能使用“秒”来设定。否则 netconf 会自动的把英文字母删除掉﹐那就不是我所预期的设定值了。无论您用什么单位来设定﹐都要遵守下面的规则﹕ 

expire >= refresh + retry expire >= 10 * retry 
   Tips﹕请注意﹕SOA 记录中这对 “ ( ) ”符号之第一个 “ (”括号一定要和 SOA 写在同一行﹐而不能用 Enter 断行到下一行去(有时候您在书本的范例中看到这个符号排在下一行去了﹐那是因为版面的关系而已)﹐而且其左边最好有一个空格键或 tab 建。而最后一个 “ )”括号也不能写在批注符号 “ ﹔”的右边。 

   1D IN NS @ 

    1D IN A 127.0.0.1 
    设定 DNS 的 RR 记录文件﹐其格式要求非常严格﹐我们丝毫不能掉以轻心。比方说﹕如果句子不是以空格键﹑Tab 键﹑ 或批注符号 ( ; )开头﹐也不在 SOA 的 “ ( ) ”之内﹐ 则表示要定义一个“新记录项 (Entry) 
  ”﹔如果句子是以空格键或 tab 键开始的话﹐其设定被视为上一个“记录项”的内容。所以﹐如果您要为“同一个记录项”定义多个记录设定﹐而不想重复打字﹐您倒可以偷懒﹕在接着它的后面几行用空白或 Tab 来缩排就可以了。所以﹐最后这两行还是关于 localhost. 的设定﹐因为上一个“数据项”为 “ @ ”﹐也就是 localhost. 。当然﹐您如不喜欢﹐这两行句子也可以这样写﹕ 

;; 修改前﹕ 
    1D IN NS @ 
    1D IN A 127.0.0.1 
;; 修改后﹕ 
@1D IN NS @ 
@1D IN A 127.0.0.1 
;; 或﹕ 
localhost.1D IN NS localhost. 
localhost.1D IN A 127.0.0.1 
    这两行的意思是说﹕负责 localhost. 这个记录的 name server ( NS ) 是 localhost. 这台机器﹔而 localhost. 的 IP Address ( A ) 是 127.0.0.1 。DNS 里面的 A 记录应该是最常见的记录类型之一﹐如果在 IPv6 版本中﹐地址记录名称则改为 AAAA 。 
    最后﹐让我们检查剩下的 named.local 档案吧。如果您还没忘记 /etc/named.conf 的内容的话﹐应知道这个档案是 zone "0.0.127.in-addr.arpa" 的‘反解’记录文件﹐它的内容也很简单﹕ 
$TTL 86400 
@     IN SOA localhost. root.localhost. ( 
                                                        1997022700 ; Serial 
                                                        28800 ; Refresh 
                                                        14400 ; Retry 
                                                        3600000 ; Expire 
                                                        86400 ) ; Minimum 
       IN NS localhost. 
1     IN PTR localhost. 
    最后一行我们看到一个“ PTR ”记录﹐它是“Pointer”的意思。 PTR 通常用于反记录当中﹐将 IP 指向主机名称(刚好和 A 记录相反)。您或许还不是很清楚这个句子为什么是这样设定的吧﹖或许您会这样问﹕您不是说 PTR 是从 IP 反查询主机名称的吗﹖为什么这里是 1 而不是 127.0.0.1 ? 
    我们知道 127.0.0.1 所对应的主机名称就是 localhost ﹐因为这里是反向查询﹐所以 IP 顺序是掉过来写的﹐于是这个反查询 IP 就是﹕“ 1.0.0.127.in-addr.arpa. ”﹐由于我们这里的 ORIGIN ( @ ) 是“ 0.0.127.in-addr.arpa." ”﹐因为在记录文件中﹐如果名称不带小数点﹐则被补上 $ORIGIN 或 zone 的名称﹐所以这个 “ 1 ”就成了 1.0.0.127.in-addr.arpa. ”。同样道理﹐后面的“ localhost. ”如果漏了最后的小点的话﹐则会成为“ localhost.0.0.127.in-addr.arpa. ”﹐这显然是不对的。假如您喜欢﹐可以将这行句子修改成为下面的样子﹕ 
﹔﹔修改前﹕ 
1     IN PTR localhost. 
﹔﹔修改后﹕ 
1.0.0.127.in-addr.arpa. IN PTR localhost. 
    前面所看到的设定﹐事实上已经足够让您的 DNS 主机跑起来了﹗因为它能够透过 root 查询其它 DNS 的缘故﹐您无须在再加设任何设定﹐您就可以利用这台主机为大家提供 Internet 的 DNS 查询服务。只是﹐这样的 DNS 主机﹐我们称之为 cache only name server 而已。如果您了解 DNS 的查询流程﹐您应该知道 DNS 的 cache 作用和它的效益。所以﹐就算您不打算设定自己的 domain name 服务 ﹐我也建议您至少可以将 cache only NS 跑起来。 
    设定 NAMED 

实例
     题目:如何设定自己的 domain name 服务吧。
rh71.siyongc.domain 192.168.100.23 
acer.siyongc.domain 192.168.100.20 
mdk.siyongc.domain 192.168.100.24 
emilie.siyongc.domain 192.168.100.11 
rh71.dmz.domain 10.0.1.131 
lp64.dmz.domain 10.0.1.130 
    当所有的主机名称和 IP 整理出来之后﹐再看看我们这里需要设定哪些 domain ﹖ 从上面的数据中﹐我们不难发现有两个正解 zone 和两个反解 zone 需要设定﹐分别是﹕ 
区域名称 记录项名称 
siyongc.domain emilie﹑acer﹑rh71﹑mdk 
dmz.domain lp64﹑rh71 
100.168.192.in-addr.arpa 11﹑20﹑23﹑24 
1.0.10.in-addr.arpa 130﹑131 
    因为这些 IP 和 domain 都在内部网络使用﹐所以我们省却了注册这关﹐同时也不必担心授权的问题。但这些信息也只能在内部网络使用﹐无论如何是不能设定在对外的 DNS 上面的 (为什么﹖除了安全的考虑之外﹐private IP 的使用本来就有这样的规定﹐就算您真的对外散布这些 DNS 信息﹐在 IP 的路由上还是有问题﹐所以﹐内部的信息﹐只能内部使用)。 
    一般来说﹐我会先设定“反查询区域(revers zone)”﹐当然﹐这是个人习惯而已。所以﹐我首先在 /etc/named.conf 上面补上两个反解 zone 的设定﹕ 
zone "100.168.192.in-addr.arpa" IN {// 定义反解区域名称 
type master;// 定义服务器类型 
file "192.168.100.rev";// 指定记录文件名称 
};// 结束区域设定 
zone "1.0.10.in-addr.arpa" IN { 
type master; 
file "10.0.1.rev"; 
}; 
    注意哦﹕如果您要设定外部 DNS 的反解﹐那就先获得 ISP 的授权才能自己设定﹔否则反解部份就不用自己担心了﹐但一定要请 ISP 帮忙。


(ISP许可证(Internet Service Provider),是指互联网服务提供商
    Tips﹕假如您是 hinet 的固定制 ADSL 用户﹐可以到 hinet 的网站填写表格﹐请他们帮忙设定反解﹕
/>     其它 ISP 的用户﹐请自行接洽 ISP 的客服部门。无论如何﹐如果没有取得授权﹐那就不要自己设﹗ 
    这里﹐我们再一次碰到反解区域的识别标志﹕“ .in-addr.arpa ”﹐同时﹐我们解释一下上次关于本机反解还没说明的地方﹕如果您了解 DNS 的授权和查询过程(这章一开始的时候﹐我就已要求您一定要学习的)﹐您会知道反解查询是先从 root 开始(正解也是一样)﹐然后到 arpa ﹑到 in-addr ﹑到第一组 IP ﹑到第二组 IP ﹑...... 这样查询下来的。所以﹐在设定反区域的时候﹐您一定要将您的 net ID 部份反过来写﹐例如﹕我的网络为 192.168.100.0/24﹐它的反查询区域名则是﹕“100.168.192.in-addr.arpa”﹔假如我将 netmask 改为 16 bit ﹐即变成 192.168.0.0/16﹐它的反解区域名就会变成﹕“168.192.in-addr.arpa”。如果您还搞不懂如何区分 Net ID 和 Host ID﹐请立即去看一看“学习网络”中的“IP 基础”。 
    同时﹐我将这些 zone 都设定为“主 DNS 服务器”(即﹕master﹐也有人称之为 primary dns )。 
    在每个 zone 的最后部份﹐我分别指定了它们各自的记录文件名称。它们都存放在 /var/named 这个目录下面(也就是前面 options 指定的 directory 啦)。档案的名称随您喜欢﹐不致做成混乱则可。 
    完成上面的设定之后﹐我们就可以到 /var/named 目录去建立相应的记录档案了。说实在﹐在 named.conf 里面如何定义文件名称没一定的标准﹐只要您能正确指定哪个记录文件给哪个 zone 使用﹐而且文件名称能够一致就行。首先﹐根据第一个 zone 的 file 设定﹐我要建立一个 /var/named/192.168.100.rev 档案﹐其内容如下﹕ 
$TTL 86400 
@ IN SOA rh71.siyongc.domain. root.rh71.siyongc.domain. ( 
2001111601 ; Serial

28800 ; Refresh 

14400 ; Retry 
3600000 ; Expire 
86400 ) ; Minimum 
@ IN NS rh71.siyongc.domain. 
@ IN NS lp64.dmz.domain. 
11 IN PTR emilie.siyongc.domain. 
20 IN PTR acer.siyongc.domain. 
23 IN PTR rh71.siyongc.domain. 
24 IN PTR mdk.siyongc.domain. 
而另外一个反解设定档是 /var/named/10.0.1.rev ﹐我们依样画葫芦就行了﹕ 
$TTL 86400 
@ IN SOA rh71.siyongc.domain. root.rh71.siyongc.domain. ( 
2001111601 ; Serial 
28800 ; Refresh 
14400 ; Retry 
3600000 ; Expire 
86400 ) ; Minimum 
@ IN NS rh71.siyongc.domain. 
@ IN NS lp64.dmz.domain. 
130 IN PTR lp64.dmz.domain. 
131 IN PTR rh71.dmz.domain. 
    就这样﹐反解 DNS 就设定完成了﹗是否很简单呢﹖如果您回答“ Yes ”的话﹐那就让我们继续正解区域的设定吧。同样的﹐先在 /etc/named.conf 里面加上两个 zone﹕ 
zone "siyongc.domain" IN { 
type master; 
file "siyongc.domain"; 
}; 
zone "dmz.domain" IN { 
type master; 

file "dmz.domain"; 
}; 
完成后﹐再建立 /var/named/siyongc.domain 这个档案﹕ 
$TTL 86400 
$ORIGIN siyongc.domain. 
@ IN SOA rh71.siyongc.domain. root.rh71.siyongc.domain. ( 
2001111601

 28800 

14400 

3600000 

86400 ) 
IN NS rh71.siyongc.domain. 
IN NS lp64.dmz.domain. 
IN MX 10 rh71.siyongc.domain. 
IN MX 20 lp64.dmz.domain. 
;; -- default address 
@ IN A 192.168.100.23 
;; -- linux servers -- 
rh71 IN A 192.168.100.23 
IN MX 0 rh71.siyongc.domain. 
IN MX 10 lp64.dmz.domain. 
IN HINFO "Petium II 266""Redhat 7.1" 
IN TXT "The internet gateway." 
mdk IN A 192.168.100.24 
IN MX 0 mdk.siyongc.domain. 
IN MX 10 rh71.siyongc.domain. 
IN HINFO "Petium II 266 dell""Mandrak 8.0" 
;; -- Windows desktops -- 
acer IN A 192.168.100.20 
IN MX 0 mdk.siyongc.domain. 
IN HINFO "Petium III 800 acer""Windows ME" 
emilie IN A 192.168.100.11 
IN MX 0 mdk.siyongc.domain. 
IN HINFO "Petium II 300""Windows 98" 
;; -- cnames -- 
gw IN CNAME rh71 
www IN CNAME rh71 
ftp IN CNAME rh71 
mail IN CNAME rh71 
   这里﹐我们在正解记录文件里面看到几个新的记录类别﹐或许需要进一步讲解一下的﹕ 
因为我这个区域的记录分别由两台主机负责﹐所以我这里指定了两个 NS 记录。这里﹐如果您确定上一个 ORIGIN 是正确的话﹐那也可以偷懒﹕正如我上面解释过﹐如果名称后面不是以“.”结尾的话﹐它所属的 ORIGIN ( @ ) 就会自动的加在该记录名称后面﹔所以﹐您可以只写“ rh71 ”而不带小数点结尾﹐就会变成“rh71.siyongc.domain.”了﹐这个名称实际就是我所要的。不过﹐我建议您在设定 NS 的时候还是尽量使用 FQDN 为好。 
    接下来的 ‘ MX ’ 记录恐怕要花些时间解析﹕ 
    MX 记录 
    MX 是‘Mail eXchange’的意思﹐它指定了负责该记录项(可以为 domain 也可以是 host )的邮件服务器名称(最好使用 FQDN )﹐而且该名称必须是一个 A 记录(不建议使用 CNAME )。 
    在邮件系统中﹐只要邮件服务器双方都知道对方的 IP 就可以进行邮件交换了。我们用 /etc/hosts 也可以做到名称查询的目的﹐但正如我们可以想象的﹕ineternet 有那么多邮件服务器﹐我们不可能一一为它们建立好 IP 对应。就算﹐我们可以这样做﹐如果对方要更换邮件服务器呢﹖要维护这样一个对应殊非易事。既然﹐我们可以用 DNS 来查询主机和 IP﹐为什么不使用这么便利的系统呢﹖这也是 DNS 系统的应用原因啊~~~ 但问题是﹐各区域的邮件服务器名称都不一样﹐我们不可能知道对方的邮件服务器主机名称是什么﹖就算知道﹐如果对方以后更换名称呢﹖ 

    您看﹐即使我们使用了 DNS 系统来进行邮件路由﹐也不是这么简单的事情。但是﹐使用 MX 记录就大大发挥了 DNS 系统的功能了﹕我们只要为每一个区域建立起 MX 记录﹐利用 DNS 查询得到的邮件服务器名称(邮件路由查询中﹐DNS 只是其中一种方法)﹐这样﹐当邮件服务器要和对方的区域进行邮件传递的时候﹐就可以通过 MX 记录得到对方的邮件服务器名称﹐而不需预先知道要和哪台邮件主机沟通。在日后﹐就算对方更换名称﹐将 DNS 记录改改就可以﹐完全无需知会其它邮件主机﹔而外面的邮件服务器也根本无需认知到这个改变。 
    这样的设计﹐无疑是非常灵活便利的﹗另外﹐使用 MX 还有一个功能﹕您可以用多个 MX 同时指定好几台邮件服务器名称﹐从而提供备援或平行处理服务。在我这个例子中﹐我就分别为‘siyongc.domain’这个区域指定了两个 MX 记录﹕‘rh71.siyongc.domain.’和‘lp64.dmz.domain.’。但您有没有发现它们前面都有一个数字呢﹖这数字有什么作用﹖ 
    问得好﹗当外面的邮件服务器通过 DNS 查询到我们的邮件服务器﹐如果发现超过一台主机负责邮件交换的话﹐数值越低的就越先被查询。但有时候该主机没有响应呢﹖那么就由下一个数值的主机负责了。这样有一个好处就是﹕就算第一台邮件服务器出现故障﹐也不至于导致邮件交换功能瘫痪掉。我们通常会将各自的 MX 主机尽量分布在不同的位置上(例如别的城市或国家的分公司主机)﹐假如万一发生专线﹑甚至 ISP 的问题﹐我们还能将邮件转往下一台 MX 主机。然而﹐在设计上﹐由于账号和 client 端的设定因素﹐我们的邮件并非真的完全转到下一个 MX 主机接收﹐而是先将邮件暂时队列( queue ) 在那台机器上﹐当原来的 MX 主机恢复联机之后﹐邮件会自动的从队列主机那边送回来﹐这样就能避免邮件丢失或被退信。 
    Tips﹕虽然﹐我们通常喜欢用‘10’﹑‘20’﹑‘30’.... 这样的偏好值( preference ) 来分配 MX 记录﹐但只要您喜欢﹐用‘1’﹑‘2’﹑‘3’... 这样的顺序一样可以。不过﹐我建议您还是使用惯例啦。 
    现在很多大型邮件系统﹐都可以同时使用多台邮件主机来提供邮件交换服务﹐这时候您可以将 MX 的 preference 设为相同﹐然后利用 NIS 和 NFS 服务﹐将邮件同步到相同的账号去。您已经在前面的章节里面学会了 NIS 和 NFS﹐等日后学习邮件主机架设的时候﹐不妨玩玩看﹗ 
    或许﹐您还发现我这里为所有主机指定了 MX 记录﹐有些直接指向自己(如 rh71﹑mdk 等)﹐而有些则指向别的机器(如 lp64﹑acer 等)。在 Linux 机器上面﹐各主机本身就具备邮件交换功能(除非您将之移除了)﹐而 Windows 则除非额外加装﹐否则本身是没有邮件交换功能的。这里的设定是﹐从外面通过 DNS 查询而寄往那些主机的邮件﹐都会转到 MX 上面指定的邮件服务器。这在实际的网络环境中很常见﹐尤其您接触过“ mail hub ”这个概念。无论如何﹐我建议您应该帮负责 domain 的邮件服务器本身设定一个偏好值最低的 MX 记录指向自己(但这不是硬性必须如此的)。 
    Tips﹕事实上﹐我当初对 MX 的理解一直存在着错误﹐直到有一次在新闻组上和大家讨论﹐才纠正过来。如果您对这个故事感兴趣的话﹐或是想更进一步了解 MX 的实际运作原理﹐请参考 << Sendmail 与 MX >> 一文。 
    在过去﹐有些人并不知道如何正确的运用 MX 记录﹐但相对的﹐他们会为 domain 名称本身设定一个 A 记录 (@ IN A 192.168.100.23 )。这样的做法虽然不是正统的﹐但也行之有年了。而且﹐在许多网站的 URL 上﹐这样的设定﹐也能让您少输入“ ”这四个键~~~ 
     另外﹐在这个档里面﹐您或许还发现‘ TXT ’这样的记录类别﹐它是‘Text InFORMation’的意思﹐它实际上不牵涉任何设定﹐只记录一些环境说明而已﹔这和‘ HINFO(Host InFORMation) ’差不多﹐但 HINFO 一定要有两项记录(分别用引号分开)﹐其中第一项是关于 CPU 的讯息﹐第二项则是操作系统。然而﹐TXT 和 HINFO 这些信息仅能在一个信任的环境中提供﹐如果您架设的 DNS 是对外提供服务的﹐那么﹐就不要设定这些信息了。要不然﹐入侵者可非常感谢您哦﹐因为您帮他们省却了很多主机系统的探测手续~~~ 所以﹐这里仅做范例﹐供您参考而已。 
    而最后您所看到的‘CNAME’记录又是怎样的呢﹖CNAME 也是一个常见的记录类别﹐它是一个别名记录( Canonical Name )。当 DNS 系统在查询 CNAME 左面的名称的时候﹐都会转向 CNAME 右面的名称再进行查询﹐一直追踪到最后的 PTR 或 A 名称﹐成功查询后才会做出响应﹐否则失败。例如﹐在正解查询中﹐一个 IP 通常(当然也有例外)﹐只会对应一个 A 记录﹐但我们可以使用 CNAME 在 A 名称之上赋予该 IP 更多的名称。也就是说﹕所有关于‘’﹑‘ftp.siyongc.domain’﹑ ‘mail.siyongc.domain’这些名称的查询﹐实际上都会再查询一次‘rh71.siyongc.domain.’这个记录﹐直到找到它的 IP 地址为止。有些朋友或许会设定多层的 CNAME 查询﹐例如﹕ 
C CNAME B 
B CNAME A 
    这样的话﹐会一层一层的逐级 CNAME 下去... 但是﹐这很浪费 DNS 资源﹗因为每一个 CNAME 都一定会产生另外一个查询动作﹐如果层级越多﹐那就产生越多的重复查询。所以﹐精明的 DNS 管理员﹐都会尽量的减少查询次数的发生﹐他会将 CNAME 变成这样子﹕ 
C CNAME A 
B CNAME A 
这样就用心多了﹗ 
基本上﹐我们在正解设定上所使用到的记录大概就前面所看到的。哦﹐对了~~ 还有另外一个 /var/named/dmz.domain 档案也不要忘记了﹕ 
$TTL 86400 
$ORIGIN dmz.domain. 
@ IN SOA rh71.siyongc.domain. root.rh71.siyongc.domain. ( 
2001111601 28800 14400 3600000 86400 ) 
IN NS rh71.siyongc.domain. 
IN NS lp64.dmz.domain. 
IN MX 10 rh71.dmz.domain. 
;; -- linux servers -- 
rh71 IN A 10.0.1.131 
IN MX 0 rh71.dmz.domain. 
IN HINFO "Petium II 266""Redhat 7.1" 
IN TXT "The internet gateway." 
lp64 IN A 10.0.1.130 
IN MX 0 rh71.dmz.domain. 
IN HINFO "Pentium 90""Linpus 6.4" 
;; -- cnames -- 
gw IN CNAME lp64 
www IN CNAME lp64 
ftp IN CNAME lp64 
mail IN CNAME lp64 
您看﹗就这样﹐我们的 DNS 就已经设定好了﹐包括反解和正解哦~~~ 

重新启动 named 
    当您以为所有设定档都设定好之后﹐最想做的事情莫过于要测试一下啦。但在测试之前﹐我们还要重新启动 named ﹐否则﹐您查询出来的还是旧数据。聪明的您或许已经知道使用如下命令来重新启动DNS 服务了吧﹕ 
service named restart 
    然而﹐作为一个有经验的 DNS 管理员﹐在重新启动 named 服务之后﹐他一定会检查一个档案﹐就是 /var/log/messages 。因为﹐许多时候﹐当您执行 service named restart 之后您看到的都是绿色的 OK ﹐但事实上是否真的 OK 呢﹖谁也不敢保证﹐除非您在 log 档中没发现错误信息。所以﹐我也强烈建议您每次重新启动 named 之后﹐一定一定要做如下动作﹕ 
    vi /var/log/messages 
然后按“G”键(大写)跳到档案末尾部份(事实上﹐您也可以用 tail 命令)。您或许会看到如下这样的记录﹕ 
Nov 16 14:54:10 rh71 named[2211]: starting BIND 9.1.0 -u named 
Nov 16 14:54:10 rh71 named[2211]: using 1 CPU 
Nov 16 14:54:10 rh71 named: named startup succeeded 
Nov 16 14:54:10 rh71 named[2215]: loading configuration from '/etc/named.conf' 
Nov 16 14:54:10 rh71 named[2215]: the default for the 'auth-nxdomain' option is now 'no' 
Nov 16 14:54:10 rh71 named[2215]: no IPv6 interfaces found 
Nov 16 14:54:10 rh71 named[2215]: listening on IPv4 interface lo, 127.0.0.1#53 
Nov 16 14:54:10 rh71 named[2215]: listening on IPv4 interface eth0,192.168.100.23#53 
Nov 16 14:54:10 rh71 named[2215]: listening on IPv4 interface eth1, 10.0.1.1#53 
Nov 16 14:54:10 rh71 named[2215]: listening on IPv4 interface eth2, 10.0.1.131#53 
Nov 16 14:54:10 rh71 named[2215]: listening on IPv4 interface vmnet1, 172.16.233.1#53 
Nov 16 14:54:10 rh71 named[2215]: listening on IPv4 interface vmnet8, 192.168.183.1#53 
Nov 16 14:54:10 rh71 named[2215]: listening on IPv4 interface ppp0, 211.74.244.213#53 
Nov 16 14:54:10 rh71 named[2215]: running 

上面虽然有 'auth-nxdomain' 和 IPV6 的提示﹐但那是正常的(除非您有设定相关的功能)。如果没有其它错误信息的话﹐那真要恭喜您了﹗ 
但有时候您或许会看到有其它错误信息的﹐例如﹕ 
Nov 16 15:01:49 rh71 named[2287]: loading configuration from '/etc/named.conf' 
Nov 16 15:01:49 rh71 named[2287]: /etc/named.conf:41: parse error near zone 
Nov 16 15:01:49 rh71 named[2287]: loading configuration: failure 
Nov 16 15:01:49 rh71 named[2287]: exiting (due to fatal error) 
这个错误信息明显指出了是 /etc/named.conf 的问题﹐而且很可能在 41 行附近。根据我个人的经验﹐这通常是您漏了 “ ﹔”符号的原因而已。 
    如果您碰到如下信息﹐那是没有为所有 RR 记录项设定 TTL 而已﹐您可以为每一个记录项补上 TTL (在 IN 前面)﹐也可以在记录文件的前面用 $TTL 来设定﹕ 
Nov 16 15:04:47 rh71 named[2395]: master.c:1172: unexpected error: 
Nov 16 15:04:47 rh71 named[2395]: dns_master_load: siyongc:3: no TTL specified. 
THIS ZONE WILL NO LONGER WORK IN FUTURE VERSIONS. Add a TTL. 
Nov 16 15:04:47 rh71 named[2395]: dns_master_load: siyongc:5: using 
RFC 1035 TTL semantics 
    如果您碰到下面这样的信息﹐那多是因为您打字错误的关系﹐输入了 named 不认识的记录类别名称(例如漏了记录名称或打错了)﹕ 

Nov 16 15:07:44 rh71 named[2422]: dns_master_load: siyongc:2: unknown RR 
type 'siyongc.domain.' 
Nov 16 15:07:44 rh71 named[2422]: dns_zone_load: zone siyongc.domain/IN: loading 
master file siyongc: unknown class/type 
    如下的问题﹐那可能是您没有定义 SOA 记录﹐或设定有错误﹕ 
Nov 16 15:14:33 rh71 named[2506]: dns_zone_load: zone siyongc.domain/IN: could 
not find NS and/or SOA records 
Nov 16 15:14:33 rh71 named[2506]: dns_zone_load: zone siyongc.domain/IN: has 
0 SOA records 
Nov 16 15:14:33 rh71 named[2506]: dns_zone_load: zone siyongc.domain/IN: no 
NS records 
    下面的问题可能是您的 SOA 记录中多输入了一组数字﹐或少输入了一组数字﹐或数字格式有错误﹕ 
Nov 16 15:14:33 rh71 named[2506]: dns_zone_load: zone siyongc.domain/IN: could not 
find NS and/or SOA records 
Nov 16 15:14:33 rh71 named[2506]: dns_zone_load: zone siyongc.domain/IN: has 
0 SOA records 
Nov 16 15:14:33 rh71 named[2506]: dns_zone_load: zone siyongc.domain/IN: no 
NS records 
Nov 16 15:18:24 rh71 named[2562]: dns_rdata_fromtext: siyongc:4: near eol: unexpected 
end of input 
Nov 16 15:18:24 rh71 named[2562]: dns_zone_load: zone siyongc.domain/IN: loading 
master file siyongc: unexpected end of input 
Nov 16 15:19:34 rh71 named[2640]: dns_rdata_fromtext: 
siyongc:4: near '14B400': 
syntax error 
Nov 16 15:19:34 rh71 named[2640]: dns_zone_load: zone 
siyongc.domain/IN: loading 
master file siyongc: syntax error 
以下问题可能是 SOA 的 “ ( ) ”符号有问题﹐要么是“ ( ” 给断到下一行了﹐要么是“ ) ”给批注掉了﹕ 
Nov 16 15:22:08 rh71 named[2669]: dns_rdata_fromtext: siyongc:3: near eol: unexpected 
end of input 
Nov 16 15:22:08 rh71 named[2669]: dns_zone_load: zone siyongc.domain/IN: loading 
master file siyongc: unexpected end of input 
Nov 16 15:22:52 rh71 named[2696]: dns_rdata_fromtext: siyongc:4: 
near 'IN': extra input text 
Nov 16 15:22:52 rh71 named[2696]: dns_zone_load: zone siyongc.domain/IN: 
loading master file siyongc: extra input text 

以下是您没有设定 NS 记录或 NS 记录设定有错误﹕ 
Nov 16 15:25:30 rh71 named[2801]: dns_zone_load: zone siyongc.domain/IN: no NS records 
    下面的错误可能是您设定了一个记录项超出了当前 ORIGIN 的范围﹐例如 localhost. 或 siyongc. (也就是错误使用 FQDN )﹔或是错误的使用了 $ORIGIN 设定﹔或是在 named.conf 中有多个 zone 在分享同一份记录文件﹕ 
Nov 16 15:31:20 rh71 named[2920]: dns_master_load: siyongc:16: 
ignoring out-of-zone data 
下面的错误﹐有可能您在设定多个 $ORIGIN 并同时尝试设定多个 SOA 时出现的错误﹕ 
Nov 16 15:28:31 rh71 named[2855]: dns_master_load: siyongc:26: 
not at top of zone 
    许多许多问题﹐事实上您都可以在 /var/log/messages 中找到﹐当您发现这些错误信息之后﹐看看是关于什么记录的﹐然后顺藤摸瓜﹐留心一下档案内容﹐就比较容易找到错误的原因了。 
    有时候﹐您想简化您的 DNS 设定工作﹐您可以使用 netconf 来做。不过﹐根据我的经验是﹕netconf 未必能够完全帮您正确的设定起来。当您重新启动 named 之后﹐别忘了看一下 /var/log/messages ﹐确定没有错误发生。如果您使用工具来设定 DNS 而碰到问题﹐这就需要您有手工设定的能力了。 
设定 DNS Client 
    DNS 系统是一个典型的 Client/Server 架构﹐前面介绍的动作仅是确保 DNS 的 server 成功启动起来而已﹐如果您要测试它﹐还必须设定好 client 端才行。 
    不知道您会不会设定 linux 的 dns client 呢﹖如果忘记了要打屁屁了哦~~~ 事实上我们在第一章的“网络设定”那里就设定过了﹐也就是修改 /etc/resolv.conf 这个档案﹐将您刚设定好的 DNS 主机 IP 放在档案的前排位置﹐如﹕
nameserver192.168.100.23 
nameserver168.95.1.1 
nameserver139.175.10.20 
domainsiyongc.domain 
searchsiyongc.domain dmz.domain test.com 
假如您的 client 和 server 在同一台机器上﹐那可以将第一个 name server 设定为 0.0.0.0 或 127.0.0.1 。 
    要是您使用 Windows ﹐但不是透过 DHCP 来指定 DNS 的话﹐那您或许需要手工设定了﹕控制台 --> 网络 --> TCP/IP (-> 网络卡) --> 内容 --> DNS 组态 ﹕ 
    请注意﹕如果您修改了这里的设定﹐就算您的 Windows 是透过 DHCP 取得 IP 设定的话﹐也会以这里的设定为准。如果您想使用 DHCP 的设定﹐那就选择“关闭 DNS”吧。 
    测试 DNS 
要测试我们的设定是否生效﹐我们可以使用的方法有很多﹐其中最简单的莫过于 ping 命令了。直接 ping 一下您所预期的 dns 名称就知道结果了。 
    不过﹐ping 毕竟很有限﹐例如﹕您不能查询 MX 和 NS 等记录。实作上﹐我们最最常使用的 DNS 查询工具是 nslookup 命令。关于 nslookup ﹐在“学习网络”的“DNS 协议”文章中有很详细的例子﹐这里不再重复。如果我们在测试中失败﹐例如 nslookup 响应说﹕ 
*** rh71.siyongc.domain can't find XXX.XXXX.XXXX: 

Non-existent host/domain 

    这通常是反解记录没设定好的缘故﹐请确定 DNS 主机本身的反解有设定起来﹐而且可以被 DNS 追查得到。如果反解没有授权下来﹐那就请上游 ISP 帮忙设定。不过﹐我发现这个错误信息似乎在新版的 nslookup 中不会出现﹐anyway ﹐请您自己留意吧。 
    有时候 nslookup 会停在某处一动也不动﹐其实它不是当掉了﹐而是在查询没结果之后等 time out 而已。您可以按 Ctrl + C 终止查询﹐再打 exit 跳出来。不过﹐如果您在按了 Ctrl + C 之后接着再输入一个无结果的查询﹐那就好可能将 nslookup 当掉。这样您可能要登录进另外一个 terminal ﹐然后用 kill 将 PID 杀掉。同上﹐新版的 nslookup 没有这个困绕﹐但如果按 Ctrl + C 的话﹐则会直接跳离 nslookup 程序。 
    然而﹐nslookup 似乎在以后的版本中不再维护了﹐取而代之的﹐就是 dig 命令﹐所以﹐当您在 Redhat 7.1 上输入 nslookup﹐您会看到如下这样的信息﹕ 
Note: nslookup is deprecated and may be removed from future releases. 
Consider using the `dig' or `host' programs instead. Run nslookup with 
the `-sil[ent]' option to prevent this message from appearing. 
这段文字不用解释了吧﹖真的不知道说什么就查字典吧~~ 这里﹐我们不妨学习一下如何用 dig 来查询和测试 DNS 服务。 
基本上﹐dig 命令的语法如下﹕ 
dig [@server] domain [] [] [+] 
[-] [%comment] 
    看起来蛮复杂的﹐恐怕要 man dig 才知道怎么使用。不过﹐我们平时只用它来查询 dns 数据的话﹐要使用到的选项也不会太多啦﹐如果您会得在 nslookup 中设定 type=XXX 的话﹐那您也可以用 dig 来查询不同的记录类别数据。例如﹕ 
# dig siyongc.domain mx 
; <<>> DiG 9.1.0 <<>> siyongc.domain mx 
;; global options: printcmd 
;; Got answer: 
;; ->>HEADER<<- opcode: QUERY, status: NOERROR, id: 8198 
;; flags: qr aa rd ra; QUERY: 1, ANSWER: 2, AUTHORITY: 2, ADDITIONAL: 2 
;; QUESTION SECTION: 
;siyongc.domain. IN MX 
;; ANSWER SECTION: 
siyongc.domain. 86400 IN MX 20 lp64.dmz.domain. 
siyongc.domain. 86400 IN MX 10 rh71.siyongc.domain. 
;; AUTHORITY SECTION: 
siyongc.domain. 86400 IN NS lp64.dmz.domain. 
siyongc.domain. 86400 IN NS rh71.siyongc.domain. 
;; ADDITIONAL SECTION: 
rh71.siyongc.domain. 86400 IN A 192.168.100.23 
lp64.dmz.domain. 86400 IN A 10.0.1.130 
;; Query time: 8 msec 
;; SERVER: 192.168.100.23#53(192.168.100.23) 
;; WHEN: Fri Nov 16 21:13:18 2001 
;; MSG SIZE rcvd: 138 
    上面是的命令是使用预设的 name server 来查询 siyongc.domain 的 mx 记录。当然﹐您也可以用 @ 来指定用某一台 name server 来查询其它的信息。例如﹐我要用 hinet 的 dns 来查询负责 com.tw 的 NS 有哪些﹕ 
# dig @168.95.1.1 com.tw ns 
; <<>> DiG 9.1.0 <<>> @168.95.1.1 com.tw ns 
;; global options: printcmd 
;; Got answer: 
;; ->>HEADER<<- opcode: QUERY, status: NOERROR, id: 33339 
;; flags: qr aa rd ra; QUERY: 1, ANSWER: 3, AUTHORITY: 0, ADDITIONAL: 4 
;; QUESTION SECTION: 
;com.tw. IN NS 
;; ANSWER SECTION: 
com.tw. 518400 IN NS b.twnic.net.tw. 
com.tw. 518400 IN NS c.twnic.net.tw. 
com.tw. 518400 IN NS a.twnic.net.tw. 
;; ADDITIONAL SECTION: 
b.twnic.net.tw. 159497 IN A 192.72.81.200 
c.twnic.net.tw. 159497 IN A 168.95.192.10 
a.twnic.net.tw. 159497 IN A 163.28.1.2 
a.twnic.net.tw. 159497 IN A 140.111.1.2 
;; Query time: 167 msec 
;; SERVER: 168.95.1.1#53(168.95.1.1) 
;; WHEN: Fri Nov 16 21:17:46 2001 
;; MSG SIZE rcvd: 146 
    除了用 nslookup 和 dig 之外﹐如果您只想简单的查询 dns 信息的话﹐那您可以用 host 命令。例如﹕ 
# host -t any siyongc.domain 0.0.0.0 
Using domain server: 
Name: 0.0.0.0 
Address: 0.0.0.0#53 
Aliases: 
siyongc.domain. SOA rh71.siyongc.domain. root.rh71.siyongc.domain. 2001111601 28 
800 14400 3600000 86400 
siyongc.domain. name server lp64.dmz.domain. 
siyongc.domain. name server rh71.siyongc.domain. 
siyongc.domain. mail is handled by 10 rh71.siyongc.domain. 
siyongc.domain. mail is handled by 20 lp64.dmz.domain. 
siyongc.domain. has address 192.168.100.23 
    上面的命令就是用本机 name server 来查询 siyongc.domain 的 any 信息。至于 host 命令的格式如下﹕ 
host [-aCdlnrTwv] [-c class] [-N ndots] [-R number] [-t type] [-W wait] 
name [server] 
老话啦﹐看 man host 以了解那些参数和选项的用法吧。 

    您可以发现﹕透过 nslookup ﹑ dig ﹑与 host 命令﹐事实上可以查询到许多 dns 上面的设定信息。所以﹐如果您的 DNS 是对外提供服务的话﹐请尽量尽量控制 DNS 信息量﹐如果您觉得没必要对外提供的﹐那就拿掉它。无论如何﹐关于内部网络的 DNS 信息﹐是绝对不能对外散布的。如果查询的结果未如您所预期的﹐您就要进行 debug 工作了。
    引自: 
    ~linuxpub/bbs/showthread.php?t=46297 



阅读(1531) | 评论(0) | 转发(0) |
给主人留下些什么吧!~~