What is a nameserver and how to run one?

What is a nameserver and how to run one

If you are working with websites and networking, you must have heard of the name of ‘NAMESERVERS’. We will try to figure out what exactly are these and how to install one and use it. Lets see what is a nameserver and how to run one

What is a nameserver?

These are the servers running which are specialised to handle request which translates the domain name to an identifiable address or forward the request to the location where it can be resolved. These are very basic elements which helps in resolution of the DNS queries.

How nameservers works?

Generally these nameservers have mapping of Domain names and the server/location to which it has to forward the request to.

How to run one?

You can install a nameserver options present in open source. We will be installing pdns and work around it.

Ubuntu

sudo apt-get install pdns-server

FreeBSD

pkg install dns/powerdns

Redhat

yum install pdns

Mac OS X

brew install pdns

We will try to use it with mysql. For this we need to change the settings in pdns.conf. This will be present usually in /etc/powerdns folder.

You will need to have a mysql server running use this link to install one.

Below are the settings you need to add.

launch=gmysql
gmysql-host=127.0.0.1(mysql host)
gmysql-user=root(mysql user)
gmysql-dbname=pdns(mysql dbname)
gmysql-password=mysecretpassword(mysql password)

Now that it does not create the pdns database we need to create the database and tables manually. Below is the script that you can use to create mysql tables.

If you don’t want to create it manually you can install pdns-mysql-backend.

sudo apt-get install pdns-mysql-backend

This will create the tables for you.

CREATE SCHEMA pdns;

 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);
Reload the PDNS server

How to test or check if the dns server running?

Create domain name entries in PDNS with below mysql scripts.

INSERT INTO domains (name, type) values ('example.com', 'NATIVE');
INSERT INTO records (domain_id, name, content, type,ttl,prio)
VALUES (1,'example.com','localhost admin.example.com 1 10380 3600 604800 3600','SOA',86400,NULL);
INSERT INTO records (domain_id, name, content, type,ttl,prio)
VALUES (1,'example.com','dns-us1.powerdns.net','NS',86400,NULL);
INSERT INTO records (domain_id, name, content, type,ttl,prio)
VALUES (1,'example.com','dns-eu1.powerdns.net','NS',86400,NULL);
INSERT INTO records (domain_id, name, content, type,ttl,prio)
VALUES (1,'www.example.com','192.0.2.10','A',120,NULL);
INSERT INTO records (domain_id, name, content, type,ttl,prio)
VALUES (1,'mail.example.com','192.0.2.12','A',120,NULL);
INSERT INTO records (domain_id, name, content, type,ttl,prio)
VALUES (1,'localhost.example.com','127.0.0.1','A',120,NULL);
INSERT INTO records (domain_id, name, content, type,ttl,prio)
VALUES (1,'example.com','mail.example.com','MX',120,25);

Now go on any machine that will use this machine as dns server and change its resolv.conf.

How to change the resolv.conf. The config file is present in /etc/resolv.conf. You can add this entry at the top here.

nameserver ip_of_dns_server

Note that after this, only those dns will resolve from this machine whose entries are present in dns mysql records. Thus google.com facebook.com anything will not resolve.

Run this command to check if the dns is working fine

$ dig +short www.example.com @127.0.0.1
192.0.2.10

It will resolve in something like below. If this is coming then you pdns server is working fine.

Now you can make entries for your local machine and under stand them with the name instead of remembering the ips.

For more pdns queries you can head over to their official site.

Read more about servers here. 

Like the article please share and subscribe.


Gaurav Yadav

Gaurav is cloud infrastructure engineer and a full stack web developer and blogger. Sportsperson by heart and loves football. Scale is something he loves to work for and always keen to learn new tech. Experienced with CI/CD, distributed cloud infrastructure, build systems and lot of SRE Stuff.

2 COMMENTS
  • Aneesh R
    Reply

    Is there any specific reason on why you are feeding these data to a database, which is not as simple having a config file. You can always have the name server configs in a file system level with some versioning enabled.

    1. Gaurav Yadav
      Reply

      There is no specific reason to do so. It’s just that it makes the use of pdns API easy thus if you want to add more entries you can automate them via the apis

Leave a Reply

Your email address will not be published. Required fields are marked *

This site uses Akismet to reduce spam. Learn how your comment data is processed.