Jump to content

Why Memorize IP's When You Can Self-Host DNS Instead?

For the uninitiated, what is DNS?

DNS or Domain Name Server/Service is a feature available on most networks which resolves (or otherwise translates) domain names (or the names of websites) to their IP address equivalents. The reason for this is when you make a request to go to a website the name you type in isn't what takes you there. The request goes to your configured DNS provider (most often hosted by your ISP) this service then translates the request to the IP currently assigned to the website you're trying to visit.


In the event you're hosting any servers at home DNS can be used to assign them domain names making it easier to track and manage one or multiple systems/servers without the need for memorizing one or multiple IP addresses. This tutorial will cover how to setup and configure a very simple DNS forwarder for resolving local domain names. If at any point you have questions or need help troubleshooting feel free to comment down below.




1. Hardware Requirements

     1.1 - Server Side

     1.2 - Network Side

     1.3 - Client Side

2. Preparing Installation Media

     2.1 - For Windows

     2.2 - For Linux

3. Installing FreeBSD

4. Installing & Configuring Packages

     4.1 - Installing pkg

     4.2 - Installing sudo

     4.3 - Installing nano

     4.4 - Installing rsync

     4.5 - Installing dnsmasq

5. Testing the new DNS Forwarder

     5.1 - On Windows

     5.2 - On GNU/Linux

          5.2.1 - Netplan

          5.2.2 - Ifconfig

6. Configuring A Backup DNS (Optional - Recommended)

     6.1 - Enabling Remote Root Password Authentication

     6.2 - Configuring Password-Less Public/Private Key Authentication

     6.3 - Configuring RSYNC

     6.4 - Creating an RSYNC Script

     6.5 - Automating the RSYNC Script


1. Hardware Requirements


1.1 - Server Side


Domain Name Resolution is a very light-weight service which is implemented on most Operating Systems including Windows, Linux, UNIX, and Mac. The hardware requirements are very low. Any relatively modern system should be capable of handling the service. Do keep in mind that this will be your key to the Internet (explained later) so pick something you know will run reliably. If easily available to you server hardware will offer better compatibility/features.


1.2 - Network Side


Although not explicitly required you will want administrative access to your router. This will guarantee the server and your network behave how you want them to. DNS queries are very light-weight so no special high-speed networking is required. If you have a router that supports reserving IP addresses this will also be a desired feature.


1.3 - Client Side


Depending on if you have administrative access to your router it may be necessary that you have administrative control over your client PC(s) as we will otherwise have to manually edit the DNS servers on each individual client.


With that out of the way. Let's get started. :old-grin:


2. Preparing Installation Media


With your hardware chosen we will be using UNIX to host our DNS forwarder. More specifically FreeBSD as the operating system and dnsmasq as the DNS Forwarder.


NOTE: If you would prefer to use Windows, GNU/Linux, or MacOS for the hosting server it is possible to setup dnsmasq on Linux & MacOS. In the event of Windows you may need to resort to virtualization, the Windows Subsystem for Linux, or use another DNS resolver entirely.


Begin by downloading the .ISO image from the OS linked above. Which download you pick will be dependent on your platform of choice but the file you want will be similar to the following structure:


Most PC's today will work with AMD64. If you're looking to host this on something a little more special other platforms are supported.



2.1 - For Windows


After the .ISO finishes downloading start by installing an application known as Rufus. Rufus is a free and easy utility for Windows to create bootable USB media.




Start by selecting the thumb drive you want to install to in the Device field.




Now click SELECT to the right and navigate to where you saved the .ISO file. Click the .ISO file then click Open. From here Rufus may show you a small warning dialog. Just press OK.




Now click START. You'll be prompted that all data on the drive will be erased. If you're certain that that's OK go ahead and click OK.




During the installation you may receive a pop-up where Rufus attempts to mount the new media volume and fails.




This is perfectly fine and can be ignored. Just press OK if you receive the pop-up error.


From here you will know the installer USB is ready when you see the following screen:





2.2 - For Linux


After the .ISO finishes downloading start by opening a Terminal in the directory where the .ISO file is located. We're going to use the terminal application DD which is included with many GNU/Linux distributions. If you don't have DD this can likely be downloaded from your distributions repositories.


Start by listing what devices are available with the lsblk command.

user@workstation:~$ lsblk
sde           8:64   1  57.3G  0 disk 
└─sde1        8:65   1  57.3G  0 part /media/user/64 GB
nvme0n1     259:0    0 953.9G  0 disk 
├─nvme0n1p1 259:1    0   512M  0 part /boot/efi
└─nvme0n1p2 259:2    0 953.4G  0 part /run/timeshift/backup


We can see a 64(57.3)GB thumb-drive with the drive name sde. Start by unmounting any & all volumes on the drive with umount /dev/sde*:

user@workstation:~$ umount /dev/sde*
umount: /dev/sde: not mounted.


Now to create a file-system on it use sudo mkfs.ext4 /dev/sde:

user@workstation:~$ sudo mkfs.ext4 /dev/sde
[sudo] password for user: 
mke2fs 1.45.5 (07-Jan-2020)
Found a dos partition table in /dev/sde
Proceed anyway? (y,N) y
Creating filesystem with 15022080 4k blocks and 3760128 inodes
Filesystem UUID: 31afea12-4adf-42f8-8656-a812307e4f40
Superblock backups stored on blocks: 
	32768, 98304, 163840, 229376, 294912, 819200, 884736, 1605632, 2654208, 
	4096000, 7962624, 11239424

Allocating group tables: done                            
Writing inode tables: done                            
Creating journal (65536 blocks): done
Writing superblocks and filesystem accounting information: done


From here we can use DD to write the .ISO image to the USB using sudo dd if=FreeBSD-13.0-RELEASE-amd64-disc1.iso of=/dev/sde status=progress:

user@workstation:~$ sudo dd if=FreeBSD-13.0-RELEASE-amd64-disc1.iso of=/dev/sde status=progress 
1249743360 bytes (1.2 GB, 1.2 GiB) copied, 84 s, 14.9 MB/s 
2463616+0 records in
2463616+0 records out
1261371392 bytes (1.3 GB, 1.2 GiB) copied, 99.1369 s, 12.7 MB/s


Your installer USB is now ready.



3. Installing FreeBSD


Insert the thumb drive into the PC and start the computer. If the system doesn't bring you to a screen similar to below check your BIOS boot options including Boot Order, BIOS/Legacy vs UEFI platform support, CSM parameters, and/or the Boot Menu to try forcing the BIOS to boot directly to the USB drive.


Screenshot from 2021-09-04 11-35-05.png


 When you first start the installer after seeing the splash screen above you'll be greeted by a menu with the options to Install, exit to Shell, or run the Live CD. Go ahead and click install.




After this you'll be told to pick a keyboard keymap (default is QWERTY English).




Next up is to choose a name for your server.




You can name yours whatever you prefer.


The next few menus can all be left on default unless you otherwise need something.










Now select which disk you want to install the OS to. This can be done with the arrow keys + the space bar for selection.




You'll be asked if you're sure as all data on this disk will be erased.




If you're sure. Proceed.


Now pick a password for your new root user:

FreeBSD Installer

Please select a password for the system management account (root):
Typed characters will not be visible.
Changing local password for root
New Password:


Time to configure the network interfaces. Now the FreeBSD installer only lets you configure one interface, any others will need to be configured within the OS. Select the adapter that's going to be part of your management network. If you make a mistake here it's OK. We can fix it once we're booted into the OS.




You'll be prompted as to if you want to configure IPv4. Under most circumstances the answer is yes.




Next up is do you want to leave it up to DHCP (Dynamic Host Configuration Protocol - ie. your Router) to setup the interface? Although you can, I don't recommend it. You'll want to configure the interface manually so the IP doesn't have the possibility of changing on you. It's important to note though whatever IP you assign it isn't able to be handed out by your router anymore to other clients as this can lead to serious network conflict.




If you don't know what to enter below reference your router's DHCP page or ask a question to find out what subnet your network uses as not all computer networks are setup like mine.




You'll be prompted as to if you want to configure IPv6. This is optional and subject to your needs. So I won't be going over it here.




Now we need to setup DNS (Domain Name Server/Service). You can use your ISP provided DNS or a 3rd party like Google (,, or CloudFlare (,




Time Zone Setup














The following menus can be left on default values.








Now you need to add a user.



When adding a user you will have to fill out the following details:

FreeBSD Installer
Add Users

Username: dns
Full name: dns
Uid (Leave empty for default):
Login group [dns]:
Login group is dns. Invite dns into other groups? []:
Login class [default]:
Shell (sh csh tcsh nologin) [sh]:
Home directory [/home/dns]:
Home directory permissions (Leave empty for default):
Use password-based authentication? [yes]:
Use an empty password? (yes/no) [no]:
Use a random password? (yes/no) [no]:
Enter password:
Enter password again:
Lock out the account after creation? [no]:
Username   : dns
Password   : *****
Full Name  : dns
Uid        : 1001
Class      :
Groups     : dns
Home       : /home/dns
Home Mode  :
Shell      : /bin/sh
Locked     : no
OK? (yes/no):


Afterwords you'll be asked if you have any final changes you'd like to make:




If you'd like the enter shell:




And finally Reboot or enter Live CD.



Go ahead and reboot the system. OS installation is now complete. You will see the following when the OS finishes loading:





4. Installing & Configuring Packages


At this point in time you should now be able to login as root with the root username and your password. There are really only two software packages that have to be installed but I'm going to list three additional packages I recommend.

  • pkg (The package manager. Used for installing, upgrading, or removing software packages)
  • sudo (Recommended: Allows a normal user to run commands as though they were root. Reason being not all users are granted system wide permissions.)
  • nano (Recommended: A simple text editor with a easier learning curve as opposed to the default (Vi/Vim).
  • rsync (Recommended: A file synchronization application.
  • dnsmasq (The DNS Forwarder we will be using for this setup)

4.1 - Installing pkg


To install the package manager query it by running the command pkg.

root@dns-forwarder:~ $ pkg
The package management tool is not yet installed on your system. Do you want to fetch and install it now? [y/N]:


When complete you will see the following output:

Bootstrapping pkg from pkg+http://pkg.FreeBSD.org/FreeBSD:13:amd64/quarterly, please wait...
Verifying signature with trusted certificate pkg.freebsd.org.2013102301... done
Installing pkg-1.17.5...
Extracting pkg-1.17.5: 100%
pkg: not enough arguments
Usage: pkg [-v] [-d] [-l] [-N] [-j <jail name or id>|-c <chroot path>|-r <rootdir>] [-C <configuration file>] [-R <repo config dir>] [-o var=value] [-4|-6] <command> [<args>]

For more information on available commands and options see 'pkg help'.



4.2 - Installing sudo


 Sudo is a helpful tool for allowing regular users to run commands they'd ordinarily have to be root in order to use. To install it run pkg install sudo.

root@dns-forwarder:~ $ pkg install sudo
Updating FreeBSD repository catalogue...
FreeBSD repository is up to date.
All repositories are up to date.
The following 1 package(s) will be affected (of 0 checked):

New packages to be INSTALLED:
	sudo: 1.9.8p2

Number of packages to be installed: 1

The process will require 7 MiB more space.
1 MiB to be downloaded.

Proceed with this action? [y/N]:


When complete you should see this output:

[1/1] Fetching sudo-1.9.8p2.pkg: 100%    1 MiB   1.5MB/s    00:01    
Checking integrity... done (0 conflicting)
[1/1] Installing sudo-1.9.8p2...
[1/1] Extracting sudo-1.9.8p2: 100%
root@dns-forwarder:~ # 


To allow users to use sudo we need to edit the sudoers file. This can be done with visudo.

root@dns-forwarder:~ # visudo

## sudoers file.
## This file MUST be edited with the 'visudo' command as root.
## Failure to use 'visudo' may result in syntax or file permission errors
## that prevent sudo from running.
## See the sudoers man page for the details on how to write a sudoers file.

## Host alias specification
## Groups of machines. These may include host names (optionally with wildcards),
## IP addresses, network numbers or netgroups.
# Host_Alias    WEBSERVERS = www1, www2, www3

## User alias specification
## Groups of users.  These may consist of user names, uids, Unix groups,
## or netgroups.
# User_Alias    ADMINS = millert, dowdy, mikef

## Cmnd alias specification
## Groups of commands.  Often used to group related commands together.
# Cmnd_Alias    PROCESSES = /usr/bin/nice, /bin/kill, /usr/bin/renice, \
#                           /usr/bin/pkill, /usr/bin/top
# Cmnd_Alias    REBOOT = /sbin/halt, /sbin/reboot, /sbin/poweroff

## Defaults specification
## Uncomment if needed to preserve environmental variables related to the
## FreeBSD pkg utility and fetch.
# Defaults     env_keep += "PKG_CACHEDIR PKG_DBDIR FTP_PASSIVE_MODE"
## Additionally uncomment if needed to preserve environmental variables
## related to portupgrade
## You may wish to keep some of the following environment variables
## when running commands via sudo.
## Locale settings
# Defaults env_keep += "LANG LANGUAGE LINGUAS LC_* _XKB_CHARSET"
## Run X applications through sudo; HOME is used to find the
## .Xauthority file.  Note that other programs use HOME to find
## configuration files and this may lead to privilege escalation!
# Defaults env_keep += "HOME"
## X11 resource path settings
## Desktop path settings
# Defaults env_keep += "QTDIR KDEDIR"
## Allow sudo-run commands to inherit the callers' ConsoleKit session
# Defaults env_keep += "XDG_SESSION_COOKIE"
## Uncomment to enable special input methods.  Care should be taken as
## this may allow users to subvert the command being run via sudo.
## Uncomment to use a hard-coded PATH instead of the user's to find commands
# Defaults secure_path="/usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin:/sbin:/bin"
## Uncomment to send mail if the user does not enter the correct password.
# Defaults mail_badpass
## Uncomment to enable logging of a command's output, except for
## sudoreplay and reboot.  Use sudoreplay to play back logged sessions.
# Defaults log_output
# Defaults!/usr/bin/sudoreplay !log_output
# Defaults!/usr/local/bin/sudoreplay !log_output
# Defaults!REBOOT !log_output

## Runas alias specification

## User privilege specification
root ALL=(ALL) ALL

## Uncomment to allow members of group wheel to execute any command
# %wheel ALL=(ALL) ALL

## Same thing without a password

## Uncomment to allow members of group sudo to execute any command
# %sudo ALL=(ALL) ALL

## Uncomment to allow any user to run sudo if they know the password
## of the user they are running the command as (root by default).
# Defaults targetpw  # Ask for the password of the target user
# ALL ALL=(ALL) ALL  # WARNING: only use this together with 'Defaults targetpw'

## Uncomment to show on password prompt which users' password is being expected
# Defaults passprompt="%p's password:"

## Read drop-in files from /usr/local/etc/sudoers.d
@includedir /usr/local/etc/sudoers.d


To add users start by pressing the letter "I" for "Insert", now append to the end of the file user ALL=(ALL) ALL substituting "user" for your username(s).

## Read drop-in files from /usr/local/etc/sudoers.d
@includedir /usr/local/etc/sudoers.d



To save & exit press ESC then the characters :wq followed by pressing Enter.

/usr/local/etc/sudoers.tmp: 109 lines, 3654 characters.


Now to test if sudo is working start by changing users with su - user.

root@dns-forwarder:~ # su - dns
To do a fast search for a file, try

	 locate filename

locate uses a database that is updated every Saturday (assuming your computer
is running FreeBSD at the time) to quickly find files based on name only.
dns@dns-forwarder:~ $ 


Now if we try to run the sudo editor as normal we get a permission denied error:

dns@dns-forwarder:~ $ visudo
visudo: /usr/local/etc/sudoers: Permission denied


But with sudo we are offered to enter a password so we can run visudo among many other functions as if we were root:

dns@dns-forwarder:~ $ sudo visudo

We trust you have received the usual lecture from the local System
Administrator. It usually boils down to these three things:

    #1) Respect the privacy of others.
    #2) Think before you type.
    #3) With great power comes great responsibility.




4.3 - Installing nano


Nano is an easy to use CLI text editor which we will use to create and/or edit configuration files. Although, Vi/Vim among other popular editors will work just as well.


To install nano run sudo pkg install nano.

dns@dns-forwarder:~ $ sudo pkg install nano
Updating FreeBSD repository catalogue...
FreeBSD repository is up to date.
All repositories are up to date.
The following 1 package(s) will be affected (of 0 checked):

New packages to be INSTALLED:
	nano: 5.9

Number of packages to be installed: 1

The process will require 3 MiB more space.
563 KiB to be downloaded.

Proceed with this action? [y/N]: 


Which should look like this when it's done:

[1/1] Fetching nano-5.9.pkg: 100%  563 KiB 576.4kB/s    00:01    
Checking integrity... done (0 conflicting)
[1/1] Installing nano-5.9...
[1/1] Extracting nano-5.9: 100%
dns@dns-forwarder:~ $



4.4 - Installing rsync


To install RSYNC run the command sudo pkg install rsync.

dns@dns-forwarder:~ $ sudo pkg install rsync
Updating FreeBSD repository catalogue...
Fetching packagesite.pkg: 100%    6 MiB   3.4MB/s    00:02    
Processing entries: 100%
FreeBSD repository update completed. 31375 packages processed.
All repositories are up to date.
The following 5 package(s) will be affected (of 0 checked):

New packages to be INSTALLED:
	libiconv: 1.16
	liblz4: 1.9.3,1
	rsync: 3.2.3_1
	xxhash: 0.8.0
	zstd: 1.5.0

Number of packages to be installed: 5

The process will require 7 MiB more space.
2 MiB to be downloaded.

Proceed with this action? [y/N]:


Which should look like this when it finishes:

[1/5] Fetching rsync-3.2.3_1.pkg: 100%  355 KiB 363.2kB/s    00:01    
[2/5] Fetching xxhash-0.8.0.pkg: 100%   73 KiB  75.1kB/s    00:01    
[3/5] Fetching libiconv-1.16.pkg: 100%  606 KiB 620.9kB/s    00:01    
[4/5] Fetching zstd-1.5.0.pkg: 100%  582 KiB 595.5kB/s    00:01    
[5/5] Fetching liblz4-1.9.3,1.pkg: 100%  131 KiB 134.5kB/s    00:01    
Checking integrity... done (0 conflicting)
[1/5] Installing liblz4-1.9.3,1...
[1/5] Extracting liblz4-1.9.3,1: 100%
[2/5] Installing xxhash-0.8.0...
[2/5] Extracting xxhash-0.8.0: 100%
[3/5] Installing libiconv-1.16...
[3/5] Extracting libiconv-1.16: 100%
[4/5] Installing zstd-1.5.0...
[4/5] Extracting zstd-1.5.0: 100%
[5/5] Installing rsync-3.2.3_1...
[5/5] Extracting rsync-3.2.3_1: 100%
dns@dns-forwarder:~ $ 



4.5 - Installing dnsmasq


To install dnsmasq run the command sudo pkg install dnsmasq.

dns@dns-forwarder:~ # sudo pkg install dnsmasq
Updating FreeBSD repository catalogue...
FreeBSD repository is up to date.
All repositories are up to date.
The following 7 package(s) will be affected (of 0 checked):

New packages to be INSTALLED:
	dnsmasq: 2.86_3,1
	gettext-runtime: 0.21
	gmp: 6.2.1
	indexinfo: 0.3.1
	libidn2: 2.3.2
	libunistring: 0.9.10_1
	nettle: 3.7.3

Number of packages to be installed: 7

The process will require 13 MiB more space.
3 MiB to be downloaded.

Proceed with this action? [y/N]:


Which will look like this when it finishes:

[1/7] Fetching dnsmasq-2.86_3,1.pkg: 100%  359 KiB 367.3kB/s    00:01    
[2/7] Fetching nettle-3.7.3.pkg: 100%    1 MiB   1.5MB/s    00:01    
[3/7] Fetching indexinfo-0.3.1.pkg: 100%    6 KiB   5.7kB/s    00:01    
[4/7] Fetching gmp-6.2.1.pkg: 100%  479 KiB 490.1kB/s    00:01    
[5/7] Fetching libidn2-2.3.2.pkg: 100%  112 KiB 114.5kB/s    00:01    
[6/7] Fetching libunistring-0.9.10_1.pkg: 100%  517 KiB 529.7kB/s    00:01    
[7/7] Fetching gettext-runtime-0.21.pkg: 100%  166 KiB 169.9kB/s    00:01    
Checking integrity... done (0 conflicting)
[1/7] Installing indexinfo-0.3.1...
[1/7] Extracting indexinfo-0.3.1: 100%
[2/7] Installing gmp-6.2.1...
[2/7] Extracting gmp-6.2.1: 100%
[3/7] Installing libunistring-0.9.10_1...
[3/7] Extracting libunistring-0.9.10_1: 100%
[4/7] Installing nettle-3.7.3...
[4/7] Extracting nettle-3.7.3: 100%
[5/7] Installing libidn2-2.3.2...
[5/7] Extracting libidn2-2.3.2: 100%
[6/7] Installing gettext-runtime-0.21...
[6/7] Extracting gettext-runtime-0.21: 100%
[7/7] Installing dnsmasq-2.86_3,1...
[7/7] Extracting dnsmasq-2.86_3,1: 100%
Message from dnsmasq-2.86_3,1:

To enable dnsmasq, edit /usr/local/etc/dnsmasq.conf and
set dnsmasq_enable="YES" in /etc/rc.conf[.local]

Further options and actions are documented inside

It is recommended to enable the wpad-related options
at the end of the configuration file (you may need to
copy them from the example file to yours) to fix
CERT Vulnerability VU#598349.


From here there are two files that have to be configured, /usr/local/etc/dnsmasq.conf & /etc/hosts.


Starting with /usr/local/etc/dnsmasq.conf these lines need to be added to the beginning or end of the file. This file can be edited with sudo nano /usr/local/etc/dnsmasq.conf.


The two servers listed above are CloudFlare's primary and secondary DNS resolvers but you can use whichever other public provider you prefer or your ISP's.


Ctrl+O then Enter to save, Ctrl+X to exit.


Now to edit the other file run sudo nano /etc/hosts. Here at the end of this file you have to get a little creative.

# Imaginary network.
#               myname.my.domain myname
#               myfriend.my.domain myfriend
# According to RFC 1918, you can use the following IP networks for
# private nets which will never be connected to the Internet:
#        -
#      -
#     -
# In case you want to be able to connect to the Internet, you need
# real official assigned numbers.  Do not try to invent your own network
# numbers but instead get one from your network provider (if any) or
# from your regional registry (ARIN, APNIC, LACNIC, RIPE NCC, or AfriNIC.)
# server.domain.name server.domain.name is an example of the format in which the file needs to be written. This is what will translate the hostname/domain you create into the IP your client needs to connect to your server(s). There is quite a bit of creative freedom in what you can name the domains but I've personally decided to preference CPU#.Operating-System.Service. You can go almost any other route though.


After you finish with that add the following line to the end of /etc/rc.conf:



Now start the dnsmasq service:

dns@dns-forwarder:~ # sudo dnsmasq
dns@dns-forwarder:~ #


And verify it's running with sudo service dnsmasq status:

dnsmasq is running as pid 867.


We're ready to perform our first test.



5. Testing the new DNS Forwarder


If you plan to use this for your entire network you will want to perform an isolated test on a client by manually setting the DNS from whatever DHCP gave it to your new local DNS Forwarder. How you do that will depend on your OS:


5.1 - On Windows


In Windows we can edit DNS a few different ways. Today let's do it the PowerShell way. Start by opening an Administrative PowerShell window:

(Right-click) Windows Start Icon -> Windows PowerShell (admin) -> Yes


You will see the Windows PowerShell Window:

Windows PowerShell
Copyright (C) Microsoft Corporation. All rights reserved.

Try the new cross-platform PowerShell https://aka.ms/pscore6

PS C:\WINDOWS\system32>


From here we need to get the interface alias of the port that connects us to the Internet. We can do that and look at our current DNS configuration with Get-DnsClientServerAddress:

PS C:\WINDOWS\system32> Get-DnsClientServerAddress

InterfaceAlias               Interface Address ServerAddresses
                             Index     Family
--------------               --------- ------- ---------------
Ethernet 3                          15 IPv4    {,}
Ethernet 3                          15 IPv6    {}
Ethernet 4                          17 IPv4    {}
Ethernet 4                          17 IPv6    {fec0:0:0:ffff::1, fec0:0:0:ffff::2, fec0:0:0:ffff::3}
Loopback Pseudo-Interface 1          1 IPv4    {}
Loopback Pseudo-Interface 1          1 IPv6    {fec0:0:0:ffff::1, fec0:0:0:ffff::2, fec0:0:0:ffff::3}

"Ethernet 3" is the port we're interested in. For laptop or desktops with Wi-Fi adapters you may see "Wi-Fi" instead.


To set the DNS on Ethernet 3 we can use the command Set-DnsClientServerAddress "Ethernet 3" -ServerAddresses ("","").

PS C:\WINDOWS\system32> Set-DnsClientServerAddress "Ethernet 3" -ServerAddresses ("","")
PS C:\WINDOWS\system32>


At this time it may be required to restart the network interface or the whole computer for the changes to take effect. Afterwords try connecting to your local server using the hostname/domain you created in FreeBSD and see what happens. :old-grin:



5.2 - On GNU/Linux


Depending on distribution DNS can be set on GNU/Linux in a variety of ways but we'll focus on the CLI methods if you don't already know how to do it from the GUI.


5.2.1 - Netplan


If you're distribution uses the Netplan client you should be able to edit your DNS configuration from the .yaml file located in /etc/netplan:

user@hostname:~$ cat /etc/netplan/50-cloud-init.yaml 
    version: 2

Edit the nameservers variable. Save. Exit.


Now run sudo netplan try. This will test the config file to see if it has any errors and ask if you want to put your changes into effect:

user@hostname:~$ sudo netplan try
Warning: Stopping systemd-networkd.service, but it can still be activated by:
Do you want to keep these settings?

Press ENTER before the timeout to accept the new configuration

Changes will revert in 117 seconds
Configuration accepted.


At this time it may be required to restart the network interface or the whole computer for the changes to take effect. Afterwords try connecting to your local server using the hostname/domain you created in FreeBSD and see what happens. :old-grin:



5.2.2 - Ifconfig


If your distribution uses the ifconfig client this can be done by editing /etc/resolv.conf:

user@hostname:~# cat /etc/resolv.conf 

At this time it may be required to restart the network interface or the whole computer for the changes to take effect. Afterwords try connecting to your local server using the hostname/domain you created in FreeBSD and see what happens. :old-grin:




At this time if you want to implement this on all of your network devices it's going to be important that your new DNS is not just resolving the hostname(s) of your local server(s) but that it's forwardering everything else to Public DNS providers because without DNS you effectively have no Internet.


We can test if our DNS server is working as intended by giving FreeBSD a Public DNS provider other than our ISP's and going to the website WhoIsMyDNS.com?




WhoIsMyDNS is intended as a hijack prevention testing website but serves the purpose beautifully of showing us what Public DNS provider is resolving our requests. This means if you configured dnsmasq with a DNS other than your ISP's you should see the DNS providers name here. Otherwise you will see your ISP or the ISP's parent company. If you set Google, Cloudflare, etc but this website still says your ISP's DNS then something is wrong with the configuration.


Assuming everything is in order you can take your new founded DNS Forwarding server and add it to your routers DHCP configuration if it permits it.


6. Configuring A Backup DNS (Optional - Recommended)


Now the astute among you will have noticed while explaining how to test the new DNS forwarder I showed examples containing two 192.168.0.X IP's. The reason being even publicly available DNS providers can fail causing mass Internet outages. If your client(s) rely on one you're hosting yourself how well can you guarantee it won't ever go offline?  The solution? Having a primary & secondary DNS server. If you choose to setup a secondary DNS you don't have to use the same Public DNS provider on both. One could be CloudFlare's the second could be Google's.


If you don't want to or can't setup a second server configuring a Public DNS on the Router or each of your clients as a fall back will at least allow you to retain Internet access in the event your server goes down.


For those of who are willing to setup a full second server the only real difference in configuration if you want to keep the same Public DNS for forwarding is to configure an automated service that updates /etc/hosts from DNS1 to DNS2 so whenever changes are made to your /etc/hosts config file you only have to worry about doing it to your primary server.

6.1 - Enabling Remote Root Password Authentication


To more easily setup a automated synchronization task we need to temporarily enable remote root password authentication. This allows remote users to login as root directly. Under normal circumstances this is very undesirable so we will be disabling it again when we're done.


Start by logging into DNS2 and running the command sudo nano /etc/ssh/sshd_config and finding the line #PermitRootLogin no.

# Authentication:

#LoginGraceTime 2m
#PermitRootLogin no
#StrictModes yes
#MaxAuthTries 6
#MaxSessions 10

Change this line to PermitRootLogin yes then save & exit.


From here restart the ssh dameon with sudo /etc/rc.d/sshd restart:

dns@dns-forwarder:~ $ sudo /etc/rc.d/sshd restart
Performing sanity check on sshd configuration.
Stopping sshd.
Waiting for PIDS: 736.
Performing sanity check on sshd configuration.
Starting sshd.
dns@dns-forwarder:~ $


You should now be able to remote into DNS2 as root with your root login password.


6.2 - Configuring Password-Less Public/Private Key Authentication


Now we need a means to allow root on DNS2 to login as our user on DNS1 automatically. This can be done by generating a Password-Less Public/Private Key Pair with the command ssh-keygen:

dns@dns-forwrder:~ $ ssh-keygen
Generating public/private rsa key pair.

You will be asked three questions. All of which leave empty. Just press enter for each:

Enter file in which to save the key (/home/dns/.ssh/id_rsa):
Enter passphrase (empty for no passphrase): 
Enter same passphrase again:

The output of which should look similar to this:

Your identification has been saved in /home/dns/.ssh/id_rsa.
Your public key has been saved in /home/dns/.ssh/id_rsa.pub.
The key fingerprint is:
SHA256:TZ/ItwDEtW8eTXcjqVTEVkevORJ1x/Lv0frkHbd2kUs dns@dns-forwarder
The key's randomart image is:
+---[RSA 2048]----+
|       .... ooo+=|
|       ..  ..+o.=|
|        . o.oo.++|
|         =.+.=.++|
|        S =.O = +|
|           = + Eo|
|            o .+*|
|              .=B|
|              .o=|

This operation generated two files. id_rsa & id_rsa.pub. Now we want to copy id_rsa to DNS2.


To copy the file run the command ssh-copy-id -i .ssh/id_rsa root@<ip_of_DNS2>:

ssh-copy-id -i .ssh/id_rsa root@
password for root@dns-forwarder2:

If this works no output will be generated.


NOTE: Now is the time to go back into DNS2 and revert "#PermitRootLogin yes" to "#PermitRootLogin no". Don't forget to restart the SSH daemon with "sudo /etc/rc.d/sshd restart"! 


6.3 - Configuring RSYNC


From here DNS2 now has the information it needs to login to DNS1 without user intervention. Now we need to use a program called RSYNC to sync our files. RSYNC is a data replication program which supports the nifty little feature of accessing files on remote clients. These clients could be on the LAN or even over the Internet. Before starting make sure you're logged in as root on DNS2.


To create the command start with the word rsync:



After this we append what are known as arguments. These change the way in which RSYNC behaves when executed. We're only interested in two, those being -a & -e which can be compressed down to just -ae.

rsync -ae
  • a = Archive. This preserves various parameters relative to the files being copied and is useful here.
  • e = COMMAND. This allows us to inject a command or part of a command into the RSYNC job.


The command we want to inject tells RSYNC we want to use SSH and the Private Key that we copied over to the system from DNS1. This will be typed out as 'ssh -i .ssh/id_rsa':

rsync -ae 'ssh -i .ssh/id_rsa'


Now to specify the source and destination directories. Our source is going to be the /etc/hosts file located on DNS1. For me that would be typed as dns@

rsync -ae 'ssh -i .ssh/id_rsa' dns@


To designate a destination all we have to do is append our local /etc/hosts file location:

rsync -ae 'ssh -i .ssh/id_rsa' dns@ /etc/hosts

So in summary what this command is saying is...


Login to this remote server..rsync -ae 'ssh -i .ssh/id_rsa' dns@ /etc/hosts

As this user.................rsync -ae 'ssh -i .ssh/id_rsa' dns@ /etc/hosts

Using these credentials......rsync -ae 'ssh -i .ssh/id_rsa' dns@ /etc/hosts

Copy this remote file........rsync -ae 'ssh -i .ssh/id_rsa' dns@ /etc/hosts

Overwrite this local file....rsync -ae 'ssh -i .ssh/id_rsa' dns@ /etc/hosts


Now if you've not remoted into this server already you may receive an unknown server security message. Go ahead and answer Yes that you trust the server you're logging into. If the key was accepted you should be brought right back to a prompt without any further information. Go ahead and check the contents of /etc/hosts on DNS2 and see if the file contains everything you entered into /etc/hosts on DNS1. If it does, we can move on.


6.4 - Creating an RSYNC Script


Taking the command you just created and turning it into a script is a simple job that only requires a couple of commands. This can be done by opening a new file with a text editor:

nano dns-sync.script


Add the following two lines (substituting the second line for your custom RSYNC command):

rsync -a -e 'ssh -i .ssh/id_rsa' dns@ /etc/hosts

Save + Exit.


Now to make this file an executable script run the command:

chmod 744 dns-sync.script



6.5 - Automating the RSYNC Script


To automate the script we're going to be using something known as Crontab which when used in this fashion is also commonly referred to as a Cron Job. Start by running the command crontab -e. Crontab will likely use the VIM editor by default. To edit Crontab press "I" as in "Insert". From here add the lines:

# DNS Syncronization - Pull request: /etc/hosts from DNS1 to /etc/hosts on DNS2
0 * * * * /root/dns-sync.script

The first line is just a comment telling you what the Cron Job is for. The second line is very important. This executes the RSYNC Job once every hour on the hour. Now you don't have to run it that often but once every hour on the hour is denoted by the 0 * * * * at the beginning of the line.


To Save & Exit press ESC followed by :wq.


From now on every hour on the hour DNS2 will query DNS1 for the hostname list and update it's own keeping the two servers in sync without your intervention.



Link to comment
Share on other sites

Link to post
Share on other sites

Create an account or sign in to comment

You need to be a member in order to leave a comment

Create an account

Sign up for a new account in our community. It's easy!

Register a new account

Sign in

Already have an account? Sign in here.

Sign In Now