天天看點

域名伺服器安全增強

為什麼要寫這篇文章?第一個原因當然就是前段時間出現的BIND 8.2.x TSIG

        安全漏洞(還有去年公布的BIND 8.1.x/8.2.x NXT安全漏洞),直到目前為止,國内也還沒有關于DNS服務安全配置方面的較為完整的文章(即使是國外也不多見)。

        另一個原因是經過調查發現,幾乎任何一種UNIX家族的作業系統,都使用BIND軟體

        作為其DNS的唯一實作,比起其它諸如ftp/http/pop3等網絡服務有各種各樣的發行

        版本,是以一旦被發現有安全問題,則受影響的主機之多也是其它漏洞很難比拟的。

        是以覺得應該寫一份針對BIND DNS服務軟體的安全配置資料,充分利用BIND自身已

        經實作的保護功能,加強BIND安全性,進而能抵禦目前已知的BIND安全漏洞,并使

        潛在的安全漏洞所可能對伺服器造成的影響盡可能地減少。

        配置環境:

        FreeBSD 4.1-RELEASE

        BIND 8.2.3

        ---[[ 啟動安全選項 ]]---------------------------------------------------

named程序啟動選項:

        -r:關閉域名伺服器的遞歸查詢功能(預設為打開)。該選項可在配置檔案的

        options中使用"recursion"選項覆寫。

        -u <user_name>和-g <group_name>:定義域名伺服器運作時所使用的UID和GID。

        這用于丢棄啟動時所需要的root特權。

        -t <directory>:指定當伺服器程序處理完指令行參數後所要chroot()的目錄。

        ---[[ 配置檔案中的安全選項 ]]-------------------------------------------

        1、假如希望記錄安全事件到檔案中,但同時還希望保持原有的日志模式,可以添

        加以下内容:

        logging {

        channel my_security_channel {

        file "my_security_file.log" versions 3 size 20m;

        severity info;

        };

        category security {

        my_security_channel;

        default_syslog; default_debug; };

        }

其中my_security_channel是使用者自定義的channel名字,my_security_file.log

        是安全事件日志檔案,可包含全路徑(否則是以named程序工作目錄為目前目錄)。

        安全事件日志檔案名為my_security_file.log,儲存三個最近的備份

        (my_security_file.log0、my_security_file.log1、my_security_file.log2),

        日志檔案的最大容量為20MB(如果達到或超這一數值,直到該檔案被再次打開前,

        将不再記錄任何日志消息。預設(省略)時是沒有大小限制。)

        2、在options節中增加自定義的BIND版本資訊,可隐藏BIND伺服器的真正版本号。

        version "Who knows?";

        // version 9.9.9;

此時如果通過DNS服務查詢BIND版本号時,傳回的資訊就是"Who knows?"。^_^

        3、要禁止DNS域名遞歸查詢,在options(或特定的zone區域)節中增加:

        recursion no;

        fetch-glue no;

        4、要增加出站查詢請求的ID值的随機性,在options節中增加:

        use-id-pool yes;

則伺服器将跟蹤其出站查詢ID值以避免出現重複,并增加随機性。注意這将會

        使伺服器多占用超過128KB記憶體。(預設值為no)

        5、要限制對DNS伺服器進行域名查詢的主機,在options(或特定的zone區域)節

        中增加:

        allow-query { <address_match_list> };

        address_match_list是允許進行域名查詢的主機IP清單,如"1.2.3.4; 5.6.7/24;"。

        6、要限制對DNS伺服器進行域名遞歸查詢的主機,在options(或特定的zone區域)

        節中增加:

        allow-recursion { <address_match_list> };

        address_match_list是允許進行域名遞歸查詢的主機IP清單,如

        "1.2.3.4; 5.6.7/24;"。

        7、要指定允許哪些主機向本DNS伺服器送出動态DNS更新,在options(或特定的

        zone區域)節中增加:

        allow-update { <address_match_list> };

        address_match_list是允許向本DNS伺服器送出動态DNS更新的主機IP清單,如

        預設時為拒絕所有主機的送出。

        8、要限制對DNS伺服器進行區域記錄傳輸的主機,在options(或特定的zone區域)

        allow-transfer { <address_match_list> };

        address_match_list是允許進行區域記錄傳輸的主機IP清單,如"1.2.3.4;

        5.6.7/24;"。

        9、要指定不接受哪些伺服器的區域記錄傳輸請求,在options(或特定的zone區域

        )節中增加:

        blackhole { <address_match_list> };

        address_match_list是不接受區域記錄傳輸請求的主機IP清單,如"1.2.3.4;

        10、在options節中還有一些資源限制選項,不同使用者可根據實際情況靈活設定,

        但一定要注意不當的設定會損失DNS服務的性能。

        coresize <size_spec> ; // core dump的最大值。預設為default。

        datasize <size_spec> ; // 伺服器所使用的最大資料段記憶體。預設為

        default。

        files <size_spec> ; // 伺服器能同時打開的最大檔案數。預設為

        // unlimited(不限制)。

        // (注意,并非所有作業系統都支援這一選項。)

        max-ixfr-log-size <size_spec> ; // (目前版本暫不使用。)限制增量區域

        記

        錄傳輸時會話日志的大小。

        stacksize <size_spec> ; // 伺服器所使用的最大堆棧段記憶體。預設為

        11、定義ACL位址名(即用于上面的<address_match_list>)。注意,如果要使用

        這裡定義的清單名,必須先定義,後使用!

        例如:

        acl intranet {

        192.168/16;

        acl partner {

        !172.16.0.1;

        172.16/12; // 除172.168.0.1外172.16.0.0/12網絡中其它主機

        BIND已内置以下四個ACL:

        all // 允許所有主機

        none // 禁止所有主機

        localhost // 本機的所有網絡接口

        localnets // 本機所在網絡

        12、BIND域名伺服器的一個有用功能(慎用!!!):

        控制管理接口controls節文法格式:

        controls {

        [ inet ip_addr

        port ip_port

        allow { <address_match_list>; }; ]

        [ unix path_name

        perm number

        owner number

        group number; ]

        controls節提供管理接口。如果使用第一種(inet),則在指定IP(接口)和端

        口上監聽,但隻允許在allow中限定允許與其連接配接的IP位址清單。如果使用第二種

        (unix),則産生一個FIFO的控制管道,權限、屬主和使用者組都由其參數限定。

        ---[[ 通過TSIG對區域記錄傳輸進行認證和校驗 ]]---------------------------

        首先請確定你的BIND域名伺服器軟體已更新到最新版本!

        在BIND 8.2+中,能夠使用事務簽名(Transaction Signatures,即TSIG!)

        來對區域記錄資料進行驗證和校驗。它要求在主域名伺服器和輔助域名伺服器上配

        置好加密密鑰,并通知伺服器使用該密鑰與其它域名伺服器通訊。(注意,TSIG的

        使用要求域名伺服器必須進行時鐘同步!)

        A、如果需要用TSIG簽名來進行安全的DNS資料庫手工更新,具體操作步驟很簡單:

        1、使用BIND自帶的dnskeygen工具生成TSIG密鑰。

        # dnskeygen -H 128 -h -n tsig-key.

        則會生成兩個檔案。'Ktsig-key.+157+00000.key'内容如下:

        tsig-key. IN KEY 513 3 157 awwLOtRfpGE+rRKF2+DEiw==

        'Kvip-key.+157+00000.private'内容如下:

        Private-key-format: v1.2 Algorithm: 157 (HMAC) Key: awwLOtRfpGE+rRKF2+DEiw==

        注意這些密鑰都已經過BASE64編碼了。将它們放到本地域名伺服器的配置檔案中。例如

        :

        key tsig-key. { algorithm hmac-md5; secret "awwLOtRfpGE+rRKF2+DEiw=="; };

        zone "dns.nsfocus.com" {

        ...

        allow-update { key tsig-key. ; };

        記住要重新開機named守護程序。

然後将這兩個密鑰檔案複制到用戶端系統(或輔助域名伺服器),例如為/var

        /named/tsig目錄。最後運作如下指令即可:

        nsupdate -k /var/named/tsig:tsig-key.

        B、如果需要對區域記錄傳輸(自動或手工)進行TSIG簽名,則:

        1、用dnskeygen生成TSIG密鑰,方法同上。

        2、主域名伺服器配置檔案的内容(節選)如下:

        // 定義認證的方法和共享密鑰

        key master-slave {

        algorithm hmac-md5;

        secret "mZiMNOUYQPMNwsDzrX2ENw==";

        // 定義輔助域名伺服器的一些特性

        server 192.168.8.18 {

        transfer-format many-answers;

        keys { master-slave; };

        // 區域記錄定義

        zone "nsfocus.com" {

        type master;

        file db.nsfocus.com;

        allow-transfer { 192.168.8.18; };

        3、輔助域名伺服器配置檔案的内容(節選)如下:

        // 定義與主域名伺服器通訊時的一些特性

        server 192.168.8.19 {

        type slave;

        file "bak.db.nsfocus.com";

        masters { 192.168.8.19; };

        allow-transfer { none; };

        ---[[ 實施DNSSec功能 ]]-------------------------------------------------

        說實在的,我一直在考慮需不需要在目前的版本中實施DNSSec功能。因為雖然ISC

        早已在BIND 8.1.x版本後增加了DNSSec的實作,但實際的應用卻不常見,而且去年

        公布的NXT遠端安全漏洞和DNSSec有關(實際上NXT就屬于DNSSec實作的功能之一)。

        最後我決定在本文不讨論如何實施DNSSec安全功能。

        但不可否認,DNSSec确實是一項很好的安全技術,它通過加密DNS資料來提高了DNS

        服務的安全性。主加密密鑰用于對第一級域名的加密密鑰進行加密簽字,第一級域

        名(.com, .cn等)密鑰用于對自身資料及其子域名密鑰進行加密簽名,以此類推。

        例如,nsfocus.com的域名伺服器由.com域密鑰簽名,nsfocus.com域密鑰則用于對

        www.nsfocus.com域名進行加密簽名。

        ---[[ 實作BIND的chroot ]]---------------

        (以FreeBSD系統平台為例)

        步驟一:BIND-8的最新源代碼版本擷取和安裝

        請到ISC FTP站點下載下傳BIND的最新版本。

        BIND 8:http://www.isc.org/products/BIND/bind8.html

        BIND 9:http://www.isc.org/products/BIND/bind9.html

        步驟二:構造靜态(static)的named和named-xfer二進制檔案

        在編譯和安裝後,你需要構造可執行檔案的靜态連結版本。隻要對%BIND%/src

        /port/freebsd目錄下的Makefile.set檔案稍加修改後即可。

修改檔案内容:

        'CDEBUG= -O2 -g'

        替換為:

        'CDEBUG= -O2 -static'

        切換到BIND的源代碼路徑,執行"make clean"和"make"指令。在下面的步驟中

        将會把這些檔案複制到chroot()目錄下。

        # cd /tmp/bind/src

        # make clean ; make

        本步驟構造的靜态連結執行檔案在運作時無需裝載動态連結庫。在chroot()環

        境中,這種“獨立”可執行檔案可避免出現缺少連結庫檔案問題。它在chroot()環

        境中無需任何靜态連結庫,可使服務配置簡單化。其它所有的網絡守護程序也可以

        編譯和使用這種靜态連結版本。

        步驟三:構造BIND目錄

        為chroot()環境構造BIND目錄。這個目錄将在chroot()環境中被BIND當作系統

        根目錄。在這裡我使用/chroot/bind作為chroot後的根目錄。

        # cd /chroot/bind

        # mkdir /chroot

        # mkdir /chroot/dev

        # mkdir /chroot/etc

        # mkdir /chroot/etc/namedb

        # mkdir /chroot/usr

        # mkdir /chroot/usr/sbin

        # mkdir /chroot/var

        # mkdir /chroot/var/run

需要複制以下檔案到其下的相應子目錄中,和進行一些必要的處理:

        # cp /etc/namedb/named.conf /chroot/bind/etc/

        # cp /etc/localtime /chroot/bind/etc/

        # grep bind /etc/group > /chroot/bind/etc/group

        # cp -R /etc/namedb/ /chroot/bind/etc/namedb/

        # mknod /chroot/bind/dev/null c 2 2

        # chmod 666 /chroot/bin/dev/null

        # cp /tmp/bind/src/bin/named/named /chroot/bind/usr/sbin/

        # cp /tmp/bind/src/bin/named-xfer/named-xfer /chroot/bind/

        另外還可根據需要指定日志記錄目錄(如/var/log),請參考下面的章節或

        named.conf的手冊頁。

        步驟四:添加bind使用者群組(如果沒有的話。如果已經有bind或named之類的使用者

        群組,請跳過本步驟。)

        在/etc/passwd和/etc/group檔案中添加bind使用者群組。它們是DNS伺服器運作

        時的UID/GID。

        此時,你可以到chroot環境中執行"chown -R bind.bind /chroot/bind/etc/

        namedb"指令。這樣當你向系統發送中斷信号(kill -INT )時,named程序能夠儲存

        伺服器緩存和統計資訊。如果該目錄為root所有則named程序無法将輸出寫到目錄

        中,但不會影響named伺服器功能。另一個選擇是僅改變目錄權限(使named使用者具

        有寫權限),而屬主仍然是root。這種方法也是可行的,但必須小心設定,確定其

        它使用者不會修改named記錄!

        *** 重要警告***

        不要用一個已存在的UID/GID(如"nobody")運作named。記住,以chroot環境

        中使用任何已存在的UID/GID都可能會影響到服務的安全性。必須養成在chroot環

        境中為每一個守護程序提供獨立的UID/GID的習慣。

        步驟五:其它必要調整

如果在named.conf中還指定了另外的目錄和檔案,也要相應地在chroot()環境

        中(在本例中即/chroot/bind/目錄)進行設定。

        步驟六:調試

        1、終止系統中原有的syslogd和named守護程序。

        # killall syslogd named

        2、用适當的參數重新啟動syslogd守護程序。

        # syslogd -s -p /chroot/bind/var/run/log

        3、用适當參數重新啟動named守護程序。

        # /chroot/bind/named -u bind -g bind -t /chroot/bind

        4、檢查syslogd/named守護程序、監聽端口是否正常,和/var/log/messages檔案

        中named程序啟動時是否正常。

        # ps auwx|grep syslogd

        root 5896 0.0 1.7 896 508 ?? Ss 9:44PM 0:00.10 syslogd -s -p

        /chroot/bind/var/run/log

        # ps auwx|grep named

        bind 5941 0.0 4.9 1652 1444 ?? Is 9:52PM 0:00.01

        /chroot/bind/usr/sbin/named -u bind -g bind -t /chroot/bind

        # netstat -an|grep 53

        tcp4 0 0 127.0.0.1.53 *.* LISTEN

        tcp4 0 0 192.168.8.19.53 *.* LISTEN

        udp4 0 0 127.0.0.1.53 *.*

        udp4 0 0 192.168.8.19.53 *.*

        步驟七:修改系統啟動腳本

對于FreeBSD系統,在/etc/rc.conf檔案中增加如下内容即可:

        syslogd_enable="YES"

        # 如果希望禁止向外發送日志,将-s換成-ss。

        syslogd_flags="-s -p /chroot/bind/var/run/log"

        named_enable="YES"

        named_program="/chroot/bind/usr/sbin/named"

        named_flags="-u bind -g bind -t /chroot/bind"

注:如果在其它系統平台,如OpenBSD、Linux、Solaris,則可能會稍有不同。

        主要是不同平台上的syslog實作不盡相同。例如對于OpenBSD和Linux系統,打開日

        志别名socket的指令是"syslogd -a /chroot/bind/var/run/log",而Solaris的

        syslogd守護程序則不支援别名。是以Solaris系統平台上的chroot需要通過另外的

        方法實作,關于具體的實作過程我會在另外的文章中說明。

        ---[[ 結束語 ]]---------------------------------------------------------

安全增強配置的文章寫完了,但并不是說隻要你按本文提到的方法和技術實施

        就能萬無一失,高枕無憂了。其實以上設定對NXT和TSIG遠端漏洞攻擊并不沒太多

        的防禦作用,充其量隻不過是要編寫更多的shellcode代碼來突破chroot環境的限

        制。即使用allow-query等極其嚴格地限制查詢用戶端(實際上在網際網路上并不現

        實),基于UDP協定的TSIG攻擊技術也隻需構造僞造IP位址的資料包即可繞過其限

        制。

是以,在對BIND(還有其它應用服務)進行安全增強配置的基礎上,安全管理

        員仍然需要密切關注最新的安全公告、安全更新檔和安全技術,經常與專業的計算機

        安全專家交流知識和經驗,再輔以必要的安全産品和安全服務,才能更充分地保護

        好自己的網絡和計算機使用者,抵禦各種惡意攻擊。

繼續閱讀