Profile picture

[CentOS 7] DNS 서버 구축하기

JaehyoJJAng2023년 06월 07일

◾️ DNS

DNS

네트워크에서 도메인이나 호스트 이름을 숫자로 표기된 IP 주소로 해석해주는 TCP/IP 네트워크 서비스를 의미.

bind

DNS 서버를 구축 / 운영하기 위한 데몬 프로그램.
또한 유닉스(Unix) 및 리눅스(Linux), 윈도우 등 거의 모든 플랫폼을 지원하는 DNS의 모든 기능을 갖춘 소프트웨어.


▪️ bind 설치

배포판 리눅스에서 사용되는 대표적인 DNS는 bind이다. bind는 패키지 형태로 제공되고 있으며, Redhat 배포판에서는 yum 명령어를 사용하여 설치할 수 있다.

yum update -y
yum install -y bind bind-chroot bind-utils

▪️ named.conf 설정

bind 설치가 완료됐다면 /etc/named.conf 설정파일이 생성된다.
네임서버 데이터베이스 및 zone 파일의 위치, 접근제어등의 보안설정을 할 수 있는 메인 설정파일이다. /etc/named.conf 파일을 열어 설정을 바꿔보도록 하자.


  • 1. 기본 설정은 127.0.0.1(Localhost)에 리스닝하기 때문에, 외부에서는 DNS 접근이 불가능하다. 서버에 설정된 모든 IP에 대해 리스닝하거나 특정 IP 대역에 대해 리스닝 할 수 있도록 변경할 수 있다.
    • options.listen-on port 53 {127.0.0.1; [외부대역망]; [내부대역망];}; : 특정 IP 대역 리스닝
    • options.listen-on port 53 {any;}; : 모든 IP 대역 리스닝
  • 2. 네임서버에 설정된 도메인만 응답하도록 설정
    • options.allow-query {localhost; [외부대역망]; [내부대역망];} : 외부에서 오는 query에 대해 특정 IP만 허용
    • options.allow-query {any;} : 외부에서 오는 query에 대해 모든 IP 허용
  • 3. options.mastefile-format text;를 추가하여 slave에서 zone 파일이 동기화 될 때 text로 변환되어 저장되도록 함.
  • 4. DNS 서버가 로컬에서 해결할 수 없는 도메인 이름에 대한 쿼리를 외부 DNS 서버로 전달하도록 설정
    • options.forwarders {8.8.8.8; 8.8.4.4;};
  • 5. 내부 네트워크에서 도메인 이름 해결을 위해 내부 뷰를 사용하며, 루트 힌트 및 기타 필요한 설정과 함께 특정 도메인에 대한 추가적인 DNS 정보를 로드하도록 설정.
    • view "internal: { ...; include "/var/named/[원하는 도메인명].shop.zones";} : 특정 도메인에 대한 추가적인 DNS 정보를 "/var/named/[원하는 도메인명].shop.zones" 파일에서 로드하도록 설정

/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";
        recursing-file  "/var/named/data/named.recursing";
        secroots-file   "/var/named/data/named.secroots";
        allow-query     { localhost; [퍼블릭 대역폭]; [프라이빗 대역폭]; };
        forwarders { 8.8.8.8; 8.8.4.4; }; 

        recursion yes;

        dnssec-enable yes;
        dnssec-validation yes;

        /* Path to ISC DLV key */
        bindkeys-file "/etc/named.root.key";

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

        pid-file "/run/named/named.pid";
        session-keyfile "/run/named/session.key";
};

logging {
        channel default_debug {
                file "data/named.run";
                severity dynamic;
        };
};

view "internal" {
        zone "." IN {
                type hint;
                file "named.ca";
        };

        include "/etc/named.rfc1912.zones";
        include "/var/named/[원하는 도메인명].shop.zones";
};

image


• validation check

/etc/named.conf 설정을 완료하고 설정에 문제가 없는지 확인하기 위해 'validation check'를 하도록 하자.

named-checkconf /etc/named.conf

명령어를 통해 /etc/named.conf에 문제가 없는지 확인할 수 있다.
명령어 입력 시 아무 내용이 출력되지 않는다면 문제가 없다고 보면 된다.


• domain zone 정보 추가

네임서버에 쿼리 요청시 사용할 도메인 정보(정방향 영역과 역방향영역)을 설정해야될 부분이다.
본래라면 /etc/named.rfc1912.zones 파일의 맨 하단 부분에 추가할 domain zone 정보를 추가해야한다.

예를 들어, 추가할 도메인 정보의 경우 jaehyo.shop 도메인을 사용하려면
"jaehyo.shop.zone([도메인].zone)" 파일을 만들어야 한다.


/etc/named.rfc1912.zones

...
zone "jaehyo.shop" IN {
        type master;
        file "jaehyo.shop.zone";
        allow-update { none; };
};

그러나 필자의 경우 '/etc/named.conf' 파일의 view 섹션에 include "/var/named/[원하는 도메인명].shop.zones"; 라고 기입 해두었으니 /var/named 경로에 domain zone들을 추가할 zones 파일을 만들어줄거다.


/var/named/jaehyo.shop.zones



...
zone "[설정한 도메인명]" IN {
        type master;
        file "[설정한 도메인명].shop.zone"; # .db 대신 .zone 이라고 적든 아무 이름으로 적든 상관은 없다.
        allow-update { none; };
};

zone "[프라이빗 대역폭 역주소].in-addr.arpa" IN {
        type master;
        file "[프라이빗 대역폭 역주소].in-addr.arpa.zone";
        allow-update { none; };	
};

필자의 경우 역주소에 대한 zone 정보도 추가하였다.
image


/var/named/jaehyo.shop.zones 파일 또한 오류가 없는지 named-checkconf로 확인해보자.

$ named-checkconf /var/named/jaehyo.shop.zones

• zone 파일 생성 및 권한 변경

/var/named/jaehyo.shop.zones에 입력한 도메인 zone 파일을 생성해보자. 그리고 해당 zone 파일의 권한을 변경해주자.

/var/named/[설정한 도메인명].shop.db(=보통 /var/named/[설정한 도메인명].zone 파일로 만들기는 함.)은 네임서버 설정시 가장 중요한 도메인 정보 파일이다.

네임서버 기동시에 zone 파일(/var/named/[설정한 도메인명].shop.db)를 읽어 네임서버 서비스가 가동되며, zone 파일은 도메인을 IP 주소로 변환해 주는 역할을 한다.

$ cp -R /var/named/named.localhost /var/named/[설정한 도메인명].shop.zone
$ cp -R /var/named/named.localhost /var/named/[프라이빗 대역폭 역주소].in-addr.arpa.zone

# 권한 수정
$ chown root:named /var/named/*.zone

파일이름은 /var/naemd/jaehyo.shop.zones에서 각 zone에 정의된 file명을 사용해야 한다.
image


• zone 파일 레코드 수정

zone 파일의 규칙 및 domain에 연결할 IP 레코드를 추가하자.


/var/named/[설정한 도메인명].shop.zone

$TTL    86400	
@       IN      SOA     [설정한 도메인].shop.   root.[설정한 도메인].shop.(
                        2022041401 ; Serial  // 시리얼 값
                        3h         ; Refresh // 보조 네임서버가 주 네임서버에 접속하는 시간
                        1h         ; Retry   // 접속 실패시 다시 시도할 시도 간격
                        1w         ; Expire  // 주네임서버에서 데이터가 없다면 1주 이후에 지워짐
                        1h )       ; Minimum // TTL 설정과 같은 의미

        IN      NS      ns.[설정한 도메인].shop.
        IN      MX 10   ns.[설정한 도메인].shop.
ns      IN      A       [DNS 서버 주소]
web     IN      A       [WEB 서버 주소]
  • IN NS ns.[설정한 도메인].shop.
    • 이 레코드는 해당 도메인에 대한 네임 서버(NS)를 나타냅니다. 여기서 ns.[설정한 도메인].shop.는 이 도메인에 대한 네임 서버의 FQDN (Fully Qualified Domain Name)을 나타냅니다. 이 도메인을 위해 존 파일에서 지정된 네임 서버의 주소를 찾을 수 있게 됩니다.
  • IN MX 10 ns.[설정한 도메인].shop.
    • 이 레코드는 메일 서버(MX) 레코드입니다. MX 레코드는 메일을 받을 서버를 지정합니다. 여기서 10은 우선순위를 나타내며, ns.[설정한 도메인].shop.는 이 도메인의 메일 서버의 FQDN을 나타냅니다. 이 설정은 이 도메인에 메일을 전송할 때 사용되는 메일 서버를 정의합니다.
  • ns IN A [DNS 서버 주소]
    • 이 레코드는 DNS 서버를 나타냅니다. ns는 호스트의 이름을 나타내며, A는 이 호스트의 IPv4 주소를 나타냅니다. 여기서 [DNS 서버 주소]는 설정된 DNS 서버의 IPv4 주소입니다.
  • web IN A [WEB 서버 주소]
    • 이 레코드는 웹 서버를 나타냅니다. web은 호스트의 이름을 나타내며, A는 이 호스트의 IPv4 주소를 나타냅니다. [WEB 서버 주소]는 설정된 웹 서버의 IPv4 주소입니다.

image


/var/named/[프라이빗 대역폭 역주소].in-addr.arpa.zone

$TTL    86400
@       IN      SOA     [설정 도메인].shop. root.[설정 도메인].shop.(
                        2022041401 ; Serial
                        3h         ; Refresh
                        1h         ; Retry
                        1w         ; Expire
                        1h )       ; Minimum

        IN      NS      ns.[설정 도메인].shop.
[끝주소]     IN      PTR     ns.[설정 도메인].shop.
[끝주소]     IN      PTR     web.[설정 도메인].shop.
EOF
  • @ IN NS ns.[설정 도메인].shop.
    • 해당 존의 기본 네임 서버(NS) 레코드를 설정합니다.
  • [끝주소] IN PTR ns.[설정 도메인].shop.
    • IP 주소에 대한 PTR(Pointer) 레코드로, 해당 IP 주소의 역방향 DNS 조회시 반환되는 이름을 설정합니다.
  • [끝주소] IN PTR web.[설정 도메인].shop
    • 또 다른 IP 주소에 대한 PTR 레코드로, 해당 IP 주소의 역방향 DNS 조회시 반환되는 이름을 설정합니다.

image


• /etc/resolv.conf에 DNS 등록

/etc/resolv.conf 파일에 DNS 서버주소를 등록해주자

$ cat >> /etc/resolv.conf << EOF
nameserver 10.21.0.100

• DHCP 환경인 경우

DHCP로 내부망에 IP가 할당되고 있는 경우 내부 서버들의 DNS 주소를 바꾸려면 DHCP 서버에서 /etc/dhcp/dhcpd.conf 설정을 바꿔줘야 한다.


운용중인 DHCP 서버로 이동한 후 /etc/dhcp/dhcpd.conf 파일을 수정하자.

$ vi /etc/dhcp/dhcpd.conf

...
option domain-name-servers [DNS 서버 주소] 8.8.8.8, 8.8.4.4;

image


그리고 DHCP 서버의 외부망 NIC의 설정을 아래처럼 변경

$ vi /etc/sysconfig/network-scripts/ifcfg-[외부망 포트이름]

image
DNS1에 DNS 서버 주소 추가


• named 재기동

$ systemctl enable --now named
$ systemctl restart named

• DNS 테스트

nslookup 명령어를 사용하여 zone에 도메인을 등록한 값 입력하여 정방향(domain -> IP) 값 도출하기

nslookup
> web.jaehyo.shop
Server:		10.21.0.100
Address:	10.21.0.100#53

Name:	web.jaehyo.shop
Address: 10.21.0.101

▪️ 트러블슈팅

내부 다른 서버에서 ping ns.jaehyo.shop을 해보니 도메인을 찾을 수 없다고 뜸.
마찬가지로 ping web.jaehyo.shop 해봐도 동일한 상태.

DNS 서버의 로그를 볼 필요가 있어보임.


DNS 서버로 가서 named 서비스 재시작

$ systemctl restart named

그리고 journalctl -xe로 가장 최근 로그 확인

$ journalctl -xe | grep 'master'
1116 14:33:35 dns-prac named[1149]: zone 0.21.10.in-addr.arpa/IN/internal: loading from master file 0.21.10.in-addr.arpa.zone failed: permission denied
1116 14:33:35 dns-prac named[1149]: zone jaehyo.shop/IN/internal: loading from master file jaehyo.shop.zone failed: permission denied
1116 14:33:35 dns-prac postfix/master[1320]: daemon started -- version 2.10.1, configuration /etc/postfix
1116 14:36:17 dns-prac named[1694]: zone 0.21.10.in-addr.arpa/IN/internal: loading from master file 0.21.10.in-addr.arpa.zone failed: permission denied
1116 14:36:17 dns-prac named[1694]: zone jaehyo.shop/IN/internal: loading from master file jaehyo.shop.zone failed: permission denied

권한 거부가 뜸.


ls -lh 명령어로 /var/named 파일 목록 확인

$ ls -lh /var/named
-rw-r-----. 1 root  root  413 1116 14:01 0.21.10.in-addr.arpa.zone
drwxr-x---. 7 root  named   61 1116 12:36 chroot
drwxrwx---. 2 named named   23 1116 12:49 data
drwxrwx---. 2 named named   60 1116 12:49 dynamic
-rw-r-----. 1 root  root  456 1116 14:29 jaehyo.shop.zone
-rw-r--r--. 1 root  root  246 1116 14:20 jaehyo.shop.zones
-rw-r-----. 1 root  named 2.3K  45  2018 named.ca
-rw-r-----. 1 root  named  152 1215  2009 named.empty
-rw-r-----. 1 root  named  152  621  2007 named.localhost
-rw-r-----. 1 root  named  168 1215  2009 named.loopback
drwxrwx---. 2 named named    6 1016 22:26 slaves

zones 파일 및 zone 파일들의 그룹 소유권이 named가 아닌 root로 되어있었음!


zone 파일 및 zones 파일의 그룹 소유권 변경

$ chown root:named *.zone*

named 서비스 재시작 후 journalctl 명령어 실행하여 로그 다시 확인

$ systemctl restart names
$ journalctl -xe | tail -n 5
-- The start-up result is done.
1116 14:45:02 dns-prac named[1784]: zone 0.21.10.in-addr.arpa/IN/internal: sending notifies (serial 2022041401)
1116 14:45:02 dns-prac named[1784]: zone jaehyo.shop/IN/internal: sending notifies (serial 2022041401)

해결 완료!


◾️ named.conf에 대해

named.conf 파일은 네임서버 서비스가 시작될 때 제일 먼저 읽는 파일이다.


options {
		
       # 네임서버에 접속이 허용된 IP 주소	
        listen-on port 53 { any; };
        listen-on-v6 port 53 { none; };

       # 네임서버 DB 파일이 들어있는 디렉터리 
        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";

        secroots-file   "/var/named/data/named.secroots";
        recursing-file  "/var/named/data/named.recursing";
        
       # DNS 쿼리를 허용할 IP 설정
        allow-query     { any; };

       # 외부에서 네임서버 지정하여 허용/차단 옵션
        recursion yes;

       # dnssec 기능 활성화와 검증 설정
        dnssec-enable yes;
        dnssec-validation yes;

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

        pid-file "/run/named/named.pid";
        session-keyfile "/run/named/session.key";

        include "/etc/crypto-policies/back-ends/bind.config";
};

logging {

       # 디버깅 로그 설정
        channel default_debug {
                print-time yes;
                print-category yes;
                print-severity yes;
                file "data/named.run";
                severity dynamic;
        };

       # DNS 쿼리 로그 설정
        channel queries_log {
                print-time yes;
                print-category yes;
                print-severity yes;
                file "data/queries" versions 10 size 20M;
                severity info;
        };

       # DNS 쿼리 에러 로그 설정
        channel query-errors_log {
                print-time yes;
                print-category yes;
                print-severity yes;
                file "data/query-errors" versions 10 size 20M;
                severity dynamic;
        };

        category queries { queries_log; };
        category query-errors { query-errors_log; };
};

# 루트 도메인 지정
zone "." IN {

       # 네임서버 타입 지정 : hint(루트도메인), master(1차 네임서버), slave(2차 네임서버)
        type hint;
        file "named.ca";
};

# 외부 설정파일 경로 지정
include "/etc/named.rfc1912.zones";

# root 영역을 위한 DNS Key 파일 경로 지정
include "/etc/named.root.key";

# 도메인 존 이름 지정
zone "waytothem.org" IN {
		
       # 1차 네임서버 지정
        type master;

       # 도메인 존 파일 지정
        file "waytothem.org.db";
        
       # 2차 네임서버 주소 지정, none은 2차 네임서버 없음
        allow-update { none; };

named.conf 문법 검사

named.conf 설정 중 오타나 잘못된 내용으로 작성되었을 때 네임서버가 동작되지 않는다. 설정 파일의 오류를 찾는 것이 쉽지는 않은데 named-checkconf 명령어를 통해 입력한 내용이 틀렸는지 쉽게 확인이 가능하다


named-checkconf 명령을 사용하여 문법 오류가 없으면 아래와 같이 별도의 메시지가 없다

$ named-checkconf

Loading script...