설명
CentOS 7에서 DNS 서비스를 설치하고 간단한 환경설정을 해봅니다.
서버 정보
버전 정보: bind-9.11.26-6
마스터 서버: 192.168.80.171
SELinux 비활성화
DNS 서버에서 SELinux를 사용하지 않으므로 비활성화 합니다.
### Inactive the SELinux ###
[root@localhost ~]# sed -i 's/SELINUX=enforcing/SELINUX=disabled/g' /etc/selinux/config
[root@localhost ~]# reboot
Firewall에 DNS 서비스 추가
외부에서 DNS 서버로 접속할수 있도록, 파이어월에 dns 서비스를 추가합니다.
### Register dns service in the firewall ###
[root@localhost ~]# firewall-cmd --permanent --add-service=dns
[root@localhost ~]# firewall-cmd --reload
추가한 dns 서비스가 파이어월 서비스 리스트에 등록되었는지 확인합니다.
### Check the service list registered in the firewall ###
[root@localhost ~]# firewall-cmd --list-services
cockpit dhcpv6-client dns nfs proftpd ssh
dns 서비스의 포트 구성을 확인합니다.
### Check the dns service information in the firewall ###
[root@localhost ~]# firewall-cmd --info-service=dns
dns
ports: 53/tcp 53/udp
protocols:
source-ports:
modules:
destination:
includes:
helpers:
패키지 설치
DNS 서비스에 필요한 패키지를 설치합니다.
### Install the BIND package ###
[root@localhost ~]# yum -y install bind bind-chroot bind-utils
DNS 서비스 활성화
bind와 bind-chroot 패키지를 설치하면, 각각 named와 named-chroot 데몬이 생성됩니다. chroot 기능이 포함된 DNS 서비스를 구성하므로 named-chroot 데몬을 활성화시킵니다. (named와 named-chroot 데몬은 동시에 실행시킬수 없습니다)
### Enable and Start the BIND Service ###
[root@localhost ~]# systemctl enable named-chroot
[root@localhost ~]# systemctl start named-chroot
named-chroot 데몬을 실행한후 "/var/named/chroot/etc" 폴더를 검색해보면, 아래와 같이 환경파일이 생성됩니다.
[root@localhost ~]# ls -al /var/named/chroot/etc
total 708
drwxr-x--- 5 root named 186 Dec 6 12:52 .
drwxr-x--- 7 root named 61 Dec 6 11:05 ..
drwxr-x--- 3 root named 23 Dec 6 11:05 crypto-policies
-rw-r--r--. 2 root root 318 Oct 26 22:09 localtime
drwxr-x--- 2 root named 6 Aug 25 08:20 named
-rw-r----- 1 root named 1705 Aug 25 08:20 named.conf
-rw-r----- 1 root named 1029 Aug 25 08:20 named.rfc1912.zones
-rw-r--r-- 1 root named 1070 Aug 25 08:20 named.root.key
drwxr-x--- 3 root named 25 Dec 6 11:05 pki
-rw-r--r--. 1 root root 6568 Sep 10 2018 protocols
-rw-r----- 1 root named 100 Dec 6 12:51 rndc.key
-rw-r--r--. 1 root root 692252 May 15 2020 services
DNS 초기화 (참고)
named-chroot 데몬에 대해서 구글링을 하다보면, named-chroot 데몬을 시작하기 전에 "/usr/libexec/setup-named-chroot.sh"을 실행하는 모습이 심심치않게 보여서 찾아봤습니다. 결론부터 말하면 현재 설치하는 버전에서는 별도로 "/usr/libexec/setup-named-chroot.sh"를 실행해서 초기화할 필요는 없어 보입니다. 그 이유에 대해서는 아래 내용에서 확인할수 있습니다.
■서비스 연관성
①"systemctl start named-chroot"를 실행하면, "named-chroot.service" 파일의 내용이 실행됩니다.
②"named-chroot.service" 파일에서 "named-chroot-setup" 서비스가 호출되며, "named-chroot-setup.service" 파일의 내용이 실행됩니다.
③"named-chroot-setup.service" 파일에서 다시 "setup-named-chroot.sh"이 실행되면서 초기화 작업이 진행됩니다.
자세한 흐름은 아래 파일의 내용을 참고해 주세요.
### named-chroot.service ###
[root@localhost ~]# cat /usr/lib/systemd/system/named-chroot.service
# Don't forget to add "$AddUnixListenSocket /var/named/chroot/dev/log"
# line to your /etc/rsyslog.conf file. Otherwise your logging becomes
# broken when rsyslogd daemon is restarted (due update, for example).
[Unit]
Description=Berkeley Internet Name Domain (DNS)
Wants=nss-lookup.target
Requires=named-chroot-setup.service
Before=nss-lookup.target
After=named-chroot-setup.service
After=network.target
[Service]
Type=forking
Environment=NAMEDCONF=/etc/named.conf
EnvironmentFile=-/etc/sysconfig/named
Environment=KRB5_KTNAME=/etc/named.keytab
PIDFile=/var/named/chroot/run/named/named.pid
ExecStartPre=/bin/bash -c 'if [ ! "$DISABLE_ZONE_CHECKING" == "yes" ]; then /usr/sbin/named-checkconf -t \
/var/named/chroot -z "$NAMEDCONF"; else echo "Checking of zone files is disabled"; fi'
ExecStart=/usr/sbin/named -u named -c ${NAMEDCONF} -t /var/named/chroot $OPTIONS
ExecReload=/bin/sh -c 'if /usr/sbin/rndc null > /dev/null 2>&1; then /usr/sbin/rndc reload; else /bin/kill \
-HUP $MAINPID; fi'
ExecStop=/bin/sh -c '/usr/sbin/rndc stop > /dev/null 2>&1 || /bin/kill -TERM $MAINPID'
PrivateTmp=false
[Install]
WantedBy=multi-user.target
### named-chroot-setup.service ###
[root@localhost ~]# cat /usr/lib/systemd/system/named-chroot-setup.service
[Unit]
Description=Set-up/destroy chroot environment for named (DNS)
BindsTo=named-chroot.service
Wants=named-setup-rndc.service
After=named-setup-rndc.service
[Service]
Type=oneshot
RemainAfterExit=yes
ExecStart=/usr/libexec/setup-named-chroot.sh /var/named/chroot on /etc/named-chroot.files
ExecStop=/usr/libexec/setup-named-chroot.sh /var/named/chroot off /etc/named-chroot.files
[root@localhost ~]# cat /etc/named-chroot.files
# Configuration of files used in chroot
# Following files are made available after named-chroot.service start
# if they are missing or empty in target directory.
/etc/localtime
/etc/named.root.key
/etc/named.conf
/etc/named.rfc1912.zones
/etc/rndc.conf
/etc/rndc.key
/etc/named.iscdlv.key
/etc/crypto-policies/back-ends/bind.config
/etc/protocols
/etc/services
/etc/named.dnssec.keys
/etc/pki/dnssec-keys
/etc/named
/usr/lib64/bind
/usr/lib/bind
/usr/share/GeoIP
/run/named
# Warning: the order is important
# If a directory containing $ROOTDIR is listed here,
# it MUST be listed last. (/var/named contains /var/named/chroot)
/var/named
DNS 환경파일 설정하기
아래는 bind 패키지를 설치하면 기본적으로 제공되는 named.conf 파일의 내용입니다. 내용을 살펴보면 IPv4와 IPv6 환경은 "127.0.0.1"과 "::1"로 제한되어 있으며, DNS 서버에 질의를 허용하는 옵션인 "allow-query"는 localhost로 제안되어 있기 때문에 외부에서 이 DNS 서버로 도메인 해석을 질의해도 응답하지 않도록 설정되어 있습니다.
### /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";
secroots-file "/var/named/data/named.secroots";
recursing-file "/var/named/data/named.recursing";
allow-query { localhost; };
recursion yes;
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 {
file "data/named.run";
severity dynamic;
};
};
zone "." IN {
type hint;
file "named.ca";
};
include "/etc/named.rfc1912.zones";
include "/etc/named.root.key";
이제 몇 가지 조건을 붙여서 named.conf의 설정을 조금 변경해 보겠습니다.
내부 도메인 해석에 대한 질의/응답을 내부 네트워크로 제한하는 경우 (폐쇄형 DNS에 적용)
우선 DNS 서버 외의 IP 주소에서도 네트워크 통신이 가능하도록 "listen-on port 53"와 "listen-on-v6 port 53"를 "자신의 DNS 서버 IP"로 변경합니다. 내부 네트워크(office-nets)에서 도메인 해석 질의가 가능하도록 "allow-query"를 "office-nets"로 제한하도록 설정합니다. 마지막으로 recursion 옵션을 no로 설정하므로서 DNS 서버에서 설정된 Zone 외에는 도메인 해석 질의가 불가능하도록 제한합니다.
### /etc/named.conf ###
acl office-nets {
192.168.80.0/24;
};
options {
listen-on port 53 { 192.168.80.171; };
listen-on-v6 port 53 { fe80::20c:29ff:fe24:2e78; };
...
allow-query { office-nets; };
recursion no;
...
};
내부 도메인 해석에 대한 질의/응답을 모든 네트워크에 허용하는 경우 (자사 서비스 DNS에 적용)
모든 네트워크에서 도메인 해석 질의에 대해 응답이 가능하도록 "allow-query"를 any로 설정하며, "recursion"을 no로 설정하여 DNS 서버에서 설정한 Zone으로 질의/응답 범위를 내부 도메인으로 제한합니다. (실제 환경에서 "listen-on port 53"와 "listen-on-v6 port 53"에서 설정하는 IP는 반드시 Public IP여야만 합니다)
### /etc/named.conf ###
options {
listen-on port 53 { 192.168.80.171; };
listen-on-v6 port 53 { fe80::20c:29ff:fe24:2e78; };
...
allow-query { any; };
recursion no;
...
};
내/외부 도메인 해석에 대한 질의/응답을 내부 네트워크로 제한하는 경우 (사내 DNS에 적용)
도메인 해석 질의를 내부 네트워크인 "office-nets"로 제한하며, 내/외부 모든 도메인 해석이 가능하도록 recursion 옵션을 yes로 변경합니다.
### /etc/named.conf ###
acl office-nets {
192.168.80.0/24;
};
options {
listen-on port 53 { 192.168.80.171; };
listen-on-v6 port 53 { fe80::20c:29ff:fe24:2e78; };
...
allow-query { office-nets; };
recursion yes;
...
};
내/외부 도메인 해석에 대한 질의/응답을 모든 네트워크에 허용하는 경우 (포탈 사이트의 DNS 또는 Public DNS)
모든 네트워크에서 질의가 가능하도록 "allow-query"를 any로 설정하며, 내/외부 모든 도메인 해석이 가능하도록 recursion 옵션을 yes로 변경합니다. (실제 환경에서 "listen-on port 53"와 "listen-on-v6 port 53"에서 설정하는 IP는 반드시 Public IP여야만 합니다)
### /etc/named.conf ###
options {
listen-on port 53 { 192.168.80.171; };
listen-on-v6 port 53 { fe80::20c:29ff:fe24:2e78; };
...
allow-query { any; };
recursion yes;
...
};
몇 가지 설정할수 있는 유형에 대해서 알아 보았는데요, 일견 모든 네트워크에서 모든 도메인에 대해 질의와 해석이 가능하도록 설정하는 것이 이상적으로 보일수 있지만, DNS 공격에 악용될수 있으므로 반드시 목적에 맞게 서비스 범위를 제한하도록 설정합시다.