DNS 란
네트워크 상에서 컴퓨터는 IP를 이용하여 서로를 구별하고 통신합니다. 다른 컴퓨터에 접속하기 위해서는 해당 컴퓨터의 IP 주소를 알고 있어야 하지만 IP 주소는 의미 없는 숫자여서 기억하기가 어렵습니다. 그 문제를 해결하기 위해 DNS가 탄생했습니다. DNS는 도메인 이름을 IP 주소로 변경해 주거나 반대로 IP 주소를 도메인 이름으로 변경해 주는 기능을 합니다. 도메인이란 우리가 알고 있는 “naver.com”처럼 사이트에 방문하기 위한 URL 주소를 말합니다.
nslookup 명령은 도메인 이름을 입력하면 DNS 서버에게 질의해서 IP 주소를 확인합니다. 또는 그와 반대로 IP 주소를 입력하면 도메인 이름을 알려줍니다. nslookup 명령을 통해서 “naver.com”의 IP 주소를 질문하도록 하겠습니다.
질문에 답변한 서버는 “172.19.140.7” IP를 가지고 있는 서버입니다. 지금 SK LTE를 이용해서 인터넷을 사용하고 있는 환경이고 “172.19.140.7” 주소는 SKT에서 제공하고 있는 DNS 서버입니다. 이처럼 주요 통신사에서는 DNS 서버를 구축해 제공하고 있으며 DNS 서버는 인터넷을 사용하기 위한 필수 구성요소입니다.
예를 들어 “kisa.or.kr” 도메인처럼 .kr로 끝나는 도메인 주소는 우리나라 국가 도메인 주소입니다. .kr이라는 도메인 주소를 알고 있는 서버가 여러 개 존재하며 이들 DNS 서버가 모두 종료된다면 .kr을 사용하는 주소는 아무도 접근할 수 없게 됩니다. 그래서 이런 중요한 DNS 서버들을 여러 위치에 두고 관리하게 됩니다.
<출처: https://krnic.kisa.or.kr/jsp/resources/dns/dnsInfo.jsp>
사용 가능한 외부 DNS 서버 주소
DNS 서버는 통신사 뿐 아니라 국내 및 해외 여러 기관에서 운영하고 있습니다. 우리가 사용하는 통신사 별 DNS 서버 주소는 다음과 같습니다. 이게 전부는 아니고 대표적인 몇 개의 DNS 서버 주소입니다. 이 외에도 굉장히 많은 DNS 서버가 존재합니다.
KT DNS
168.126.63.1
168.126.63.2
SK Broadband
210.220.163.82
219.250.36.130
SKT
172.19.140.7
LG U+
164.124.101.2
203.248.252.2
61.41.153.2
1.214.68.2
그 밖에 통신사가 아닌 곳에서도 DNS 서버를 제공하고 있습니다.
8.8.8.8
8.8.4.4
환경
Redhat Enterprise linux (RHEL)
목표
간단하게 DNS가 무엇인지 알아봤습니다. 이제부터는 DNS 서버를 직접 구축해 보도록 하겠습니다. 이번 실습의 목표는 내부에서 사용하는 아래의 도메인 주소를 오픈시프트 내부 서버들이 사용할 수 있도록 하는 데 있습니다.
api.sno.example.com <-> 192.168.243.200
api-int.sno.example.com <-> 192.168.243.200
*.apps.sno.example.com <-> 192.168.243.200
DNS 서버에서 위 3개의 도메인 주소를 물어보면 IP 주소로 변환하여 알려줍니다. 또한 그 반대로 IP 주소를 입력하면 도메인 주소를 알려주는데 이를 역방향 조회라고 합니다.
DNS 서버 설치
많은 DNS 서버가 제공되고 있지만 직접 DNS 서버를 구축하는 이유는 성능 개선 및 외부 DNS를 활용하지 않음으로 보안을 강화하는 이유 등 여러 가지가 있습니다.
bind 패키지를 활용하여 DNS 서버를 구축해 보도록 하겠습니다. bind 패키지는 레드햇 OS에 포함되어 있는 서비스여서 레드햇 설치 이미지에서 패키지를 구할 수 있습니다. 레포 구성 방법은 Local Repo 구성 여기를 참조하실 수 있습니다.
- dnf 명령을 사용하여 bind 패키지를 설치합니다.
# dnf install bind
...
============================================================================================================================================================================
Package Architecture Version Repository Size
============================================================================================================================================================================
Installing:
bind x86_64 32:9.11.36-8.el8_8.1 rhel-8-for-x86_64-appstream-rpms 2.1 M
Upgrading:
bind-libs x86_64 32:9.11.36-8.el8_8.1 rhel-8-for-x86_64-appstream-rpms 176 k
bind-libs-lite x86_64 32:9.11.36-8.el8_8.1 ...
Transaction Summary
============================================================================================================================================================================
...
Complete!
DNS 설정 파일 편집
bind 패키지를 설치하면 DNS의 주 설정 파일인 “/etc/named.conf” 파일이 생성됩니다. 해당 파일을 수정하여 외부에서 접근 가능하도록 설정하고 example.com의 존 파일을 추가하도록 하겠습니다.
- named.conf 파일의 기본 설정을 수정 및 추가합니다. 각 항목에 대한 설명은 주석을 참고합니다.
# vim /etc/named.conf
...
options {
listen-on port 53 { any; }; ## 외부에서 포트 접근 가능하도록 설정
listen-on-v6 port 53 { ::1; } ## IPv6설정 제거
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";
allow-query { any; }; ## 외부에서 DNS질의 가능 하도록 설정
...
recursion yes;
allow-recursion { localhost; 192.168.243.0/24; }; ## 재귀적인 쿼리를 허용하는 IP를 제한
...
공인 IP 주소로 재귀적인 쿼리를 허용하면 악의적인 공격자가 대량의 재귀적인 쿼리를 보내 서버의 부하를 증가시킬 수 있습니다. 재귀적인 쿼리는 DNS 서버가 다른 DNS 서버로부터 정보를 가져오는 과정에서 발생하는 쿼리를 말합니다.
- example.com 도메인 주소의 존 파일을 설정합니다. 이 설정도 named.conf 파일에 추가됩니다.
DNS 서버가 도메인 주소를 IP로 변경하려면 DNS ↔ IP 매핑 정보를 알고 있는 설정이 필요합니다. 설정 파일의 가장 아랫부분에 zone 블록을 추가합니다.
# vim /etc/named.conf
...
zone "example.com" IN {
type master;
file "example.com.zone";
allow-update { none; };
};
zone "243.168.192.in-addr.arpa" IN {
type master;
file "example.com.reverse.zone";
allow-update { none; };
};
...
위에 zone 설정을 2개 하였습니다. 각 zone 블록에 위치한 “file”로 시작되는 부분이 실제 zone 정보를 불러오기 위해 DNS 서버에서 찾는 도메인/IP 매핑 정보가 담긴 파일의 위치입니다. DNS 서버는 해당 파일을 /var/named 디렉터리 위치에서 찾습니다.
따라서 /var/named 디렉터리 아래 example.com.zone과 example.com.reverse.zone 파일을 생성 후 각 파일에 정보를 기록하면 됩니다.
ZONE 파일 생성
- 첫 번째 존 파일을 생성합니다. 이 파일은 도메인 주소를IP주소로 변경해주는 레코드를 설정하고 있습니다.
# vim /var/named/example.com.zone
$TTL 1D
@ IN SOA dns.sno.example.com. root.example.com. (
2023083101 ; serial
3h ; refresh
15 ; retry
1w ; expire
3h ; minimum
)
IN NS dns.sno.example.com.
dns.sno IN A 192.168.243.169
api.sno IN A 192.168.243.200
api-int.sno IN A 192.168.243.200
*.apps.sno IN A 192.168.243.200
위 내용에서 192.168.243.169는 현재 구성중인 DNS서버의 주소입니다.
- 역방향 존 파일을 생성합니다. 이 파일은 IP 주소를 도메인 주소로 변경하는 레코드를 설정하고 있습니다.
# vi /var/named/example.com.reverse.zone
$TTL 1D
@ IN SOA dns.sno.example.com. root.example.com. (
2023083101 ; serial
3h ; refresh
15 ; retry
1w ; expire
3h ; minimum
)
IN NS dns.sno.example.com.
200 IN PTR api.sno.example.com.
200 IN PTR api-int.sno.example.com.
DNS설정은 끝났습니다. 서비스를 재시작 하기 전에 방금 설정한 설정 파일이 어떤 의미인지 알아봅니다.
DNS 레코드 영역은 크게 SOA 레코드와 DNS 서버 그리고 도메인에 대한 IP 주소 할당 항목으로 분리할 수 있습니다. 각 영역에 어떤 항목이 들어가는지 살펴보도록 하겠습니다.
- SOA 레코드 영역 설명
## SOA 레코드 영역
@ IN SOA dns.sno.example.com. root.example.com. (
2023083101 ; serial
3h ; refresh
15 ; retry
1w ; expire
3h ; minimum
)
- @(영역 이름): @를 사용할 경우 /etc/named.conf에서 설정한 영역 이름(example.com)으로 사용한다.
- IN(클래스): SOA 레코드에서는 이 필드를 항상 IN(Internet)으로 설정합니다.
- SOA(type): SOA 레코드에서는 이 필드를 항상 SOA로 설정합니다.
- dns.sno.example.com.: 이름, 서버의 호스트 이름
- root.example.com.: 관리자 메일 주소
(아래의 serial, refresh, expire, minimum은 DNS 서버를 이중화 할 시 사용하는 내용)
- serial: zone 파일의 버전 번호, 수정사항이 발생할 때마다 번호를 하나씩 올려준다.
- refresh: 보조 DNS 서버에서 주 DNS 서버의 정보 변경을 확인하는데 대기하는 시간.
- retry: 주 DNS 서버에서 쿼리를 실패할 경우 재시도 하기 위해 대기하는 시간.
- expire: 보조 DNS 서버가 주 DNS 서버로 접근이 되지 않을때 이전에 받아놓은 주 DNS서버의 정보를 언제까지 설정할지 지정하는 시간
- minimum: DNS 서버가 잘못된 도메인 이름 오류를 캐시하는 기간을 설정, 잘못된 정보가 오랫동안 캐시되지 않도록 보장하는 기능
- DNS 서버 주소 영역 설명
IN NS dns.sno.example.com.
# DNS서버 주소를 설정합니다.
- 도메인에 대한 IP주소 할당 설명
# 각 도메인에 대한 실제 IP주소 매핑 합니다. DNS주소에 해당하는 IP정보가 포함되어 있어야 합니다.
dns.sno IN A 192.168.243.169
api.sno IN A 192.168.243.200
api-int.sno IN A 192.168.243.200
*.apps.sno IN A 192.168.243.200
방화벽 활성화 및 DNS서비스 시작
[root@bastion ~]# firewall-cmd --add-service=dns
success
[root@bastion ~]# firewall-cmd --add-service=dns --permanent
success
[root@bastion ~]# systemctl start named
도메인 주소 확인 (검증)
먼저 bastion 서버의 주소로 DNS를 바라보게 설정되어 있는지 확인합니다.
# cat /etc/resolv.conf
nameserver 192.168.243.169
dig 명령을 이용해 도메인에서 처음 목표로 했던 아래의 정보가 IP → 도메인 매핑이 잘 되는지 확인합니다.
# dig api.sno.example.com | grep "ANSWER SECTION" -A 1
;; ANSWER SECTION:
api.sno.example.com. 86400 IN A 192.168.243.200
# dig api-int.sno.example.com | grep "ANSWER SECTION" -A 1
;; ANSWER SECTION:
api-int.sno.example.com. 86400 IN A 192.168.243.200
# dig test.apps.sno.example.com | grep "ANSWER SECTION" -A 1
;; ANSWER SECTION:
test.apps.sno.example.com. 86400 IN A 192.168.243.200
이번에는 nslookup 명령을 이용해 IP → 도메인 변환이 잘 되는지 확인합니다.
# nslookup 192.168.243.200
200.243.168.192.in-addr.arpa name = api-int.sno.example.com.
200.243.168.192.in-addr.arpa name = api.sno.example.com.
마무리
리눅스에서 제공하는 DNS 서버 설정하는 방법에 대해 알아봤습니다. 오픈시프트 설치와 같이 테스트 목적으로 DNS 서버가 꼭 필요한 경우에는 위 방법처럼 간단하게 bind 패키지를 설치하여 구성할 수 있습니다.
참고로 DNS 서버는 운영 환경에서 사용하기 위해 이중화로 구성되어야 합니다. 본 문서에서는 테스트 용으로 주 DNS 서버 하나만 구축되었습니다.