Profile picture

DNS 서버 구축하기

JaehyoJJAng2023년 06월 11일

DNS 실습 (Ubuntu)

필수 패키지 설치

1. bind9 패키지 설치

bind9은 DNS 서버를 구축하고 레코드를 관리할 수 있도록 도와주는 패키지이다.

sudo apt install -y bind9

2. resolvconf 패키지 설치

sudo apt install -y resolvconf

방화벽 허용

DNS에서 사용하는 기본 포트인 53번을 방화벽 단에서 허용해줘야 함.
(서버의 방화벽 정책에 따라서 ufw, firewalld 둘 중에 하나로 사용.)

# ufw
sudo ufw allow 53

# firewalld
sudo firewall-cmd --permanent --zone=public --add-service=dns
sudo firewall-cmd --reload

네임서버 등록하기

1. resolv.conf 파일 수정

/etc/resolv.conf

nameserver 127.0.0.53

127.0.0.53은 systemd-resolved가 DNS를 관리하기 위해 사용하는 IP 주소이다.

이제 /etc/resolv.conf 파일의 값을 수정해야 하는데

/etc/resolv.con를 수정할 경우, 서버가 재부팅 되었을 때 값이 초기화되는 문제가 발생한다.


그 이유는 /etc/resolv.conf의 값은 재부팅 시 /etc/resolvconf/resolv.conf.d/head의 값을 참조하여 가져오기 때문이다.

이를 해결하기 위해서는 /etc/resolv.conf가 아니라 /etc/resolvconf/resolv.conf.d/head의 값을 수정해줘야 한다.


/etc/resolvconf/resolv.conf.d/head

nameserver 127.0.0.1

위처럼 루프백 IP(127.0.0.1) 주소를 추가하면 자기 자신을 네임서버로 등록할 수 있다.

우리는 이 서버의 네임 서버가 자기 자신이 되도록해야 하기 때문에, 위와 같이 nameserver 값에 127.0.0.1을 추가하였다.


또는 아래와 같이 실제 서버 주소를 입력해도 된다.

nameserver 192.168.219.144

2. 서버 재부팅

sudo reboot

변경사항을 적용하기 위해 서버를 재부팅하도록 하자.

만약 서버를 재부팅하기 어려운 상황이라면 /etc/resolv.conf를 직접 수정하는 것도 하나의 방법이 될 수 있다.


zone 기본 구성 이해하기

cd /etc/bind 명령어를 통해 bind 디렉토리로 이동한 후,

vim named.conf.default-zones 명령어를 통해 파일을 열어보자.
image
이 파일에는 추가된 zone에 대한 정보가 담겨있다. 여기서 zone 이란 도메인의 정보를 의미한다.

  • type: master / slave 중 어느 타입인지 설정.
    • 이번 실습에서는 단일 서버로만 테스트를 할 것 이기에 master로 설정하였음.
  • file: zone file의 위치를 설정

먼저, 기본적으로 제공되는 zone 파일인 db.local 파일을 자세하게 살펴보도록 하자.


/etc/bind/db.local
image


zone 파일에 들어가는 값에 대한 설명은 아래와 같다.

  • TTL: DNS 서버 정보가 캐시될 수 있는 시간, DNS 서버 정보의 데이터 유효 기간을 결정
  • SOA: 해당 Domain에 대한 기본적인 속성을 지정
    • Serial : 일련번호
    • Refresh : DNS 서버에 대한 정보를 새로고침하는 시간 간격
    • Retry : DNS 서버에 재시도 요청을 보내는 시간 간격
    • Expire : DNS 서버로부터 정보를 갱신하기 전에 기다리는 최대 시간 간격
    • Negative Cashe TTL : DNS 서버에 정상적인 응답이 없는 경우, 응답을 캐시하는 시간 간격
  • NS: 해당 domain을 관리하는 서버 정의
  • A: domain 이름과 IP 주소를 매핑 (IPv4 주소 정의)
  • AAAA: domain 이름과 IP 주소를 매핑 (IPv6 주소 정의)
  • CNAME: 해당 domain 이름에 새로운 별칭을 정의
  • MX: 해당 domain에서 이메일을 처리하는 메일 서버 지정
  • TXT: 해당 도메인에 대한 추가 정보를 포함하는 텍스트 데이터를 작성

zone 파일 생성하기

이제 jaehyo-test.domain.com 이라는 도메인에 대한 zone 파일을 생성해보도록 하자.


/etc/bind/db.jaehyo-test-domain.com.zone
image



코드 설명

$TTL 1D
  • 이 설정은 모든 레코드의 기본 TTL(Time to Live)을 1일(1D)로 설정합니다.
  • TTL은 캐시 서버가 레코드를 보관할 시간을 지정합니다.

image

  • @는 현재 도메인(jaehyo-test-domain.com.)을 의미합니다.
  • IN은 인터넷 클래스를 나타냅니다.
  • SOA는 Start of Authority 레코드를 나타내며, 도메인에 대한 기본 정보를 제공합니다.
  • jaehyo-test-domain.com.은 마스터 네임 서버입니다.


image

  • 0 ; Serial
    • 이 숫자는 영역 파일의 버전을 나타냅니다. 파일이 변경될 때마다 이 번호를 증가시켜야 합니다.
  • 1D ; Refresh
    • 네임 서버가 존 파일을 얼마나 자주 갱신해야 하는지를 지정합니다. 여기서는 1일마다 갱신하도록 설정되어 있습니다.
  • 1H ; Retry
    • 갱신 실패 시 다시 시도하기까지의 시간을 지정합니다. 여기서는 1시간 입니다.
  • 1W ; Expire
    • 네임 서버가 갱신 시도를 포기하고 데이터가 만료되기까지의 시간을 지정합니다. 여기서는 1주일 입니다.
  • 3H ; Negative Cache TTL
    • 존재하지 않는 도메인에 대한 부정적 응답을 캐시할 시간을 지정합니다. 여기서는 3시간 입니다.


image

  • NS 레코드는 도메인의 네임 서버를 지정합니다. 여기서는 dns.jaehyo-test-domain.com.이 네임 서버입니다.

image

  • A 레코드는 IPv4 주소로 매핑합니다. 여기서는 DNS 서버 주소인 192.168.219.154로 매핑됩니다.

image

  • 서브 도메인 ftp을 IP 주소 192.168.219.154로 매핑합니다.
    • 도메인은 ftp.jaehyo-test-domain.com로 접속 가능합니다.

image

  • CNAME 레코드는 별칭을 지정합니다. 여기서는 www 서브 도메인이 jaehyo-test-domain.com.의 별칭입니다.
    • 도메인은 www.jaehyo-test-domain.com로 접속 가능합니다.
  • 마찬가지로, test 서브도메인이 jaehyo-test-domain.com.의 별칭입니다.
    • 도메인은 npm.jaehyo-test-domain.com로 접속 가능합니다.

지금까지 작성한 db.jaehyo-test-domain.com.zone 파일은

jaehyo-test-domain.com. 도메인과 관련된 다양한 DNS 레코드를 정의하며,

기본 네임 서버 설정과 몇 가지 서브도메인 설정을 포함하고 있습니다.


zone 파일 등록하기

이제 지금까지 작성한 db.jaehyo-test-domain.com.zone 파일을 bind9에서 읽어올 수 있도록 등록해줘야 한다.


/etc/bind/named.conf.default-zones 파일 맨 마지막에 해당 내용을 추가해주자.

/etc/bind/named.conf.default-zones

zone "jaehyo-test-domain.com" {
  type master;
  file "/etc/bind/db.jaehyo-test-domain.com.zone";
};

file 필드에서 지정한 zone 파일을 읽어들인다.


named.conf.options 설정하기

자체 DNS 서버를 사용하기 위해 Options 파일을 아래와 같이 설정해주자.


/etc/bind/named.conf.options

options {
  # .... 생략 ....

	forwarders {
	  8.8.8.8;
	};

	allow-query-cache {
	  192.168.219.0/24;
	};

  # .... 생략 ....
};
  • forwarders: 자체 DNS 서버에 해당되는 쿼리가 없는 경우, 외부 DNS 서버에 쿼리를 전달하고 해당 결과를 반환하는 역할을 하는 구성요소
  • allow-query-cache: 자체 DNS 서버를 사용할 대상의 IP 혹은 CIDR을 지정하여 접근을 허용하는 구성요소

유효성 검증

/etc/bind/db.jaehyo-test-domain.com.zone 파일에 들어간 설정이 문제가 없는지 확인하기 위해

named-checkconf, named-checkzone 파일을 사용해 유효성 검증을 해주도록 하자.

named-checkconf /etc/bind/named.conf.default.zones
named-checkzone jaehyo-test-domain.com /etc/bind/db.jaehyo-test-domain.com

명령어를 실행했을 때 별다른 에러 로그가 없다면 통과한 것이다.


bind9 재시작

모든 설정이 끝났으므로, bind9을 재시작해주자.

sudo systemctl restart bind9

테스트

1. DNS 서버에서 테스트

nslookup 명령어를 사용하여 테스트

nslookup이 없는 경우 아래 명령어를 실행하여 설치

sudo apt install -y dnsutils

input

nslookup jaehyo-test-domain.com

output
image
성공적으로 DNS를 구축했다면 위와 같은 output을 확인할 수 있을 것이다.


도메인으로 ping을 날려도 정상적으로 동작한다.

ping -c 2 jaehyo-test-domain.com

image


2. 타 서버에서 테스트

DNS 서버 주소를 8.8.8.8(구글 DNS)에서 위에서 구축한 DNS 서버 IP 주소로 변경

sudo sed -i 's/8\.8\.8\.8/192.168.219.144/g' /etc/netplan/00-installer-config.yaml

netplan 변경내용 적용

sudo netplan apply

nslookup 명령으로 도메인 주소가 정상적으로 검색되는지 확인

nslookup npm.jaehyohome.com

image


트러블슈팅

내부 다른 서버에서 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 명령어로 /etc/bind 파일 목록 확인

$ ls -lh /var/named
-rw-r--r-- 1 root root 2.4K Feb 12  2024 bind.keys
-rw-r--r-- 1 root root  237 Sep 20  2023 db.0
-rw-r--r-- 1 root root  271 Apr 12  2023 db.127
-rw-r--r-- 1 root root  237 Apr 12  2023 db.255
-rw-r--r-- 1 root root  353 Apr 12  2023 db.empty
-rw-r--r-- 1 root root  270 Apr 12  2023 db.local
-rw-r--r-- 1 root bind  421 Oct  4 10:57 db.jaehyo-test-domain.com.zone
-rw-r--r-- 1 root bind  272 Nov 27 09:35 db.onpremise-project.com.zone
-rw-r--r-- 1 root bind  463 Sep 20  2023 named.conf
-rw-r--r-- 1 root bind  680 Nov 27 09:34 named.conf.default-zones
-rw-r--r-- 1 root bind  165 Apr 12  2023 named.conf.local
-rw-r--r-- 1 root bind  862 Oct  4 10:33 named.conf.options
-rw-r----- 1 bind bind  100 Apr  5  2024 rndc.key
-rw-r--r-- 1 root root 1.3K Oct  4 10:34 zones.rfc1918

jaehyo-test-domain.com.zone 파일의 그룹 소유권이 named가 아닌 root로 되어있었음.


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

$ chown root:bind *.zone*

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

systemctl restart bind9
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)

해결 완료!


Loading script...