웹사이트 검색

신뢰할 수 있는 BIND DNS 서버에서 DNSSEC를 설정하는 방법


DNSSEC 정보

우리 모두는 DNS가 도메인 이름을 IP 주소로 확인하는 프로토콜이라는 것을 알고 있지만 반환된 IP 주소의 신뢰성을 어떻게 알 수 있습니까? 공격자가 DNS 응답을 변조하거나 DNS 캐시를 오염시키고 주소 표시줄에 합법적인 도메인 이름이 있는 악의적인 사이트로 사용자를 데려갈 수 있습니다. DNSSEC(DNS Security Extensions)는 DNS 응답의 데이터 무결성 유지를 목표로 하는 사양입니다. DNSSEC는 PKI(Public Key Infrastructure)를 사용하여 영역의 모든 DNS 리소스 레코드(A, MX, CNAME 등)에 서명합니다. 이제 DNSSEC 지원 DNS 리졸버(예: Google 공개 DNS)는 공개 DNSKEY 레코드를 사용하여 DNS 회신(IP 주소 포함)의 신뢰성을 확인할 수 있습니다.

DNSSEC 리소스 레코드

리소스 레코드(RR)에는 도메인에 대한 특정 정보가 포함되어 있습니다. 몇 가지 일반적인 레코드는 도메인의 IP 주소를 포함하는 A 레코드, IPv6 정보를 포함하는 AAAA 레코드 및 도메인의 메일 서버를 포함하는 MX 레코드입니다. DNS RR의 전체 목록은 여기에서 찾을 수 있습니다.

마찬가지로 DNSSEC에도 여러 RR이 필요합니다.

  • DNSKEY 확인자가 확인하는 데 사용하는 공개 키를 보유합니다.
  • RRSIG 각 RR에 대해 존재하며 레코드의 디지털 서명을 포함합니다.
  • DS - 위임 서명자 – 이 레코드는 TLD의 이름 서버에 있습니다. 따라서 example.com이 도메인 이름인 경우 TLD는 \com이고 이름 서버는 a.gtld-servers.net., b.gtld-servers.net. 입니다. 최대 m.gtld-servers.net.. 이 레코드의 목적은 DNSKEY 자체의 신뢰성을 확인하는 것입니다.

설정 환경

도메인 이름: example.com

이를 위해 실제 .COM 도메인을 사용했지만 이 기사에서는 example.com으로 대체했습니다.

마스터 네임서버:

슬레이브 네임서버:

파일 위치 및 이름

BIND의 구성 및 영역 파일의 이름과 위치는 사용되는 Linux 배포판에 따라 다릅니다.

데비안/우분투

서비스 이름:

CentOS/페도라

서비스 이름:

bind-chroot를 사용하는 경우 변경될 수 있습니다. 이 튜토리얼에서는 Master NS에 Debian을, Slave NS에 CentOS를 사용했으므로 배포판에 따라 변경하십시오.

DNSSEC 마스터 구성

options{ } 내부에 다음 구성 지시문을 추가하여 DNSSEC를 활성화합니다.

nano /etc/bind/named.conf.options

dnssec-enable yes;
dnssec-validation yes;
dnssec-lookaside auto;

일부 배포판에 이미 추가되어 있을 수 있습니다. 영역 파일의 위치로 이동합니다.

cd /var/cache/bind

다음 명령을 사용하여 영역 서명 키(ZSK)를 생성합니다.

dnssec-keygen -a NSEC3RSASHA1 -b 2048 -n ZONE example.com

haveged를 설치했다면 이 키가 생성되는 데 몇 초밖에 걸리지 않습니다. 그렇지 않으면 매우 오랜 시간이 걸립니다. 샘플 출력.

root@master:/var/cache/bind# dnssec-keygen -a NSEC3RSASHA1 -b 2048 -n ZONE example.com
Generating key pair..................+++ .............+++
Kexample.com.+007+40400

다음 명령을 사용하여 키 서명 키(KSK)를 생성합니다.

dnssec-keygen -f KSK -a NSEC3RSASHA1 -b 4096 -n ZONE example.com

샘플 출력.

root@master:/var/cache/bind# dnssec-keygen -f KSK -a NSEC3RSASHA1 -b 4096 -n ZONE example.com
Generating key pair......................++ .............................................................................................................................................................................................................++
Kexample.com.+007+62910

디렉토리에는 이제 4개의 키(ZSK 및 KSK의 개인/공용 쌍)가 있습니다. DNSKEY 레코드를 포함하는 공개 키를 영역 파일에 추가해야 합니다. 다음 for 루프가 이를 수행합니다.

for key in `ls Kexample.com*.key`
do
echo "\$INCLUDE $key">> example.com.zone
done

dnssec-signzone 명령으로 영역에 서명합니다.

dnssec-signzone -3 <salt> -A -N INCREMENT -o <zonename> -t <zonefilename>

소금을 임의의 것으로 교체하십시오. 다음은 출력의 예입니다.

root@master:/var/cache/bind# dnssec-signzone -A -3 $(head -c 1000 /dev/random | sha1sum | cut -b 1-16) -N INCREMENT -o example.com -t example.com.zone
Verifying the zone using the following algorithms: NSEC3RSASHA1.
Zone signing complete:
Algorithm: NSEC3RSASHA1: KSKs: 1 active, 0 stand-by, 0 revoked
                        ZSKs: 1 active, 0 stand-by, 0 revoked
example.com.zone.signed
Signatures generated:                       14
Signatures retained:                         0
Signatures dropped:                          0
Signatures successfully verified:            0
Signatures unsuccessfully verified:          0
Signing time in seconds:                 0.046
Signatures per second:                 298.310
Runtime in seconds:                      0.056

16자 문자열을 "salt\로 입력해야 합니다. 다음 명령

head -c 1000 /dev/random | sha1sum | cut -b 1-16

소금으로 사용될 16자의 임의 문자열을 출력합니다.

그러면 각 DNS 레코드에 대한 RRSIG 레코드가 포함된 example.com.zone.signed라는 새 파일이 생성됩니다. BIND에게 이 "서명된\ 영역을 로드하도록 지시해야 합니다.

nano /etc/bind/named.conf.local

zone { } 섹션 내에서 file 옵션을 변경합니다.

zone "example.com" IN {
    type master;
    file "example.com.zone.signed";
    allow-transfer { 2.2.2.2; };
    allow-update { none; };
};

이 파일을 저장하고 바인드를 다시 로드하십시오.

service bind9 reload

동일한 서버에서 dig를 사용하여 DNSKEY 레코드가 있는지 확인합니다.

dig DNSKEY example.com. @localhost +multiline

샘플 출력

root@master:/var/cache/bind# dig DNSKEY example.com. @localhost +multiline
;; Truncated, retrying in TCP mode.

; <<>> DiG 9.8.4-rpz2+rl005.12-P1 <<>> DNSKEY example.com. @localhost +multiline
;; global options: +cmd
;; Got answer:
;; ->>HEADER<<- opcode: QUERY, status: NOERROR, id: 43986
;; flags: qr aa rd; QUERY: 1, ANSWER: 2, AUTHORITY: 0, ADDITIONAL: 0
;; WARNING: recursion requested but not available

;; QUESTION SECTION:
;example.com.       IN DNSKEY

;; ANSWER SECTION:
example.com.        86400 IN DNSKEY   256 3 7 (
                AwEAActPMYurNEyhUgHjPctbLCI1VuSj3xcjI8QFTpdM
                8k3cYrfwB/WlNKjnnjt98nPmHv6frnuvs2LKIvvGzz++
                kVwVc8uMLVyLOxVeKhygDurFQpLNNdPumuc2MMRvV9me
                fPrdKWtEEtOxq6Pce3DW2qRLjyE1n1oEq44gixn6hjgo
                sG2FzV4fTQdxdYCzlYjsaZwy0Kww4HpIaozGNjoDQVI/
                f3JtLpE1MYEb9DiUVMjkwVR5yH2UhJwZH6VVvDOZg6u6
                YPOSUDVvyofCGcICLqUOG+qITYVucyIWgZtHZUb49dpG
                aJTAdVKlOTbYV9sbmHNuMuGt+1/rc+StsjTPTHU=
                ) ; key id = 40400
example.com.        86400 IN DNSKEY   257 3 7 (
                AwEAAa2BE0dAvMs0pe2f+D6HaCyiFSHw47BA82YGs7Sj
                qSqH3MprNra9/4S0aV6SSqHM3iYZt5NRQNTNTRzkE18e
                3j9AGV8JA+xbEow74n0eu33phoxq7rOpd/N1GpCrxUsG
                kK4PDkm+R0hhfufe1ZOSoiZUV7y8OVGFB+cmaVb7sYqB
                RxeWPi1Z6Fj1/5oKwB6Zqbs7s7pmxl/GcjTvdQkMFtOQ
                AFGqaaSxVrisjq7H3nUj4hJIJ+SStZ59qfW3rO7+Eqgo
                1aDYaz+jFHZ+nTc/os4Z51eMWsZPYRnPRJG2EjJmkBrJ
                huZ9x0qnjEjUPAcUgMVqTo3hkRv0D24I10LAVQLETuw/
                QOuWMG1VjybzLbXi5YScwcBDAgtEpsQA9o7u6VC00DGh
                +2+4RmgrQ7mQ5A9MwhglVPaNXKuI6sEGlWripgTwm425
                JFv2tGHROS55Hxx06A416MtxBpSEaPMYUs6jSIyf9cjB
                BMV24OjkCxdz29zi+OyUyHwirW51BFSaOQuzaRiOsovM
                NSEgKWLwzwsQ5cVJBEMw89c2V0sHa4yuI5rr79msRgZT
                KCD7wa1Hyp7s/r+ylHhjpqrZwViOPU7tAGZ3IkkJ2SMI
                e/h+FGiwXXhr769EHbVE/PqvdbpcsgsDqFu0K2oqY70u
                SxnsLB8uVKYlzjG+UIoQzefBluQl
                ) ; key id = 62910

;; Query time: 0 msec
;; SERVER: 127.0.0.1#53(127.0.0.1)
;; WHEN: Wed Nov 27 18:18:30 2013
;; MSG SIZE  rcvd: 839

RRSIG 레코드가 있는지 확인하십시오.

dig A example.com. @localhost +noadditional +dnssec +multiline
; <<>> DiG 9.8.4-rpz2+rl005.12-P1 <<>> A example.com. @localhost +noadditional +dnssec +multiline
;; global options: +cmd
;; Got answer:
;; ->>HEADER<<- opcode: QUERY, status: NOERROR, id: 32902
;; flags: qr aa rd; QUERY: 1, ANSWER: 2, AUTHORITY: 3, ADDITIONAL: 5
;; WARNING: recursion requested but not available

;; OPT PSEUDOSECTION:
; EDNS: version: 0, flags: do; udp: 4096
;; QUESTION SECTION:
;example.com.         IN A

;; ANSWER SECTION:
example.com.          86400 IN A 93.184.216.119
example.com.          86400 IN RRSIG A 7 2 86400 20131227171405 (
                            20131127171405 40400 example.com.
                            JCoL8L7As1a8CXnx1W62O94eQl6zvVQ3prtNK7BWIW9O
                            lir/4V+a6c+0tbt4z4lhgmb0sb+qdvqRnlI7CydaSZDb
                            hlrJA93fHqFqNXw084YD1gWC+M8m3ewbobiZgBUh5W66
                            1hsVjWZGvvQL+HmobuSvsF8WBMAFgJgYLg0YzBAvwHIk
                            886be6vbNeAltvPl9I+tjllXkMK5dReMH40ulgKo+Cwb
                            xNQ+RfHhCQIwKgyvL1JGuHB125rdEQEVnMy26bDcC9R+
                            qJNYj751CEUZxEEGI9cZkD44oHwDvPgF16hpNZGUdo8P
                            GtuH4JwP3hDIpNtGTsQrFWYWL5pUuuQRwA== )

;; AUTHORITY SECTION:
example.com.          86400 IN NS master.example.com.
example.com.          86400 IN NS slave.example.com.
example.com.          86400 IN RRSIG NS 7 2 86400 20131227171405 (
                            20131127171405 40400 example.com.
                            hEGzNvKnc3sXkiQKo9/+ylU5WSFWudbUc3PAZvFMjyRA
                            j7dzcVwM5oArK5eXJ8/77CxL3rfwGvi4LJzPQjw2xvDI
                            oVKei2GJNYekU38XUwzSMrA9hnkremX/KoT4Wd0K1NPy
                            giaBgyyGR+PT3jIP95Ud6J0YS3+zg60Zmr9iQPBifH3p
                            QrvvY3OjXWYL1FKBK9+rJcwzlsSslbmj8ndL1OBKPEX3
                            psSwneMAE4PqSgbcWtGlzySdmJLKqbI1oB+d3I3bVWRJ
                            4F6CpIRRCb53pqLvxWQw/NXyVefNTX8CwOb/uanCCMH8
                            wTYkCS3APl/hu20Y4R5f6xyt8JZx3zkZEQ== )

;; Query time: 0 msec
;; SERVER: 127.0.0.1#53(127.0.0.1)
;; WHEN: Thu Nov 28 00:01:06 2013
;; MSG SIZE  rcvd: 1335

마스터 서버의 구성이 완료되었습니다.

DNSSEC 슬레이브 구성

슬레이브 서버는 DNSSEC를 활성화하고 영역 파일 위치를 변경하기만 하면 됩니다. BIND의 기본 구성 파일을 편집합니다.

nano /etc/named.conf

이 행이 존재하지 않는 경우 options { } 섹션 안에 배치하십시오.

dnssec-enable yes;
dnssec-validation yes;
dnssec-lookaside auto;

zone { } 섹션 내에서 file 옵션을 편집합니다.

zone "example.com" IN {
    type slave;
    file "example.com.zone.signed";
    masters { 1.1.1.1; };
    allow-notify { 1.1.1.1; };
};

BIND 서비스를 다시 로드하십시오.

service named reload

.signed 영역 파일이 있는지 확인합니다.

[root@slave ~]# ls -l /var/named/slaves/
total 16
-rw-r--r-- 1 named named  472 Nov 27 17:25 example.com.zone
-rw-r--r-- 1 named named 9180 Nov 27 18:29 example.com.zone.signed

짜잔! 그게 다야. 제대로 작동하는지 확인하려면 이전 섹션에서 언급한 대로 dig를 사용하여 DNSKEY를 쿼리하십시오.

등록기관으로 DS 레코드 구성

.signed 영역 파일과 별도로 dnssec-signzone 명령을 실행했을 때 dsset-example.com이라는 파일도 생성되었습니다. DS 레코드를 포함합니다.

root@master:/var/cache/bind# cat dsset-example.com.
example.com.        IN DS 62910 7 1 1D6AC75083F3CEC31861993E325E0EEC7E97D1DD
example.com.        IN DS 62910 7 2 198303E265A856DE8FE6330EDB5AA76F3537C10783151AEF3577859F FFC3F59D

도메인 등록 기관의 제어판에 입력해야 합니다. 아래 스크린샷은 GoDaddy의 단계를 보여줍니다.

도메인 등록 기관의 제어판에 로그인하고 도메인을 선택한 다음 DS 레코드 관리 옵션을 선택합니다. GoDaddy의 제어판은 다음과 같습니다.

다음은 dsset-example.com. 파일의 데이터 분할입니다.

DS 레코드 1:

키 태그: 62910

DS 레코드 2:

키 태그: 62910

dsset-example.com. 파일의 두 번째 DS 레코드는 다이제스트에 공백이 있었지만 양식에 입력할 때는 생략해야 합니다. 다음을 클릭하고 마침을 클릭한 다음 레코드를 저장합니다.

이러한 변경 사항을 저장하는 데 몇 분 정도 걸립니다. DS 레코드가 생성되었는지 확인하려면 TLD의 이름 서버를 쿼리하십시오. TLD의 네임서버를 찾는 대신 훨씬 더 간단한 dig +trace를 수행할 수 있습니다.

root@master:~# dig +trace +noadditional DS example.com. @8.8.8.8 | grep DS
; <<>> DiG 9.8.2rc1-RedHat-9.8.2-0.17.rc1.el6_4.6 <<>> +trace +noadditional DS example.com. @8.8.8.8
example.com.          86400   IN      DS      62910 7 2 198303E265A856DE8FE6330EDB5AA76F3537C10783151AEF3577859F FFC3F59D
example.com.          86400   IN      DS      62910 7 1 1D6AC75083F3CEC31861993E325E0EEC7E97D1DD

이것이 확인되면 다음 온라인 서비스를 사용하여 DNSSEC가 제대로 작동하는지 확인할 수 있습니다.

  • http://dnssec-debugger.verisignlabs.com
  • http://dnsviz.net/

첫 번째 도구는 단순한 도구인 반면 두 번째 도구는 사물을 시각적으로 표현합니다. 다음은 첫 번째 도구의 스크린샷입니다.

내가 표시한 줄을 확인하십시오. 첫 번째는 DS 레코드의 키 태그 값(62910)을 언급하고 두 번째는 ZSK(영역 서명 키)를 보유하는 DNSKEY 레코드의 키 ID(40400)를 언급합니다. ).

구역 레코드 수정

레코드를 추가하거나 제거하여 영역을 편집할 때마다 작동하려면 서명해야 합니다. 그래서 우리는 매번 긴 명령을 입력할 필요가 없도록 이에 대한 스크립트를 만들 것입니다.

root@master# nano /usr/sbin/zonesigner.sh

#!/bin/sh
PDIR=`pwd`
ZONEDIR="/var/cache/bind" #location of your zone files
ZONE=$1
ZONEFILE=$2
DNSSERVICE="bind9" #On CentOS/Fedora replace this with "named"
cd $ZONEDIR
SERIAL=`/usr/sbin/named-checkzone $ZONE $ZONEFILE | egrep -ho '[0-9]{10}'`
sed -i 's/'$SERIAL'/'$(($SERIAL+1))'/' $ZONEFILE
/usr/sbin/dnssec-signzone -A -3 $(head -c 1000 /dev/random | sha1sum | cut -b 1-16) -N increment -o $1 -t $2
service $DNSSERVICE reload
cd $PDIR

파일을 저장하고 실행 가능하게 만드십시오.

root@master# chmod +x /usr/sbin/zonesigner.sh

레코드를 추가하거나 제거하려는 경우 .signed 파일이 아닌 example.com.zone을 편집하십시오. 이 파일은 또한 일련 값 증가를 처리하므로 파일을 편집할 때마다 이를 수행할 필요가 없습니다. 편집 후 도메인 이름과 영역 파일 이름을 매개변수로 전달하여 스크립트를 실행합니다.

root@master# zonesigner.sh example.com example.com.zone

증분된 시리얼이 영역이 전송되고 업데이트되면 보장하므로 슬레이브 네임서버에서 아무것도 할 필요가 없습니다.

Zone Walking에서 DNSSEC 설정 보호

Zone Walking은 NSEC(Next-Secure) 레코드를 쿼리하여 해당 영역의 모든 리소스 레코드를 찾는 데 사용되는 기술입니다. NSEC3이 릴리스되어 솔트를 사용하여 이 정보를 \해시\했습니다. -3 옵션을 지정한 dnssec-signzone 명령을 기억하십시오. 임의의 문자열을 생성하는 또 다른 정교한 명령으로 이것은 다음 dig 쿼리를 사용하여 찾을 수 있는 소금입니다.

# dig NSEC3PARAM example.com. @master.example.com. +short
1 0 10 7CBAA916230368F2

이 모든 것이 존 워킹을 어렵게 만들지만 불가능하지는 않습니다. Kexample.com.*.private를 사용하는 단호한 해커).

root@master:~# crontab -e

0       0       */3     *       *       /usr/sbin/zonesigner.sh example.com example.com.zone

이것은 3일마다 영역에 서명하고 결과적으로 새로운 소금이 생성됩니다. 또한 dnssec-signzone 명령의 출력이 포함된 이메일을 받게 됩니다.

제출자: 제신A