Windows and Linux Name Resolution – Choosing A domain name for your home network

In my early days of being IT, I used to connect to everything via IP address. This was fine in a small network. But it gets harder when you have to look after a large amount of servers. It hard remembering all those IP address. We can use host names which would be resolved by DNS to solve this problem.

Using DNS also helps with server migrations, because if the clients are using DNS resolution of host names to connect to a service like a SMTP or a webserver, then you only need to update the DNS name in one place and once the TTL (Time To Live – the cache expiry time for that DNS record) is reached, the client will request the IP address for that DNS name again. If you had hardcoded the IP address on the client, you would have to manually update the settings on each device when the service is migrated.

A hostname can be a short name, such as server-a or the server could use a FQDN (Fully Qualified Domain Name) like server-a.example.net. The name resolution process that resolves the IP address is different for Windows and Linux, and can also be different if you are trying to access a SMB/CIFS service share as opposed to a URL.

If you are using an internal DNS server, for example, in a Windows Active Directory environment, choose wisely what domain name you want to pick as this could trip you up in the future, especially if you are planning to use a Linux desktop OS or trying to get a TLS (SSL) Certificate from a Trusted TLS provider.

When Windows 2000 Server introduced Active Directory, using DNS you had to choose a root DNS namespace. Microsoft recommended using .local. i.e.: company.local. This is now considered to be a bad idea because in 2003, The IETF (Internet Engineering Task Force) standards created RFC 6762 which reserves the use of the domain name label .local as a pseudo-top-level domain for hostnames in local area networks that can be resolved via the mDNS (Multicast Domain Name Service) name resolution protocol. I’ll cover this more when we discuss Linux name resolution on an Ubuntu desktop OS. Also, since 1st November 2015, publicly trusted CA (TLS Certificate Authorities) are not allowed to produce certificates using the .local TLD (Top Level Domain).

Windows DNS Resolution

Windows has two routes to follow for Name Resolution – FQDN and short name resolution. With short name resolution, since Microsoft Windows 2000, if a computer is looking to talk to server-a, and it has a DNS Server configured in the network card configuration settings, it will try to resolve the name to an IP address following this method:

  1. Checks the local host file in C:\Windows\System32\Drivers\etc\hosts to see if there is an entry existing for this hostname.
  2. Query the DNS server. If you have DNS suffixes configured in the network card configuration, it will try and resolve them in order, for example, if you have company1.example.net,company2.example.net configured in the DNS suffixes. It will ask for the IP address for server-a.company1.example.net and if this is not found it will ask for server-a.company2.example.net and so on.
  3. Check the local NetBIOS name cache to see if it has been resolved before.
  4. If a WINS (Windows Internet Naming Service) server is configured in the network settings, it will ask that service to resolve the IP address.
  5. If a WINS server is not configured on the network for NetBIOS name resolution, NetBIOS names are resolved into IP addresses through a NAME QUERY REQUEST broadcast. The computer that has the NetBIOS name included in the NAME QUERY REQUEST message has to reply to the sender and return its IP address.
  6. The last thing to be checked is the LMHOSTS file: LMHOSTS files is a text file, similar to the HOSTS file used for name resolution for TCP/IP based networks. This LMHOSTS files contain host name to IP address mapping and is located in C:\Windows\System32\Drivers\etc\lmhosts.sam.

With a FQDN, if you are trying to resolve server-a.example.net, then the OS will only try the first 2 steps.

Linux DNS Resolution

In Linux, the default order on an Ubuntu 18.04 OS Desktop is:
1. Files
2. mdns4_minimal
3. dns

The order can be changed by editing the /etc/nsswitch.conf file.

Here the order in more details

Files

The file /etc/hosts is checked to see if there is an entry in the host file.

mdns4_minimal

If an mDNS or Multicast DNS service is provided Avahi/Bonjour daemon, that lets small network computers resolve names even when no central DNS is present. It uses, by default, the .local domain for resolving hosts on that network. mDNS does not cross subnet boundaries, and performs a local broadcast (e.g. 192.0.2.255 when your network is 192.0.2.0/24) to resolve the DNS name.

DNS

DNS servers, defined in /etc/resolv.conf are used for DNS Lookups.

Even with a fresh install of Ubuntu 18.04, even if you define DNS servers in the network manager, 127.0.0.53 is configured in the /etc/resolv.conf. This is because 18.04 uses systemd-resolved as a local DNS resolver. This service provides network name resolution to local applications, and implements a caching and validating DNS/DNSSEC stub resolver (basically, it can perform DNS lookups for your applications), as well as providing an LLMNR (Link-Local Multicast Name Resolution) and mDNS resolver and responder. It listens on a local IP (127.0.0.53) on UDP port 53. If the DNS request can’t be answered from its own cache or via mDNS, it will forward the DNS query to the server specified in network manager, and then cache the response for later.

.local and Ubuntu

I have always used .local just out of habit and have an Active Directory Domain Controller at home providing DNS and DHCP, in my case home.local. This was all OK until I started using a Linux desktop OS at home. Accessing SMB/CIFS/Samba shares this seemed to work fine because it uses a NetBIOS broadcast to find it.

The problem I was having was if I used a hostname or FQDN to access a webserver via a browser the system would not resolve the IP address. The DNS server setting were provided by DHCP and pointed to my local DNS server. If I used nslookup it was using 127.0.0.1 as is the DNS server to query, so it was using itself to resolve the IP address, but nslookup was not resolving the address via the DNS server defined in the network manager because, as I was using a .local TLD it was being treated as mDNS and not passing it to my normal DNS server.

So I somehow I needed to get the OS to talk directly to my local DNS and not systemd-resolve. If you look at /etc/resolv.conf it is a symbolic link to /run/systemd/resolve/stub-resolv.conf. This has the DNS server defined as 127.0.0.53 as the DNS server.

To get this to work for me I removed the symbolic link for /etc/resolv.conf and create a new symbolic link to /run/systemd/resolve/resolv.conf. This file contains the correct IP address of the DNS servers provide by the DHCP.

Here’s how I did it:

# Delete the existing symbolic link to /etc/resolv.conf file
sudo rm -f /etc/resolv.conf 
# Create a new symbolic link 
sudo ln -s /run/systemd/resolve/resolv.conf /etc/resolv.conf 
# Verify that the command has worked and the symbolic link is created
ls -l /etc/resolv.conf 

If I now use nslookup, it reports that it’s using my local DNS server and returns the correct IP address for my .local addresses, however, if I try to ping from the command line it still does not resolve hosts with the .local domain suffix. This is because the order in which DNS is searched in /etc/nsswitch.conf is still set to file,mdns4_minimal,dns. We already know that there is no entry in /etc/hosts so next it tries to use mdns4_minimal, but because I am using a .local domain name the mdns4_minimal tries to discover the hostname with mDNS, and a failure here stops the lookup. Instead, though, I can edit /etc/nsswitch.conf and remove mdns4_minimal (so now it says file,dns). I can now ping the address from the command line because the order is now the local host file and then DNS. This does, however, mean that I can’t use mDNS anymore.

Conclusion

When rebuild my home network, I want to choose a new domain name. Some people are suggesting that I should use something like home.lan, but doing further research I would probably use a domain name that I own and then add a subdomain for my internal network, something like ad.mydomain.example.net.

Some reading on choosing a good active directory name:

http://techgenix.com/active-directory-naming/

https://social.technet.microsoft.com/wiki/contents/articles/17974.active-directory-domain-naming-considerations.aspx

Wireguard for remotely accessing VPS with Linux Clients which have a dynaminc IP address

I have a VPS on the internet which has a public IP address. I have never been a great fan of exposing SSH and other services which only I need access to. Normally I lock down the firewalls on the VPS for the services to a static Public IP address i will be sitting behind, normally my home broadband connection or my work office. Lately i have been traveling a lot and need to access one of these services but did not have acess to come from one of these static Public IP address.

I would like to set up a simple Client to Server VPN Configuration, so i don’t need to come from a static public IP address. I heard of Wireguard at Oggcamp and thought I’d give it a go.

Wireguard Overview

Above I show a diagram of the setup this guide provides.

I have a Ubuntu 16.04 server with a public IP address and a laptop running Ubuntu which is behind router with a dynamic public IP Address and the laptop has been given a internal IP address via DHCP.

We will:

  • install wireguard on both the server and laptop
  • create a wireguard network interface on them
  • generate keys on both server and laptop
  • create the config on both server and laptop
  • enable firewall rules and IP forwarding the server
  • test connectivity between the server and laptop

Install Wireguard

Add the Wireguard repository to your sources list on both devices.

sudo add-apt-repository ppa:wireguard/wireguard

Install Wireguard on both devices. The wireguard package will install all necessary dependencies.

sudo apt-get update
sudo apt install wireguard

Generate Configs

On the server and laptop create the public and private keys.

umask 077
wg genkey | tee privatekey | wg pubkey > publickey

Take a note of each of the private and public key on both devices

cat publickey
cat privatekey

On the server create the config file

sudo vi /etc/wireguard/wg0.conf

Add the following information and replacing the PrivateKey and PublicKey from the output of the notes you take in the previous step.

[Interface]
Address = 10.1.1.1/24
PrivateKey = ReplaceWithServerPrivateKey
ListenPort = 55555

[Peer]
PublicKey = ReplaceWithLaptopPublicKey
AllowedIPs = 10.1.1.2/32

On the client create the config file

sudo vi /etc/wireguard/wg0.conf

Add the following, replacing the PrivateKey and PublicKey from the output of the notes you take in the previous step and replace the Endpoint with the public IP address or Hostname of the server.

[Interface]
Address = 10.1.1.3/24
PrivateKey = ReplaceWithLaptopPrivateKey

[Peer]
PublicKey = ReplaceWithServerPublicKey
AllowedIPs = 10.1.1.0/24
Endpoint = wireguard.example.com:55555
PersistentKeepalive = 10

Edit firewall to allow port 55555 in. My VPS provides this so i edit the firewall rule via their portal. You may need to add this in your IP tables firewall rules.

On the server enable IP forwarding.

Edit file /etc/sysctl.conf uncommtend the following line.

net.ipv4.ip_forward=1

Run this command to make the change take effect.

sysctl -p

Testing

bring up the interface on each device.

sudo wg-quick up wg0

type to see the state of the interfaces

wg

From the laptop you should be able to ping 10.1.1.1

To make the wg0 interface come up on every boot, shutdown the wg0 interface.

wg-quick down wg0

Run the following cmd to enable the wireguard as systemd unit

systemctl enable wg-quick@wg0 ; systemctl start wg-quick@wg0