搭建一個互聯網DNS服務器架構


本節索引
  • DNS簡介

  • DNS解析過程

  • DNS資源記錄

  • DNS主從原理

  • 搭建完整的DNS架構

  • 調試結果

  • 錯誤分析

  • 本篇小結

 

DNS簡介


DNS(Domain Name System,域名系統),是Internet上作爲域名和IP地址相互映射的一個分佈式數據庫,在這個解析庫中定義了某個域名和IP的對應關係。通過DNS的解析,我們不用去記住那些難記的IP地址(數串),我們只要能記住其對應的主機名即可,像www.baidu.com。這中字符串就顯得好記多了。DNS協議運行在TCP和UDP的上,對應端口號爲53。其運行在TCP協議上主要是爲了實現DNS冗餘,即主從複製或則說區域傳送,這裏涉及到DNS數據庫的數據的創輸,必須保證安全。而運行在UDP協議上主要是爲了實現名稱解析,名稱解析要求速度快,而且安全性並沒要太大要求,使用UPD協議剛好能滿足這些要求。


DNS解析過程


DNS域分爲多種,有最重要的根域,用“.”表示,根域的下一級是頂級域(Top Level Domain),最有名的便是com域了,在向下就是二級域、三級域等等,DNS最多支持127即域名(真達到127級還真記不住)。

我們知道,在我們的主機找中有個hosts文件,其實這也是用來做名稱解析的,你可以將自己經常訪問的地址寫在這裏面,下次訪問時系統會先讀取該文件,直接訪問IP,這樣就省掉了DNS爲你解析的過程,訪問也變快了不少。

wKiom1nEb0fiA4mQAAAfcB-W1y4021.png

如果在hosts文件中沒有找到你要訪問的地址記錄,那麼將會請求所在域的DNS服務器,如果DNS服務器的緩存中有你要的地址,直接返回給你結果;如果沒有DNS服務器將幫你去根上詢問,根幫你找相應的域,並返回給你所在域的DNS服務器下一個域的地址;你拿着這個地址在去訪問根的下級域,如此遞歸直到找到你想要的ip地址,並將結果返回給客戶端。整個解析過程如下圖:

wKiom1nEmSGxPDr3AACZfIU5_oA137.png

值得一提的是,這裏面有兩個專業術語,“遞歸查詢”“迭代查詢”。遞歸查詢是指:給你提供最終答案,你訪問你所在域的DNS服務器就是遞歸查詢;迭代查詢是指:只給你提供線索,不給出最終答案。例如:訪問www.vinsent.cn的主機,你訪問你所在域的DNS服務器,它就必須給你最終答案,這個過程就是遞歸查詢。而你所在域的DNS服務器去幫你詢問的過程,就是迭代查詢的過程。


DNS資源記錄


        DNS服務器的數據庫中記錄的就是域與IP地址之間的對應關係,以及域的子域的地址,或則從服務器的地址。而這些需要衆多的資源記錄來實現。DNS中的資源記錄類型多達10種,在這裏主要給大家說說幾類常見的資源記錄類型。

1) SOA記錄

       SOA(Start Of Authority)起始授權記錄,SOA記錄表明了DNS服務器之間的關係。SOA記錄表明了誰是這個區域的所有者。比如vinsent.cn這個區域。一個DNS服務器安裝後,需要創建一個區域,以後這個區域的查詢解析,都是通過DNS服務器來完成的。而這裏所說的所有者,就是誰對這個區域有修改權利。常見的DNS服務器只能創建一個標準區域,然後可以創建很多個輔助區域。標準區域是可以讀寫修改的。而輔助區域只能通過標準區域複製來完成,不能在輔助區域中進行修改。而創建標準區域的DNS就會有SOA記錄,或者準確說SOA記錄中的主機地址一定是這個標準區域的服務器IP地址。SOA記錄的格式與實例展示:

$TTL 86400      #  全局定義TTL,之後記錄就不用再寫TTL了
@         IN         SOA     ns1.vinsent.cn. admin.vinsent.cn. (
                     2017000002 ; 序列號
                     1H         ; 刷新時間
                     5m         ; 重試時間
                     2D         ; 過期時間
                     6H )       ; 否定答案緩存時間

說明:admin.vinsent.cn.表示管理員的郵箱地址,在這裏我們不能直接寫[email protected],必須將@用"."來替換。

2)NS記錄

        NS(Name Server)名稱服務器,NS記錄實際上也是在DNS服務器之間,表明誰對某個區域有解釋權,即權威DNS。比如你先在萬網申請了一個域名ABC.COM。一般情況是萬網的域名服務器替你來解析如www.vinsent.cn這樣的主機記錄。如果你想自己架設一個DNS服務器,讓這臺服務器從今往後替代萬網的DNS服務器解析,那麼你就需要在你的DNS上設置NS記錄,然後將萬網域名管理系統中的NS記錄改成你的DNS_IP。這樣以後就是你自己的DNS服務器負責提供解析了。即使萬網的DNS服務器出現故障,別人仍然可以找到你。權威DNS通過NSLOOKUP工具可以查看。NS記錄格式與實例

vinsent.cn.        IN          NS         ns1.vinsent.cn.
vinsent.cn.        IN          NS         ns2.vinsent.cn.
                               NS         ns3.vinsent.cn.
                               NS         ns4

說明:NS字段之前的內容,可省略不寫,從上面SOA中繼承,值得注意的是,上述記錄要麼寫完整(ns1.vinsent.cn.)要麼就直接不寫從上面繼承(ns1)。

3)A與AAAA記錄

        A記錄又稱IP指向,用戶可以在此設置子域名並指向到自己的目標主機地址上,從而實現通過域名找到服務器。他的值即指向的目標主機地址類型只能使用IP地址;而AAAA這表示IPv6地址的IP指向;例如:

vinsent.cn.         IN          NS         ns1.vinsent.cn.     
ns1.vinsent.cn.     IN          A         192.168.25.107     # A記錄必須與NS記錄成對出現

4)PTR記錄

        PTR是pointer 的簡寫,PTR記錄也被稱爲指針記錄,PTR記錄是A記錄的逆向記錄,作用是把IP地址解析爲域名。DNS的反向區域負責從IP到域名的解析,因此如果要創建PTR記錄,必須在反向區域中創建。

4.3.2.1.in-addr.arpa.     IN     PTR     www.magedu.com
4                         IN     PTR     www.magedu.com     # 網絡地址及後綴可省略

5)MX記錄

        MX即郵件交換記錄。用於將以該域名爲結尾的電子郵件指向對應的郵件服務器以進行處理。如:用戶所用的郵件是以域名dadmin.com爲結尾的,則需要在管理界面中添加該域名的MX記錄來處理所有以@admin.com結尾的郵件。

        值得一提的是,MX記錄可以使用主機名或IP地址;MX記錄可以通過設置優先級實現主輔服務器設置,“優先級”中的數字越小表示級別越高。也可以使用相同優先級達到負載均衡的目的;如果在“主機名”中填入子域名則此MX記錄只對該子域名生效。MX記錄有優先級,其範圍爲0-99,其值越小,優先級越高。

ns1             IN     MX    10    mailserver     # 10表示優先級
mailserver      IN     A           172.18.253.142

6)CNAME記錄

        CNAME通常稱別名指向。可以爲一個主機設置別名。比如設置wesrv.vinsent.cn,用來指向一個主機www.vinsent.com那麼以後就可以用wesrv.vinsent.cn來代替訪問www.vinsent.com了。值得注意的是:CNAME的目標主機地址只能使用主機名,不能使用IP地址;·主機名前不能有任何其他前綴,如:http://等是不被允許的;A記錄優先於CNAME記錄。即如果一個主機地址同時存在A記錄和CNAME記錄,則CNAME記錄不生效。例如

web        IN         A         6.6.6.6
www        IN         CNAME     web


DNS主從原理


        作爲DNS服務器,我們的職責就是爲大量用戶提供服務,即爲他們解析ip地址,我們知道在互聯網中,有時數據的訪問量是非常大的,大量的請求同涌入到一臺DNS服務器上,那麼該DNS服務的資源幾乎會被消耗殆盡,直至崩潰。由此我們引入了從服務器,從DNS服務主要是爲了分擔主DNS服務器的一些訪問請求,從而實現了負載均衡。原理如下圖:

 

wKiom1nEgQKQy9l3AABMcTTRcf0965.png

        子域授權,是指通過在原有的域上劃出一個小的區域,並給新DNS服務器管理。如果有客戶端請求解析在這個劃分區域中的域名,則只要找新的子DNS服務器。這樣的做的好處可以減輕主DNS的壓力,也便於管理。比如,我們去訪問www.vinsent.cn.這個域,從DNS查找過程我們可以知道,DNS是一級一級的查詢,上級DNS服務器只知道其直接下級,這就是子域授權的結果。我們必須在根域”.”上授權頂級域“cn”,在頂級域上授權二級域(vinsent),如此下去直到找到www.vinsent.cn這個主機的IP地址。子域授權只需要在父域的的資源記錄文件中添加子域的NS記錄即可;例如:在cn域上授權vinsent域。

wKioL1nEga6xTeK1AAAnoy-9cFg167.png


搭建自己的DNS架構


    要想搭建一個完整的DNS服務器羣,包括根域,頂級域,以及頂級域之下的子域,那麼我們必須先規劃好這個網絡的結構,這樣才能爲我們的配置創造良好的實驗條件,否者會有許許多多的問題出現。這裏強調一點,不管是老鳥還是新手,無論我們是在寫自動戶腳本還是搭建服務,全局觀的思維很重要,只要能理清、理順這些原理和本質,實驗只是結果的一種展示。

wKioL1nEmyuSgqMRAACr6M8FSNA197.png

1 實驗準備

        首先準備6臺或者7臺主機,按上圖對應的關係配置好主機的IP地址,當然了你也可以選擇不修改ip地址,主機本來是什麼地址就用什麼地址,只要互相之間能通信即可。其次爲了實驗能夠順利的完成,我們還是一樣,關閉selinux和防火牆(每一臺主機),當然了這僅僅是實驗環境,如果是真實環境,建議使用防火牆策略。本次實驗都是在CentOS 7系統上完成的,如你你是CentOS 6的主機,那麼有些命令需要調整。

[root@vinsent ~]# systemctl stop firewalld.service     # 關閉防火牆服務
[root@vinsent ~]# iptables -F                          # 清空防火牆策略
[root@vinsent ~]# setenforce 0                         # 臨時禁用selinux
[root@vinsent ~]# sed -i 's/^SELINUX=.*/SELINUX=disabled/' /etc/selinux/config # 永久關閉selinux 
[root@vinsent ~]#

2 安裝bind並認識其配置文件

        提供DNS服務的程序時bind,我們可以通過yum list bind來查看一些包的信息,使用rmp -ql 查看包中文件列表。

[root@vinsent ~]#yum -y install bind             # 安裝bind
...省略過程...
[root@vinsent ~]#yum -y install bind-utils      # 安裝bind-utils包,有些工具是由該包提供的
[root@vinsent ~]#yum info bind
Installed Packages
Name        : bind
Arch        : x86_64
Epoch       : 32
Version     : 9.9.4         # 版本
Release     : 51.el7
Size        : 4.3 M
Repo        : installed
From repo   : updates
Summary     : The Berkeley Internet Name Domain (BIND) DNS (Domain Name System) server
URL         :   # 官方網站 
License     : ISC
Description : BIND (Berkeley Internet Name Domain) is an implementation of the DNS
            : (Domain Name System) protocols. BIND includes a DNS server (named),
            : which resolves host names to IP addresses; a resolver library
            : (routines for applications to use when interfacing with DNS); and
            : tools for verifying that the DNS server is operating properly.
[root@vinsent ~]# rpm -ql bind  # bind包含很多文件,這裏只說幾個重要的,常用的文件
/etc/named.conf                 # 全局配置文件,定義域與各種規則
/etc/named.rfc1912.zones        # 域配置的另外一個文件,我們可以將自己定義的域寫在這個文件中
/etc/named.root.key             # 和dnssec認證有關的文件
/etc/rndc.conf                  # 管理工具rndc的配置文件
/usr/lib/systemd/system/named.service         # 服務名
/usr/lib64/bind
/usr/sbin/named                 # 服務的PATH路徑
/usr/sbin/rndc
/var/named                       # 主服務器域的資源記錄存放位置
/var/named/slaves                # 從服務器的資源記錄存放目錄
[root@vinsent ~]#

3 配置

1)修改根域資源記錄

        按照上圖中的要求,我們創建了6臺主機,分別配置了相應的ip地址,我們便可以開始配置了。由於我們要配置根DNS以及所以,我們必須修改根域記錄,指向我們想要的根。

[root@vinsent ~]# vim /var/named/named.ca      # 刪除其他記錄,只留下面兩條記錄即可
.                       518400  IN      NS      a.root-servers.net.
a.root-servers.net.     3600000 IN      A       172.18.253.177         # 根服務器的地址
[root@vinsent ~]#

說明,每個主機上的/var/named/named.ca都需要修改。

2)配置vinsent.cn域主DNS服務器

思路:在/etc/named.conf中添加vinsent.cn域,然後創建並書寫域記錄文件

[root@vinsent named]# vim /etc/named.conf         # 添加域
options {
//      listen-on port 53 { 127.0.0.1; };     # 註釋掉這行或者將值該爲any
        listen-on-v6 port 53 { ::1; };
        directory       "/var/named";
        dump-file       "/var/named/data/cache_dump.db";
        statistics-file "/var/named/data/named_stats.txt";
        memstatistics-file "/var/named/data/named_mem_stats.txt";
        allow-query     { any; };             # 允許查詢,修改爲any或者特定網段,或主機  
        recursion yes;        # 是否允許遞歸
...後面省略...
 
}; 
zone "vinsent.cn" IN {             # 添加vinsent.cn正向域
        type master;
        file "vinsent.cn.zone";     # 正向域資源記錄文件
};
zone "253.18.172.in-addr.arpa" IN {     # 添加vinsent.cn反向域
        type master;
        file "172.18.253.zone";     # 反向域資源記錄文件
};

[root@vinsent named]# vim /var/vinsent.cn.zone     # 創建域文件並添加以下記錄
$TTL 86400
@         IN         SOA     ns1.vinsent.cn. admin.vinsent.cn. (
                    2017000002
                    1H
                    5m
                    2D
                    6H )

                NS    ns1
ns1                A    172.18.253.142
web        IN         A     172.18.253.21 
www        IN         CNAME     web         # 別名記錄

[root@vinsent named]# named-checkconf         # 檢查配置文件是否有錯,要養成檢查錯誤的好習慣
[root@vinsent named]# named-checkzone "vinsent.cn" vinsent.cn.zone  # 檢查資源記錄文件是否有語法錯誤
[root@vinsent named]# chgrp named /var/named/vinsent.cn.zone     # 修改文件屬組
[root@vinsent named]# chmod 640 /var/named/vinsent.cn.zone     # 安全起見,修改權限
[root@vinsent named]# systemctl restart named    # 重啓服務

 3)配置vinsent.cn域從DNS服務器

方法同上,在配置文件中添加vinsent.cn域,不過這個域要指明主DNS,

[root@vinsent ~]# vim /etc/named.conf
options{
...省略...         # options 選項的設置與vinsent.cn域的設置相同,之後都是
}
zone "vinsent.cn" IN {
    type slave;
    file "slaves/vinsent.cn.zone";     # 從服務的資源記錄文件要放到slave目錄下
    masters { 172.18.253.142; };
};
[root@vinsent ~]# named-checkconf  # 檢查一下語法是否有錯
[root@vinsent ~]# systemctl restart named    # 重啓服務
[root@vinsent ~]# cd /var/named/slaves/
[root@vinsent slaves]# ls     # 重啓服務之後,文件自動生成,該文件來自主DNS服務器,從服務器會自動更新
vinsent.cn.zone

4)配置cn域

cn域的是vinsent.cn域的上級域,所以需要在cn域中對子域vinsent.cn進行授權。

[root@vinsent ~]# vim /etc/named.conf
...省略...
zone "cn" IN {         # 定義cn域
    type master;
    file "cn.zone";
};
[root@vinsent ~]# vim /var/named/cn.zone       # 創建cn域資源記錄文件

$TTL 86400
@               IN              SOA     ns1     admin.cn. (
                                        2017000002
                                        1H
                                        5m
                                        2D
                                        6H )

                                NS      ns1
ns1             IN              A       172.18.254.238
vinsent         IN              NS      ns3             # 對子域進行授權,由於子域有主從兩臺服務器
vinsent         IN              NS      ns2             # 所以有兩條記錄
ns3             IN              A       172.18.250.234
ns2             IN              A       172.18.253.142
[root@vinsent ~]# named-checkconf  # 檢查一下語法是否有錯
[root@vinsent ~]# systemctl restart named    # 重啓服務

4)配置根域“.”

根域是最高等級的域,那麼需要在根域中對cn域進行授權,如下

[root@vinsent ~]# vim /etc/named.conf
...省略...
zone "." IN {
        type master;
        file "root.zone";
};
[root@vinsent named]# vim root.zone 

$TTL 86400
@               IN              SOA     @       admin.vinsent.cn. ( 2017000001 1H  5M   6H  1D )
                IN              NS      @
                IN              A       172.18.253.177
cn              IN              NS      ns2     # 對cn域進行授權
ns2             IN              A       172.18.254.238
[root@vinsent ~]# named-checkconf  # 檢查一下語法是否有錯
[root@vinsent ~]# systemctl restart named    # 重啓服務

5)配置DNS轉發器

轉發器作用主要是將我們客戶端的請求轉發給根,並進行迭代,從而返回最終結果,配置如下:

[root@vinsent ~]# vim /etc/named.conf 
options {
//      listen-on port 53 { 127.0.0.1; };     # 註釋掉
        listen-on-v6 port 53 { ::1; };
        directory       "/var/named";
        dump-file       "/var/named/data/cache_dump.db";
        statistics-file "/var/named/data/named_stats.txt";
        memstatistics-file "/var/named/data/named_mem_stats.txt";
        allow-query     { any; };
        forward first;
        forwarders { 172.18.253.177; };
        allow-transfer {any;};    # 是否允許追蹤
        recursion yes;
        dnssec-enable no;         # 關閉dnssec認證
        dnssec-validation no;     # 這一項如果不該爲no,實驗將不會成功
        /* Path to ISC DLV key */
        bindkeys-file "/etc/named.iscdlv.key";

        managed-keys-directory "/var/named/dynamic";

        pid-file "/run/named/named.pid";
        session-keyfile "/run/named/session.key";
};
//zone "." IN {              # 註釋掉根域或者,直接刪除,
//      type hint;
//      file "named.ca";
//};

[root@vinsent ~]# vim /var/named/named.ca 
.            518400    IN    NS    a.root-servers.net.             # 留一條根指向即可
a.root-servers.net.    3600000    IN    A    172.18.253.177
[root@vinsent ~]# named-checkconf  # 檢查一下語法是否有錯
[root@vinsent ~]# systemctl restart named    # 重啓服務

到這裏DNS的配置就算完成了,接下來調試一下,看看結果。


結果測試


        要測試結果,我們需要用到一個工具dig,這個命令來自於bind-utils包,使用該工具要確保你有安裝這個包。接下來先來看看dig的用法:

dig [-t type] name [@server] [query options]

-t : 查詢類型 [ A | NS | PTR | SOA ] 

+[no]trace    : 跟蹤解析過程 : dig +trace vinsent.cn
+[no]recurse  : 進行遞歸解析
dig -x IP = dig –t ptr reverse_ip.in-addr.arpa     # 反向解析

 現在用dig來測試以下看看是否成功,篇幅影響,我這裏只測試了一下,你還可以逐個測試。

[root@vinsent named]#dig www.vinsent.cn @172.18.253.142

; <<>> DiG 9.8.2rc1-RedHat-9.8.2-0.62.rc1.el6 <<>> www.vinsent.cn @172.18.253.142
;; global options: +cmd
;; Got answer:
;; ->>HEADER<<- opcode: QUERY, status: NOERROR, id: 17807
;; flags: qr aa rd ra; QUERY: 1, ANSWER: 2, AUTHORITY: 1, ADDITIONAL: 1

;; QUESTION SECTION:
;www.vinsent.cn.            IN    A

;; ANSWER SECTION:
www.vinsent.cn.        86400    IN    CNAME    web.vinsent.cn.
web.vinsent.cn.        86400    IN    A    172.18.253.21             #查詢到了我們的地址

;; AUTHORITY SECTION:
vinsent.cn.        86400    IN    NS    ns1.vinsent.cn.

;; ADDITIONAL SECTION:
ns1.vinsent.cn.        86400    IN    A    172.18.253.142

;; Query time: 1 msec
;; SERVER: 172.18.253.142#53(172.18.253.142)
;; WHEN: Wed Sep 20 12:41:13 2017
;; MSG SIZE  rcvd: 100
[root@vinsent named]#

如果你每次的查詢都能出現你想要的結果,那麼說明你在配置是無誤的。


錯誤分析


    我們在dig查詢的結果,裏面有一項,status,我們可以根據這個狀態來分析,問題出在哪兒。

wKiom1nE8XriC4AqAAA2wUNvKMg597.png

 一般來說,常出現的狀態主要有以下幾種:

  • NXDOMAIN: 可能是CNAME對應的A記錄不存在導致

  • REFUSEE:可能是DNS策略導致

  • NOERROR不代表沒有問題,也可以是過時的記錄,可以查看是否爲權威記錄,flags:aa標記判斷


本篇小結


  到此,有關DNS的一些基礎知識以及如何構建一個自己用的DNS服務器羣就給大家說講完了,本篇主要包括,DNS主從原理、資源記錄等。在最後在給大家說一下排錯的方法。主要有幾個要點,selinux和iptables是否關閉,options中的選項是否設置正確,資源記錄的文件權限是否允許named用戶讀,如果是特定區域的傳送,是否定義好了forward項,大概就這些問題比較常見。謝謝大家的閱讀~,歡迎大家留言,指出錯誤。




發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章