[리눅스] 네임(DNS) 서버 구축

목차

리눅스 DNS 서버 구축은 BIND(named) 패키지 하나로 시작할 수 있다. DNS(Domain Name System)는 사람이 읽는 도메인 이름과 컴퓨터가 쓰는 IP 주소를 서로 매핑해 주는 핵심 인터넷 서비스로, 자체 네임 서버를 운영하면 사내 도메인 해석이나 캐싱 서버를 직접 다룰 수 있다. 이 글에서는 CentOS/RHEL 환경에서 DNS 개념부터 BIND 설치 → named.conf 설정 → zone 파일(정·역방향) 작성 → 문법 검사·서비스 가동 → 방화벽 개방 → dig 테스트까지 전 과정을 순서대로 정리한다.

DNS와 네임 서버란

DNS는 Domain Name System의 약자로, 도메인 이름과 IP 주소 간의 매핑을 관리하는 서비스다. 사람이 읽을 수 있는 도메인 이름(예: www.amazon.com)을 머신이 읽는 IP 주소(예: 192.0.2.44)로 변환한다. 인터넷상의 모든 컴퓨터는 숫자로 된 IP 주소로 서로를 찾아 통신하는데, 사람이 그 숫자를 일일이 외울 수 없으니 대신 도메인 이름을 입력하면 DNS가 알아서 IP로 바꿔 준다. 흔히 DNS를 인터넷의 전화번호부에 비유하는 이유다.

네임 서버(name server)는 이 DNS 해석을 실제로 수행하는 서버다. CentOS·RHEL 계열에서 가장 널리 쓰이는 네임 서버 데몬이 바로 BIND(Berkeley Internet Name Domain)이며, 데몬 프로세스 이름은 named다. 이 글에서는 BIND를 설치해 특정 도메인에 대한 권한 있는(authoritative) 네임 서버를 직접 구축한다.

참고: DNS의 개념·동작 원리는 AWS 공식 문서에 잘 정리돼 있다. → DNS란 무엇인가? (AWS)

BIND 패키지 설치

리눅스 DNS 서버 BIND 패키지 설치

BIND 본체와 관리 유틸리티(dig·nslookup 등이 들어 있는 bind-utils)를 설치한다.

# 핵심 패키지 설치
dnf -y install bind bind-utils

# (필요 시 관련 패키지 전체)
dnf -y install bind*

설치가 끝났으면 rpm -qa로 설치된 bind 관련 패키지를 확인한다.

rpm -qa | grep bind
BIND 패키지 설치 확인

named.conf 설정

BIND의 주 설정 파일은 /etc/named.conf다. 수정 전에 원본을 백업해 두면 문제가 생겼을 때 되돌리기 쉽다.

cp /etc/named.conf /etc/named.conf.bak
vi /etc/named.conf

options 블록 수정

기본값은 로컬에서만 질의를 받도록 돼 있다. 외부(또는 사내망) 클라이언트의 질의를 받으려면 options 블록의 listen-onallow-query를 다음과 같이 연다. 모든 인터페이스/모든 클라이언트를 의미하는 any 대신, 실서버에서는 가능한 한 특정 IP·네트워크 대역으로 제한하는 편이 안전하다.

options {
    # listen-on port 53 { 127.0.0.1; };   ← 기본값
    listen-on port 53 { any; };            # 모든 인터페이스에서 수신
    listen-on-v6 port 53 { ::none; };      # IPv6 미사용 시

    # allow-query { localhost; };          ← 기본값
    allow-query { any; };                  # 모든 클라이언트 질의 허용

    dnssec-validation no;                  # 실습 편의를 위해 비활성(운영은 yes 권장)
};

zone 선언 추가

이어서 우리가 관리할 도메인에 대한 정방향(forward) zone역방향(reverse) zone을 선언한다. 정방향은 “이름 → IP”, 역방향은 “IP → 이름” 해석을 담당한다. 아래는 example.com 도메인과 192.168.111.0/24 대역을 예로 든 것이다. type master는 이 서버가 해당 zone의 권한 있는 1차 서버임을 뜻한다.

# /etc/named.conf 하단(또는 /etc/named.rfc1912.zones)에 추가

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

zone "111.168.192.in-addr.arpa" IN {
    type master;
    file "reverse.example.com";
    allow-update { none; };
};

역방향 zone 이름의 111.168.192.in-addr.arpa는 네트워크 대역 192.168.111을 거꾸로 적은 것이다. file에 적은 이름이 곧 /var/named/ 아래에 만들 zone 파일명이다.

named.conf options 및 zone 설정

zone 파일 작성

zone 파일은 모두 /var/named/ 디렉터리에 둔다. 직접 작성하기보다 기본 제공 샘플(named.localhost)을 복사해 시작하면 권한·소유자가 함께 보존돼 편하다.

cd /var/named
cp -p named.localhost forward.example.com
cp -p named.localhost reverse.example.com

정방향 zone 파일

/var/named/forward.example.com을 열어 다음처럼 작성한다. SOA(권한 시작) 레코드와 NS(네임 서버), 그리고 호스트별 A(주소) 레코드를 정의한다.

$TTL 86400
@   IN  SOA   ns1.example.com. root.example.com. (
        2024062501  ; Serial (변경 시마다 1 증가)
        3600        ; Refresh
        1800        ; Retry
        604800      ; Expire
        86400 )     ; Minimum TTL

        IN  NS    ns1.example.com.
        IN  A     192.168.111.100

ns1     IN  A     192.168.111.100
www     IN  A     192.168.111.100

역방향 zone 파일

/var/named/reverse.example.com에는 IP의 마지막 옥텟을 이름으로 되돌리는 PTR 레코드를 작성한다.

$TTL 86400
@   IN  SOA   ns1.example.com. root.example.com. (
        2024062501  ; Serial
        3600        ; Refresh
        1800        ; Retry
        604800      ; Expire
        86400 )     ; Minimum TTL

        IN  NS    ns1.example.com.
        IN  PTR   example.com.

100     IN  PTR   ns1.example.com.
100     IN  PTR   www.example.com.

소유자·권한 설정

named 프로세스는 named 계정으로 동작하므로, zone 파일 그룹 소유자를 named로 맞춰 줘야 읽기 권한 문제가 생기지 않는다.

chown root:named /var/named/forward.example.com
chown root:named /var/named/reverse.example.com

문법 검사와 서비스 가동

설정을 적용하기 전에 문법을 먼저 검사한다. named-checkconfnamed.conf를, named-checkzone은 개별 zone 파일을 검사한다. 아무 출력이 없으면 정상이고, zone 검사는 OK가 떠야 한다.

# 설정 파일 문법 검사 (출력 없으면 정상)
named-checkconf /etc/named.conf

# zone 파일 검사: named-checkzone <zone명> <파일경로>
named-checkzone example.com /var/named/forward.example.com
named-checkzone 111.168.192.in-addr.arpa /var/named/reverse.example.com

# 출력 예시
zone example.com/IN: loaded serial 2024062501
OK
named 문법 검사 및 서비스 상태 확인

문법에 이상이 없으면 named 서비스를 시작하고 부팅 시 자동 실행되도록 등록한다. --now 옵션을 붙이면 enable과 start를 한 번에 처리한다.

systemctl enable --now named
systemctl status named

상태가 active (running)이면 정상이다. DNS의 고유 포트는 53번이며, ss(또는 netstat) 명령으로 53번 포트가 열려 있는지 확인할 수 있다.

ss -tulnp | grep :53
# 또는
netstat -tulnp | grep :53

방화벽 개방

외부에서 이 네임 서버로 질의가 들어오려면 방화벽에서 DNS 서비스(TCP/UDP 53번)를 열어 줘야 한다. firewalld 환경에서는 미리 정의된 dns 서비스를 영구 규칙으로 추가하고 다시 로드한다.

firewall-cmd --permanent --add-service=dns
firewall-cmd --reload

# 적용 확인
firewall-cmd --list-all

dig로 DNS 테스트

이제 dig로 구축한 네임 서버가 질의에 제대로 응답하는지 확인한다. @ 뒤에 질의를 보낼 DNS 서버 IP를 적는다. 우리가 정의한 정방향 레코드를 물어보자.

# 정방향(이름 → IP) 질의
dig @192.168.111.100 www.example.com

# 응답의 ANSWER SECTION 예시
;; ANSWER SECTION:
www.example.com.   86400   IN   A   192.168.111.100

역방향(IP → 이름)은 -x 옵션으로 확인한다. 외부 도메인 해석까지 잘 되는지 보려면 임의의 공개 사이트도 함께 질의해 본다.

# 역방향(IP → 이름) 질의
dig @192.168.111.100 -x 192.168.111.100

# nslookup으로도 확인 가능
nslookup www.example.com 192.168.111.100
dig로 DNS 질의 결과 확인

윈도우 클라이언트에서 접속

윈도우 PC에서 구축한 DNS 서버를 사용하게 하려면, 네트워크 어댑터의 DNS 서버 주소를 우리 서버 IP로 지정하면 된다.

윈도우 네트워크 DNS 서버 주소 설정

제어판 → 네트워크 및 인터넷 → 네트워크 및 공유 센터 → 이더넷 → ‘이더넷 상태’에서 속성 → 인터넷 프로토콜 버전 4(TCP/IPv4) → 속성 → ‘다음 DNS 서버 주소 사용’을 체크하고 구축한 서버의 IP를 입력한다. 이후 웹 사이트에 정상 접속되면 우리 네임 서버를 통해 이름 해석이 이루어진 것이다.

윈도우에서 구축한 DNS 서버로 접속 확인

트러블슈팅과 FAQ

자주 겪는 문제

  • named 서비스가 시작되지 않을 때journalctl -u named -e로 로그를 확인한다. 대부분 zone 파일 문법 오류이거나 named.conffile 이름과 실제 파일명이 다른 경우다. named-checkconf·named-checkzone으로 먼저 잡는다.
  • zone 파일을 고쳤는데 반영이 안 될 때 — SOA의 Serial 값을 올렸는지 확인한다. Serial을 그대로 두면 BIND가 변경을 인식하지 못한다. 수정 후 systemctl reload named로 다시 읽힌다.
  • 외부에서 질의가 안 될 때 — ① allow-queryany(또는 해당 대역)인지 ② 방화벽에서 dns 서비스를 열었는지 ③ listen-on이 외부 인터페이스를 포함하는지 순서대로 점검한다.
  • Permission denied 오류 — zone 파일 그룹 소유자가 named인지(ls -l /var/named), SELinux가 막고 있지는 않은지 확인한다.

Serial(시리얼) 번호는 왜 올려야 하나?

SOA 레코드의 Serial은 zone 데이터의 “버전 번호”다. 2차(slave) 서버나 캐시는 이 값이 커졌을 때만 zone을 다시 가져온다. 그래서 레코드를 수정할 때마다 Serial을 1 이상 올려 주는 것이 원칙이며, 보통 YYYYMMDDNN(날짜+일련번호) 형식을 쓴다.

레코드 끝의 점(.)은 무슨 의미인가?

zone 파일에서 ns1.example.com.처럼 끝에 점이 붙으면 FQDN(완전한 도메인 이름)으로 더 이상 도메인이 붙지 않는다. 반대로 점이 없는 이름(예: www)에는 zone의 $ORIGIN(여기서는 example.com.)이 자동으로 붙는다. 끝점 하나를 빠뜨려 해석이 어긋나는 실수가 흔하니 주의한다.

정리

리눅스 DNS 서버 구축의 핵심 순서는 BIND(bind·bind-utils) 설치 → named.conf의 listen-on·allow-query 개방 및 zone 선언 → /var/named에 정·역방향 zone 파일 작성(SOA·NS·A·PTR) → named-checkconf·named-checkzone 검사 → systemctl enable –now named → 방화벽 dns 서비스 개방 → dig 테스트다. 특히 zone을 고칠 때마다 SOA Serial을 올리는 것, 외부 질의가 안 될 때 allow-query·방화벽·listen-on을 함께 점검하는 것을 기억하면 대부분의 문제는 빠르게 해결된다. DNS에서 쓰는 IP·네트워크 설정이 더 궁금하다면 네트워크 명령어 및 설정 파일 글도 함께 참고하면 좋다.

💬 댓글 0

💬 댓글을 남기려면?
첫 댓글을 남겨보세요 ✨

이 콘텐츠가 도움이 됐나요?

누스쿨 커뮤니티에서 더 많은 커리어 전략을 나눠요