接下来的 ‘ 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 上﹐这样的设定﹐也能让您少输入“ www. ”这四个键~~~
另外﹐在这个档里面﹐您或许还发现‘ 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 更多的名称。也就是说﹕所有关于‘www.siyongc.domain’﹑‘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 档案也不要忘记了﹕
您看﹗就这样﹐我们的 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 ﹐请您自己留意吧。