This project came from the back of my desire to learn more about public key certificates ahead of deploying a two tier PKI for an enterprise network, ahead of this I thought it would be prudent to try something a little smaller scale and see how the nuts and bolts worked and try and deploy a simple single tier PKI at home and see how it could be leveraged.
Cryptography is a big interest of mine and this was the first time I’d dipped my toe in trying to set anything up like this. Given the low power I had to play with I decided to build on a VM for the CA and an additional VM for the DNS server, each with a single vCPU and a 1GB of RAM each given the load they would have to handle.
As with most of my builds, this is Linux based and can be run on just about any hardware and can just as easily be done with a RaspberryPi.
Unlike many of my projects, this one actually has a GUI for the CA, there are options to do it without, but sometimes a GUI is just easier.
Operating System: Ubuntu 16.04
Required Applications for CA: tinyCA2, xorg, xfce4
Required Applications for DNS: bind9, bind9utils, bind9-doc, nslookup, dig
Install CA Pre-Requisite Software
sudo apt-get update apt-get install xorg openssl tinyca xfce4
Upon a reboot, the VM should now have a desktop environment, if this is too fancy, xfce4 can be swapped out for blackbox which even more lightweight.
Configure the CA
It’s important not to do this as root, but rather as a privileged user, so run the application from a terminal using sudo:
sudo tinyca2
This will launch the application.
Now create a new CA with the following parameters:
Name: -ca
Common Name: -ca
Country Code: your country code
Password: enter a root CA password here and record it securely, you will need it
State:
YOUR_STATE
Locality:
YOUR_LOCALITY
Organization:
YOUR_ORG
OU:
YOUR_OU
Email:
enter
Valid: 3650
Key Length: 4096
Hash Digest: SHA-256
The Key Length and Hash Digest are the important values here, the other values like state, OU etc are all arbitrary, but will form the basis of your certificates so at least enter sensible information.
Click Next and leave the rest of the information as defaults.
You now have a solid CA which can be used to issue certificates to sign webservers, devices, encrypted sessions and anything else that can leverage a certificate. This is done by launching tinyCA2, creating a request and singing the request using the CA certificate with that same password. Once you have the new certificate it can be exported (with or without it’s key) and imported in to your device.
Install DNS Pre-Requisite Software
sudo apt-get update sudo apt-get install bind9 bind9utils bind9-doc nslookup dig
Configure bind to use IPv4 only
Unless you’re a crazy person you probably aren’t working in IPv6 yet, and if you are you aren’t reading this. So let’s set the server to use IPv4 only:
sudo systemctl edit --full bind9
Locate the line that reads
[Service]
ExecStart=/usr/sbin/named -f -u bind
and modify it to read
[Service]
ExecStart=/usr/sbin/named -f -u bind -4
Save with CTRL+O and reload and restart the DNS services;
sudo systemctl daemon-reload sudo systemctl restart bind9
Configure the DNS Server
CONFIGURE THE DNS SERVER
First determine the IP address of your system by running ifconfig. You will need this.
Then edit the bind9 options file:
sudo nano /etc/bind/named.conf.options
In the options block set the following values:
options { directory "/var/cache/bind"; recursion yes; allow-recursion { any; }; allow-query { any; }; allow-query-cache { any; }; listen-on { ; }; allow-transfer { none; }; forwarders { 208.67.222.222; 208.67.220.220; }; //dnssec-validation auto; //auth-nxdomain no; }
listen-on should be set to the IP address of your server
forwarders are the external DNS servers that your server should go to for external lookups outside of your network, in this example we’re looking at OpenDNS, however you can use anything, I personally use my firewall which then looks up to OpenDNS.
The any options for recursion, query and cache options would usually be locked to access control lists which can be set elsewhere in the config, such a config should never be done in production however since this is for a small internal network it’s less of a concern.
Configure local options
Next edit the local options file:
sudo nano /etc/bind/named.conf.local
Update the file so it looks as below, replacing 172.16.0.0/24 with your network ID and tinfoilcipher.co.uk with your domain:
acl internals { 127.0.0.1/8; 172.16.0.0/24; }; zone "tinfoilcipher.co.uk" { allow-query { internals; }; type master; file "/etc/bind/zones/db.tinfoilcipher.co.uk"; }; zone "0.16.172.in-addr.arpa" { allow-query { internals; }; type master; file "/etc/bind/zones/db.0.16.172"; };
Save the file with CTRL+O
Configure the Forward lookup zone
To configure a zone file, we first need to create a zone file. As before, replace the domain name with your own domain and network IDs with your own.
cd /etc/bind/zones touch db.tinfoilcipher.co.uk
First, add your SOA (Start of Authority record) by pasting in the below (replacing dns with the hostname of your server) NOTE THE TRAILING FULL STOP:
@ IN SOA dns.tinfoilcipher.co.uk. admin.tinfoilcipher.co.uk. ( 3 ; Serial 604800 ; Refresh 86400 ; Retry 2419200 ; Expire 604800 ) ; Negative Cache TTL
Now to the same file, we add nameserver records:
; name servers - NS records IN NS dns.tinfoilcipher.co.uk.
Then we add A records for the nameservers:
; name servers - A records dns.tinfoilcipher.co.uk. IN A 172.16.0.100
Then we can finally add the remainder of records to the zone:
;172.16.0.0/24 - A records server1.tinfoilcipher.co.uk. IN A 172.16.0.10 server2.tinfoilcipher.co.uk. IN A 172.16.0.20 ;172.16.0.0/24 - CNAME records ca IN CNAME server1.tinfoilcipher.co.uk. radius IN CNAME server1.tinfoilcipher.co.uk. vpn IN CNAME server2.tinfoilcipher.co.uk.
Finally, save the file with CTRL+O
Configure the reverse lookup zone
CONFIGURE THE REVERSE LOOKUP ZONE
The reverse lookup zone allows for reverse DNS lookup, this is essential for proper DNS configuration:
cd /etc/bind/zones touch db.0.16.172 sudo nano /etc/bind/zones/db.0.16.172
The process here is much the same but for reverse entries:
First create the SOA record:
$TTL 604800 @ IN SOA dns.tinfoilcipher.co.uk. admin.tinfoilcipher.co.uk. ( 4 ; Serial 604800 ; Refresh 86400 ; Retry 2419200 ; Expire 604800 ) ; Negative Cache TTL
BE SURE TO INCREMENT THE SERIAL NUMBER BY 1
Add the nameserver record:
; name servers - NS records IN NS dns.tinfoilciper.co.uk.
Add the PTR records, one is required for each A record and the record should be named with only the subnet and host bits of the record in question:
; PTR Records 0.10 IN PTR server1.tinfoilcipher.co.uk. ; 172.16.0.10 0.20 IN PTR server2.tinfoilcipher.co.uk. ; 172.16.0.20
Finally save the file with CTRL+O
Verify DNS Configuration and Complete
Run the below commands to verify the configuration files and zone files:
sudo named-checkconf sudo named-checkzone tinfoilcipher.co.uk db.tinfoilcipher.co.uk sudo named-checkzone 0.16.172.in-addr.arpa db.0.16.172
If any errors are returned, there is an error in your file syntax, usually a missing bracket, semicolon or curly brace.
Finally, restart the DNS service:
sudo systemctl restart bind9
You should now be able to point any clients at this DNS server and use it correctly. You can now also issue certificates to your services and webservers using CNAMEs that exist in your DNS server.