Profile picture

[Ubuntu] 자체 DNS 서버 구축하기 (bind9)

JaehyoJJAng2023년 06월 11일

▶︎ 개요

홈 서버 운용 중 매번 IP로 특정 서비스에 들어가는 것이 번거로워서

이참에 DNS 서버를 구축해보려고 한다.


▶︎ 사전 준비

  • DNS를 구축할 물리 서버 또는 가상 머신 1대가 필요하다
    • OS: ubuntu 22.04

‣ 필수 패키지 설치

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

▶︎ DNS 구축하기


‣ 네임서버 등록하기

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를 직접 수정하는 것도 하나의 방법이 될 수 있다.


‣ DNS 설정

• 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

;
; BIND data file for local loopback interface
;
$TTL	604800
@	IN	SOA	localhost. root.localhost. (
			      2		; Serial
			 604800		; Refresh
			  86400		; Retry
			2419200		; Expire
			 604800 )	; Negative Cache TTL
;
@	IN	NS	localhost.
@	IN	A	127.0.0.1
@	IN	AAAA	::1

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 이라는 도메인에 대한 zoen 파일을 생성해보도록 하자.


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

$TTL  604800
@ IN  SOA jaehyo-test-domain.com. root.jaehyo-test-domain.com. (
            2   ; Serial
       604800   ; Refresh
        86400   ; Retry
      2419200   ; Expire
       604800 ) ; Negative Cache TTL
;
@ IN  NS jaehyo-test-domain.com.
@ IN A 127.0.0.1 # 루프백 주소 또는 메인 도메인의 IP 주소
ftp IN A 192.168.219.144
smb IN A 192.168.219.143
www IN CNAME jaehyo-test-domain.com.
npm IN CNAME jaehyo-test-domain.com.

코드 설명

  • $TTL 604800
    • 이 설정은 모든 레코드의 기본 TTL(Time to Live)을 604800초(7일)로 설정합니다. TTL은 캐시 서버가 레코드를 보관할 시간을 지정합니다.
  • @ IN SOA jaehyo-test-domain.com. root.jaehyo-test-domain.com. (
    • @는 현재 도메인(jaehyo-test-domain.com.)을 의미합니다.
    • IN은 인터넷 클래스를 나타냅니다.
    • SOA는 Start of Authority 레코드를 나타내며, 도메인에 대한 기본 정보를 제공합니다.
    • jaehyo-test-domain.com.은 마스터 네임 서버입니다.
    • root.jaehyo-test-domain.com.은 관리자 이메일 주소를 나타냅니다. 보통 @ 대신 .을 사용합니다.
  • 2 ; Serial
    • 이 숫자는 영역 파일의 버전을 나타냅니다. 파일이 변경될 때마다 이 번호를 증가시켜야 합니다.
  • 604800 ; Refresh
    • 네임 서버가 존 파일을 얼마나 자주 갱신해야 하는지를 지정합니다. 여기서는 7일마다 갱신하도록 설정되어 있습니다.
  • 86400 ; Retry
    • 갱신 실패 시 다시 시도하기까지의 시간을 지정합니다. 여기서는 1일입니다.
  • 2419200 ; Expire
    • 네임 서버가 갱신 시도를 포기하고 데이터가 만료되기까지의 시간을 지정합니다. 여기서는 28일입니다.
  • 604800 ) ; Negative Cache TTL
    • 존재하지 않는 도메인에 대한 부정적 응답을 캐시할 시간을 지정합니다. 여기서는 7일입니다.
  • @ IN NS jaehyo-test-domain.com.
    • NS 레코드는 도메인의 네임 서버를 지정합니다. 여기서는 jaehyo-test-domain.com.이 네임 서버입니다.
  • @ IN A 127.0.0.1
    • A 레코드는 도메인 이름을 IPv4 주소로 매핑합니다. 여기서는 루프백 주소인 127.0.0.1로 매핑됩니다.
  • ftp IN A 192.168.219.144
    • 서브도메인 ftp을 IP 주소 192.168.219.144로 매핑합니다.
    • 도메인은 ftp.jaehyo-test-domain.com로 접속 가능하다.
  • smb IN A 192.168.219.143
    • 서브도메인 smb을 IP 주소 192.168.219.143로 매핑합니다.
    • 도메인은 smb.jaehyo-test-domain.com로 접속 가능하다.
  • www IN CNAME jaehyo-test-domain.com.
    • CNAME 레코드는 별칭을 지정합니다. 여기서는 www 서브도메인이 jaehyo-test-domain.com.의 별칭입니다.
    • 도메인은 www.jaehyo-test-domain.com로 접속 가능하다.
  • npm IN CNAME jaehyo-test-domain.com.
    • 마찬가지로, npm 서브도메인이 jaehyo-test-domain.com.의 별칭입니다.
    • 도메인은 npm.jaehyo-test-domain.com로 접속 가능하다.

이 존 파일은 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 파일을 읽어들인다.


• 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을 지정하여 접근을 허용하는 구성요소

‣ 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


Loading script...