DNS와 PowerDNS(Feat. Rocky Linux)

김흰돌·2022년 10월 12일
0

DNS란?

  • Domain Name System으로 도메인 이름을 IP 주소로 변환함
  • 숫자를 사용하여 통신을 하지만 웹 사이트로 이동할 때 긴 숫자를 기억하기 힘듬
  • 대신 도메인 이름을 입력하여 원하는 웹 사이트로 이동할 수 있음
  • DNS 서버는 도메인 이름을 입력할 시 어떤 서버에 연결할 것인지 제어함
  • 도메인 네임의 IP를 요청하는 것을 쿼리 라고 부름

도메인의 구조

  • 쿼리를 날렸을 시 한 번에 IP 주소를 돌려줄 수 있는 네임 서버는 없음
  • 각각의 레벨을 담당하는 네임 서버가 있고 각 서버는 하위 레벨 네임서버 주소밖에 알지 못함
  • 따라서 Root 부터 시작하여 단계적으로 IP 주소를 찾아감

사용자를 웹 사이트로 연결하는 과정

사용자가 naver에 접속하기 위해 www.naver.com을 주소창에 입력하였을 시 그림과 같은 순서로 IP 주소를 반환한다.


DNS Server로 PowerDNS를 추천하는 이유

  • 오픈 소스로 운영에 금전적 부담이 없음

  • Mysql/MariaDB에 도메인에 관련된 데이터를 저장하기 때문에 쿼리를 작성할 수 있는 사람이면 쉽게 DNS 서버를 다룰 수 있음

  • 쿼리를 사용할 수 있기 때문에 관리하는 도메인이 많을 때 유용함

  • 원하면 웹을 통해 쉽게 도메인을 관리할 수 있어 더욱 편의성이 좋음


PDNS의 주요 테이블 - domains

  • Zone을 구성하는 테이블
  • 도메인은 하나의 Zone으로 구성되어 있음
  • 호스트에 접속하기 위해서 그 영역의 정보, 즉 Zone을 가지고 있는 네임서버로 우선 접근 함
  • name에 Zone으로 사용할 이름을 기입
  • type은 Master와 Native로 나뉨
  • MySQL 리플리케이션을 사용할 경우 Master Replication, Native Replication 두 방식이 있음

PDNS의 주요 테이블 - records(SOA)

  • 질의 응답이 들어올 경우 가장 먼저 보여주는 값
  • 도메인에 대한 시작 정보를 담고 있음
  • SOA는 꼭 등록되어야 하는 중요한 레코드
  • TTL은 Time To Live의 약자로 네임 서버에 질의를 보낼 때 캐시 네임 서버가 그 레코드를 TTL 값에 해당하는 동안 저장해 둠

PDNS의 주요 테이블 - records(SOA)

  • 마스터 네임서버의 도메인 이름(Mname)
  • 도메인 존 관리자의 이름(Rname)
  • 처음 만든 날짜와 존파일 갱신 시 숫자 증가(Serial)
  • 도메인 존 갱신 주기(Refresh)
  • 도메인 존 갱신 실패 시 재시도 주기(Retry)
  • 도메인 존 갱신 실패 후 응답을 최종적으로 중단해야 하는 기간(Expire)
  • TTL의 디폴트 값을 지정(Minimum)

PDNS의 주요 테이블 - records(NS)

  • 네임 서버를 의미함
  • 해당 도메인에 대한 권한이 있는 DNS 서버를 표시하는 레코드
  • 실제 운영하는 DNS 레코드가 있는 서버를 지정
  • 보통 안정성을 높이기 위해 다수의 네임 서버를 구성함
  • 서버 하나가 중단되어도 다른 네임 서버를 이용할 수 있음

PDNS의 주요 테이블 - records(A/AAAA)

  • DNS 서버에서 가장 일반적으로 쓰이는 레코드
  • 도메인 정보를 입력하면 IPv4 서버를 찾아갈 수 있음
  • AAAA 레코드도 동일하나 IPv6 서버를 찾아갈 수 있음

PDNS의 주요 테이블 - records(CNAME)

  • 도메인 네임의 별칭을 말함
  • 적용되어 있는 A 레코드에 별도의 서브 도메인을 호스트네임으로 등록하는 법

PDNS의 주요 테이블 - records(MX)

  • 이메일을 발송 할 경우 도메인 네임서버가 설정된 메일 서버로 전달해줌
  • 우선순위를 설정하여 수신되는 순서 설정 가능
  • priority의 숫자가 낮은 만큼 우선순위가 올라감
  • 우선 순위가 같을 경우 5:5 비율로 응답함
  • priority가 1과 2인 세 대의 서버가 장애가 생길 시 그 다음 우선순위(prio = 4)인 mail4.test.com으로 전달 됨

PDNS의 주요 테이블 - records(PTR)

  • 반대로 IP 질의시 도메인 정보를 확인하는 정책
  • 주로 메일 인증기술에 많이 쓰임
  • 발송 서버의 IP를 조회하여 도메인에 등록된 PTR과 일치한다면 정상으로 판단 해 수신하겠다는 역방향 질의 방식

Rocky Linux에 PDNS 설치 해보기

MariaDB, pdns 설치

앞서 말했듯이 PowerDNS는 Mysql/MariaDB에 도메인 관련 데이터들을 저장하기 때문에 우리는 MariaDB를 설치한다.

sudo vi /etc/yum.repos.d/mariaDB.repo

로 파일 생성 및 아래의 내용을 입력한 후 저장한다.

# MariaDB 10.7 RedHat repository list
[mariadb]
name = MariaDB
baseurl = http://yum.mariadb.org/10.7/rhel8-amd64
module_hotfixes=1
gpgkey=https://yum.mariadb.org/RPM-GPG-KEY-MariaDB
gpgcheck=1

mariaDB.repo 파일이 생성 된 걸 확인할 수 있다,

확인해보면 아래와 같이 작성한 내용이 잘 들어가 있다.


sudo yum install pdns  pdns-backend-mysql MariaDB-server -y

위의 명령어로 pdns와 mariadb를 설치한다.


MariaDB 설정

sudo systemctl enable --now mariadb.service   mariadb 실행 및 서버 시작 시 mariadb가 자동으로 켜지게끔 설정
sudo systemctl status mariadb.service   상태 확인
sudo mariadb-secure-installation   초기 설정
mysql -uroot -p   로그인 잘 되는지 확인


계정 생성 및 레코드 추가

pdns DB 생성, pdns 계정 생성(pw는 본인이 사용할 pw를 적는다)

create database pdns;
GRANT ALL ON pdns.* TO 'pdns'@'localhost' IDENTIFIED BY '1234';
FLUSH PRIVILEGES;

pdns DB에 사용할 table 생성

use pdns;
CREATE TABLE domains (
  id                    INT AUTO_INCREMENT,
  name                  VARCHAR(255) NOT NULL,
  master                VARCHAR(128) DEFAULT NULL,
  last_check            INT DEFAULT NULL,
  type                  VARCHAR(6) NOT NULL,
  notified_serial       INT DEFAULT NULL,
  account               VARCHAR(40) DEFAULT NULL,
  PRIMARY KEY (id)
) Engine=InnoDB;

CREATE UNIQUE INDEX name_index ON domains(name);

CREATE TABLE records (
  id                    BIGINT AUTO_INCREMENT,
  domain_id             INT DEFAULT NULL,
  name                  VARCHAR(255) DEFAULT NULL,
  type                  VARCHAR(10) DEFAULT NULL,
  content               VARCHAR(64000) DEFAULT NULL,
  ttl                   INT DEFAULT NULL,
  prio                  INT DEFAULT NULL,
  change_date           INT DEFAULT NULL,
  disabled              TINYINT(1) DEFAULT 0,
  ordername             VARCHAR(255) BINARY DEFAULT NULL,
  auth                  TINYINT(1) DEFAULT 1,
  PRIMARY KEY (id)
) Engine=InnoDB;


CREATE INDEX nametype_index ON records(name,type);

CREATE INDEX domain_id ON records(domain_id);

CREATE INDEX recordorder ON records (domain_id, ordername);
 

CREATE TABLE supermasters (
  ip                    VARCHAR(64) NOT NULL,
  nameserver            VARCHAR(255) NOT NULL,
  account               VARCHAR(40) NOT NULL,
  PRIMARY KEY (ip, nameserver)
) Engine=InnoDB;

CREATE TABLE comments (
  id                    INT AUTO_INCREMENT,
  domain_id             INT NOT NULL,
  name                  VARCHAR(255) NOT NULL,
  type                  VARCHAR(10) NOT NULL,
  modified_at           INT NOT NULL,
  account               VARCHAR(40) NOT NULL,
  comment               VARCHAR(64000) NOT NULL,
  PRIMARY KEY (id)
) Engine=InnoDB;
 

CREATE INDEX comments_domain_id_idx ON comments (domain_id);

CREATE INDEX comments_name_type_idx ON comments (name, type);

CREATE INDEX comments_order_idx ON comments (domain_id, modified_at);

CREATE TABLE domainmetadata (
  id                    INT AUTO_INCREMENT,
  domain_id             INT NOT NULL,
  kind                  VARCHAR(32),
  content               TEXT,
  PRIMARY KEY (id)
) Engine=InnoDB;
 
CREATE INDEX domainmetadata_idx ON domainmetadata (domain_id, kind);

CREATE TABLE cryptokeys (
  id                    INT AUTO_INCREMENT,
  domain_id             INT NOT NULL,
  flags                 INT NOT NULL,
  active                BOOL,
  content               TEXT,
  PRIMARY KEY(id)
) Engine=InnoDB;

CREATE INDEX domainidindex ON cryptokeys(domain_id);

CREATE TABLE tsigkeys (
  id                    INT AUTO_INCREMENT,
  name                  VARCHAR(255),
  algorithm             VARCHAR(50),
  secret                VARCHAR(255),
  PRIMARY KEY (id)
) Engine=InnoDB;

 CREATE UNIQUE INDEX namealgoindex ON tsigkeys(name, algorithm);

pdns.conf 수정

sudo vi /etc/pdns/pdns.conf

launch 관련 설정줄에 아래 내용 추가
launch=gmysql
gmysql-host=localhost
gmysql-user=pdns
gmysql-password=1234
gmysql-dbname=pdns
gmysql-dnssec=yessql-dbname=pdns
gmysql-dnssec=yes


port 설정

DNS는 기본적으로 53번 포트를 사용함

sudo firewall-cmd --permanent --add-port=53/udp
sudo firewall-cmd --permanent --add-port=53/tcp
sudo firewall-cmd --reload
sudo firewall-cmd --list-port


pdns 실행

sudo systemctl start pdns
sudo systemctl status pdns

오류 없이 잘 실행되어야 함


테스트용 도메인 생성

mariadb에 접속하여 도메인을 생성한다.

INSERT INTO `domains` (`id`, `name`, `master`, `last_check`, `type`, `notified_serial`, `account`) VALUES (1, 'test.com', '', 0, 'NATIVE', 0, '');

INSERT INTO `records` (`domain_id`, `name`, `type`, `content`, `ttl`, `prio`, `change_date`, `disabled`, `ordername`, `auth`) VALUES (1, 'test.com', 'SOA', 'localhost hostmaster@vegas-solution.com 1', 86400, NULL, NULL, 0, '', 1);

INSERT INTO `records` (`domain_id`, `name`, `type`, `content`, `ttl`, `prio`, `change_date`, `disabled`, `ordername`, `auth`) VALUES (1, 'test.com', 'NS', 'ns1.test.com', 86400, NULL, NULL, 0, '', 1);

INSERT INTO `records` (`domain_id`, `name`, `type`, `content`, `ttl`, `prio`, `change_date`, `disabled`, `ordername`, `auth`) VALUES (1, 'test.com', 'NS', '111.111.111.111', 60, NULL, NULL, 0, '', 0);

INSERT INTO `records` (`domain_id`, `name`, `type`, `content`, `ttl`, `prio`, `change_date`, `disabled`, `ordername`, `auth`) VALUES (1, 'my.test.com', 'A', '192.168.100.100', 10, NULL, NULL, 0, '', 1);

0개의 댓글