20 September 2019

The Power of DNS

Years ago I wrote a somewhat shallow article on setting up a couple recursive BIND DNS servers to take the load off of the domain controllers titled The Day the DNS Died / BIND Triage Server Array.  I was pleased, although a little surprised, to hear recently that those machines are still ticking away.  There are so many more elegant ways to fix those problems now, but I guess BIND is bulletproof, and if it ain't broke, don't fix it.


What IS broken are the number of small networks, or isolated subnets of larger networks that don't have a DNS server.  I was recently doing some security consulting for a client, and a recommended that they disable netbios on all the machines (NetBIOS can help to mitigate an attacker's ability to: poison and spoof responses, obtain a user's hashed credentials, inspect web traffic, etc. That is another blog post) and the next day I got a call that they couldn't reach any network resources any more..... huh?  No dns, they were relying on netbios to resolve everything.  It's madness.

I have seen this all over the place, or worse, I have seen where net-admins don't want to spend the time to put dns on an isolated network or protected DMZ and just put everything in HOST files... MADNESS.

A DNS server, a DNS server, my Kingdom for a DNS server

We are going to walk through a simple, but powerful DNS server option called PowerDNS.  It is extensible, capable, flexible, and powerful... see what I did there.  We are going to use a SQL backend, because anyone can use a zone file (technically this can to).  The advantage of the SQL backend is historical data and the speed of not having to parse an entire text file.  We can even talk about front end options.  At the very end, we will add in a recursor, for those who need more than an authoritative dns for a closed system (i.e. internet access)


I don't know the state of your server, but lets assume your the type of person who has been relying on NETBIOS and logs into SSH as root.

1. Forget about the Ubuntu server and run CentOS, otherwise lots of this tutorial won't make sense.
2. Create a user that can sudo

adduser username
passwd username
usermod -aG wheel username

2. Remove root from being able to ssh

sudo vi /etc/ssh/sshd_config
PermitRootLogin no
sudo service sshd restart

3.  Setup the firewall

sudo yum install firewalld
sudo systemctl enable firewalld
sudo systemctl start firewalld
sudo firewall-cmd --list-all
sudo firewall-cmd --zone=public --permanent --add-service=dns
sudo firewall-cmd --reload

4. Reboot

5. Make sure you are fresh and clean .... update.

sudo yum update

Finally to Business

1. Install Pre-Reqs

sudo yum install epel-release yum-plugin-priorities wget bind-utils net-tools

2. Install and configure MariaDB

sudo yum -y install mariadb-server mariadb
sudo systemctl enable mariadb.service
sudo systemctl start mariadb.service
sudo mysql_secure_installation

3. Install PowerDNS

sudo curl -o /etc/yum.repos.d/powerdns-auth-41.repo https://repo.powerdns.com/repo-files/centos-auth-41.repo
sudo yum install pdns
sudo yum install pdns-backend-mysql

4. Do Scary things with MariaDB
Don't freak out, we will take these one at a time

mysql -u root -p

GRANT ALL ON powerdns.* TO 'powerdns'@'localhost' IDENTIFIED BY 'PASSWORD';
USE powerdns;


CREATE TABLE domains (
last_check INT DEFAULT NULL,
) Engine=InnoDB CHARACTER SET 'latin1';
CREATE UNIQUE INDEX name_index ON domains(name);

CREATE TABLE records (
content VARCHAR(64000) DEFAULT NULL,
change_date INT DEFAULT NULL,
disabled TINYINT(1) DEFAULT 0,
) Engine=InnoDB CHARACTER SET 'latin1';

CREATE INDEX nametype_index ON records(name,type);
CREATE INDEX domain_id ON records(domain_id);
CREATE INDEX ordername ON records (ordername);

CREATE TABLE supermasters (
nameserver VARCHAR(255) NOT NULL,
PRIMARY KEY (ip, nameserver)
) Engine=InnoDB CHARACTER SET 'latin1';

CREATE TABLE comments (
domain_id INT NOT NULL,
modified_at INT NOT NULL,
) Engine=InnoDB CHARACTER SET 'latin1';

CREATE INDEX comments_name_type_idx ON comments (name, type);
CREATE INDEX comments_order_idx ON comments (domain_id, modified_at);

CREATE TABLE domainmetadata (
domain_id INT NOT NULL,
kind VARCHAR(32),
content TEXT,
) Engine=InnoDB CHARACTER SET 'latin1';
CREATE INDEX domainmetadata_idx ON domainmetadata (domain_id, kind);

CREATE TABLE cryptokeys (
domain_id INT NOT NULL,
active BOOL,
content TEXT,
) Engine=InnoDB CHARACTER SET 'latin1';
CREATE INDEX domainidindex ON cryptokeys(domain_id);

CREATE TABLE tsigkeys (
name VARCHAR(255),
algorithm VARCHAR(50),
secret VARCHAR(255),
) Engine=InnoDB CHARACTER SET 'latin1';
CREATE UNIQUE INDEX namealgoindex ON tsigkeys(name, algorithm);

That was a bit..... now go get a coffee and some chocolate, maybe a nice glass of scotch.  In this example we are installing PDNS 4.1 because I like it and I think it is very stable.  If you install a different version, there is a different scheme... always reference this: https://doc.powerdns.com/authoritative/guides/basic-database.html

5. Configure PDNS

sudo mv /etc/pdns/pdns.conf /etc/pdns/pdns.conf.bu
sudo vi /etc/pdns/pdns.conf

# pdns.conf


6. Start her up

sudo systemctl enable pdns.service
sudo systemctl start pdns.service

7. Add Zones and Records

Start Simple.  Use the pdnsutil command to create zones and records (https://doc.powerdns.com/authoritative/manpages/pdnsutil.1.html)


create-zone ZONE
Create an empty zone named ZONE.


Add one or more records of NAME and TYPE to ZONE with CONTENT and optional TTL. If TTL
is not set, the default will be used.


# pdnsutil create-zone example.com ns1.example.com
Creating empty zone 'example.com.'
Also adding one NS record
# pdnsutil add-record example.com ns1 A
New rrset:
ns1.example.com. IN A 3600

# pdnsutil list-zone example.com
example.com.    3600    IN      NS      ns1.example.com.
example.com.    3600    IN      SOA     ns1.example.com hostmaster.example.com 1 10800 3600 604800 3600
ns1.example.com.        3600    IN      A

$ dig +noall +answer ns1.example.com @ 
ns1.example.com.        3600    IN      A

Done .... ish

There are 3 other, possible simpler, methods for managing PDNS.

1. Webmin - Follow the instructions, use the MySQL plugin to manage your data.
2. phpMyAdmin -  Same as above.  Follow the instructions, manage everything in the tables you just created.
3. PowerAdmin - PowerAdmin is purpose built for PDNS.  I recommend it on at least one machine.  I don't use it on all of them, because I have replication enabled, but it is a simple powerful interface with minimal weight.

To install PowerAdmin

Follow these Directions: https://www.howtoforge.com/how-to-install-powerdns-and-poweradmin-on-centos-7/


So, everything is installed, and running, if you have worked through some bugs, but now have a major hangup.... it resolves all of your internal networks, but it won't resolve the google.com ... or *gasp* it won't resolve tomvoboril.com.


In a network, it is really a better practice to separate out your authoritative DNS servers, which we just built, and your internal recursive DNS servers.  Simple said.  If you did not need anything to resolve internally, you would just point to your ISPs DNS, or google's DNS, or OpenDNS, etc.  It is very simple to install a small recursor to break out traffic between internal and external.  We will run it on the same server as the authoritative, and do some fancy binding.

1. Install PowerDNS Recursor

sudo yum install pdns-recursor

2. Configure pdns-recursor

sudo mv /etc/pdns-recursor/pdns-recursor.conf /etc/pdns/pdns-recursor.conf.bu
sudo vi /etc/pdns-recursor/pdns-recursor.conf


2 lines of config.  make sure you bind it to the boxes IP, and the network.local is whatever you want the authoritative to run.

3.  Configure PDNS to bind to local.

sudo mv /etc/pdns/pdns.conf /etc/pdns/pdns.conf.bu2
sudo vi /etc/pdns/pdns.conf



Add the yellow highlighted line to your PDNS config

sudo systemctl restart pdns.service
sudo systemctl enable pdns-recursor.service
sudo systemctl start pdns-recousor.service

Try it now....

18 September 2019

Redmine 4 with Puma and Nginx on Centos

Everyone's environments are different, but this should work for most and avoid some pitfalls that you are likely to fall into if you follow some of the other tutorials out there.
First and Foremost, get Centos 7 Minimum installed, make sure it has access to the internet and that your account is a sudoer.  Don't use root.... RVM doesn't like that.

Next install your core bits

sudo yum update
sudo yum install vim curl zlib-devel curl-devel openssl-devel httpd-devel apr-devel apr-util-devel mysql-devel ftp wget ImageMagick-devel gcc-c++ patch readline readline-devel zlib libyaml-devel libffi-devel make bzip2 autoconf automake libtool bison subversion sqlite-devel
sudo yum install epel-release
sudo yum install nginx

At this point, I leave it up to you how you want to deal with selinux.  You can search the internets to get a better idea, you can either disable temporarily or edit the config file and disable it.

sudo setenforce 0
sudo vim /etc/selinux/config

Next, take a moment to install MariaDB, and secore it, before we go on to configure it.

sudo yum install mariadb-server
sudo systemctl start mariadb
sudo systemctl enable mariadb


mysql -uroot -p

Now we setup the redmine database.  Pay attention to where you need to supply the password.

mysql -uroot -p
MariaDB [(none)]> CREATE DATABASE redmine CHARACTER SET utf8;
MariaDB [(none)]> GRANT ALL PRIVILEGES ON redmine.* TO 'redmine'@'localhost' IDENTIFIED BY 'redmine_passwd';
MariaDB [(none)]> \q

Finally we get to install RVM and the magic begins.

\curl -sSL https://get.rvm.io | sudo bash -s stable

You might get told to download the gpg key, do so. At the end you will get a message that contains a few important things. PAY ATTENTION

  * First you need to add all users that will be using rvm to 'rvm' group,
    and logout - login again, anyone using rvm will be operating with `umask u=rwx,g=rwx,o=rx`.

  * To start using RVM you need to run `source /etc/profile.d/rvm.sh`
    in all your open shell windows, in rare cases you need to reopen all shell windows.
  * Please do NOT forget to add your users to the rvm group.

So take a moment to add yourself and nginx to the rvm group.  After that, log out, reboot, get some coffee.

 sudo usermod -a -G rvm USER
 sudo usermod -a -G rvm nginx

Now, we are going to do 4 things.
1. Install Ruby 2.5.5
2. Create a gemset for our application
3. Use said gemset
4. Make any other user who is working on this with us lives easier by setting said gemset as the default.

rvm install ruby-2.5.5
rvm gemset create redmine
rvm use 2.5.5@redmine
rvm use --default 2.5.5@redmine

Onwards to Redmine

We are going to put it in /var/www because that is what normal people do (here is looking at you ubuntu)

Follow the next few steps and we will meet back at the database config

cd /var/www
sudo svn co http://svn.redmine.org/redmine/branches/4.0-stable redmine

sudo cp redmine/config/configuration.yml.example redmine/config/configuration.yml
sudo cp redmine/config/database.yml.example redmine/config/database.yml

sudo vim redmine/config/database.yml

Ok, We are using Maria DB, so we are going to configure mysql12 in the Production enviroment.  It should look like this:

  adapter: mysql2
  database: redmine
  host: localhost
  username: redmine
  password: "redmine_passwd"
  encoding: utf8

Now, a small aside, we want to add the Gem "puma" to our gemfile in Redmine under production, and remove it from test and development.

sudo vim /var/www/redmine/Gemfile

source 'https://rubygems.org'

gem "bundler", ">= 1.5.0"

gem "rails", "5.2.3"
gem "puma"
gem "rouge", "~> 3.3.0"
gem "request_store", "1.0.5"
gem "mini_mime", "~> 1.0.1"
gem "actionpack-xml_parser"
gem "roadie-rails", "~> 1.3.0"
gem "mimemagic"
gem "mail", "~> 2.7.1"
gem "csv", "~> 3.0.1" if RUBY_VERSION >= "2.3" && RUBY_VERSION < "2.6"

gem "nokogiri", (RUBY_VERSION >= "2.3" ? "~> 1.10.0" : "~> 1.9.1")
gem "i18n", "~> 0.7.0"
gem "xpath", "< 3.2.0" if RUBY_VERSION < "2.3"

Make sure it is up there at the top, and NO WHERE ELSE.

Now, from www change the owner of redmine to your user, install bundler and run the bundler.

sudo chown USER -R redmine
gem install bundler
bundle install --without development test

If that all goes well, get the database setup

rake generate_secret_token
RAILS_ENV=production rake db:migrate
RAILS_ENV=production REDMINE_LANG=en rake redmine:load_default_data

Now, from WWW, make a place for your puma socket to run (you may have to give it 777 or user nginx if you run into problems.

sudo mkdir share
sudo mkdir share/sockets

Almost done, change the owner of redmine to nginx and load up you puma.service file

sudo chown nginx -R redmine
sudo vim /etc/systemd/system/puma.service

The local ruby/puma wizard at work helped me whip up this next file.  There are options in there to do things a few different ways, but if you leave it as is, you should be fine.  You can see you can also test by putting it on a local port.

Description=Puma HTTP Server

# Foreground process (do not use --daemon in ExecStart or config.rb)

# Preferably configure a non-privileged user

# The path to the puma application root

# The command to start Puma. The top one creates a scocke
# The bottom one creates a port
ExecStart=/usr/local/rvm/wrappers/ruby-2.5.5@redmine/bundle exec puma -e production -b unix:///var/www/share/sockets/puma.sock
#ExecStart=/usr/local/rvm/wrappers/ruby-2.5.5@redmine/bundle exec puma -e production -b "tcp://"

# Variant: Use config file with `bind` directives instead:
# ExecStart=<WD>/sbin/puma -C config.rb
# Variant: Use `bundle exec --keep-file-descriptors puma` instead of binstub



Now make a copy of your nginx configuration, and edit it to add : include sites-enabled

sudo cp /etc/nginx/nginx.conf /etc/nginx/nginx.conf.bu
sudo vim /etc/nginx/nginx.conf

    # Load modular configuration files from the /etc/nginx/conf.d directory.
    # See http://nginx.org/en/docs/ngx_core_module.html#include
    # for more information.
    include /etc/nginx/conf.d/*.conf;
    include /etc/nginx/sites-enabled/*;
    server {

You can remove the default server, but change it to port 81 if you do.  It can be good for testing.
Right above server... add that line.  Now, make some sites to include

sudo mkdir /etc/nginx/sites-enabled
sudo vim /etc/nginx/sites-enabled/redmine.conf

There are, again, two options here.  The port is for testing, the socket is for production

#server {
#  listen 80;
#  listen [::]:80;
#  server_name yoursite.com;
#  location / {
#      proxy_pass http://localhost:3000/;
#  }

# http context

upstream backend_hosts {
#    server localhost:3000;
     server unix:///var/www/share/sockets/puma.sock;

server {
    listen 80;
    server_name yoursite.com;

    location / {
        proxy_pass http://backend_hosts;

Now, wrap everything up, enable the things, open the firewall, and do a good reboot at some point to make sure it ACTUALLY works.

sudo systemctl enable puma
sudo systemctl enable nginx
sudo systemctl start puma
sudo systemctl start nginx
sudo service nginx status
sudo service puma status
sudo firewall-cmd --permanent --zone=public --add-service=http 
sudo firewall-cmd --reload

31 March 2018

Paschal Candle

Since the kids were old enough to go to Easter Vigil, we have made a Paschal Candle on Holy Saturday.  The process is fairly simple, take a large pillar candle, carve a cross, the year, and the Alpha and Omega.  Next the kids apply tempera paint to the general area, you wipe off the excess... and you have a Paschal Candle that you can use to walk through what they are going to see at the Easter Vigil.

This year, we did make the candle from 100% bleached beeswax, and had the candle blessed on Candlemas.

Through the years, we have tried various designs, and methods.  Any more, I have a template that I either cut out and trace, or print in reverse, trace with pencil, and rub onto the candle.

I use GIMP to edit the template, and the font I use for the numbers is "Old London"

Feel free to edit, use, etc the template.  I have used some fancy tools to carve candles, but the best ones we have done have just been carved with a large nail.

Paschal Candle Template

Some day, I will get some decent candle painting medium and gesso so I can apply gold leaf to the inside of the cross:

17 March 2018

Fr. Joseph Neilson, OCD

Today, March 17th is the anniversary of the passing of a dear friend of our family, Fr. Joseph Neilson, OCD.  Fr. Joseph was a Discalced Carmelite.  It was fitting that he was born on the feast of the Holy Innocents (December 28, 1932) as he was instrumental in the founding of problem pregnancy centers in Texas, Arkansas, and elsewhere.  He was a great scholar, and despite a debilitating car accident, he challenged those around him and a spiritual and intellectual level. On a more personal note, he was a great friend and spiritual rock for Hannah and I when we were engaged and first married.

During one of our trips to the Marylake Monastery to drive Fr. Joseph to get ice cream he shared a prayer with us.  He told us it was his little prayer when he reached into a bag of chips, or had any other small snack: Dominus qui fecit totum, benedicat cibum et potum; May the Lord Who made everything, Bless this food and drink.

We have kept the page he wrote on, and have hung it in our kitchen, from the very beginning of our marriage, till now.  It has seen better days, but it reminds us that in all things, great and small, to God be the glory.

We miss you Fr. Joseph, and while we feel fairly certain that March 17th 2012 was your entrance day into heaven, we do as you ask and pray for your soul and all the souls of the faithful departed.

02 February 2018


Feast of the Presentation of Jesus in the Temple
Feast of the Purification of the Blessed Virgin Mary

February 2nd

One of the things I miss most about teaching, is the rhythm of the school year.  Teachers are teased about their ever changing bulletin boards, but the reality is they are an excellent example of the ebb and flow of the school year.  There is always something to be putting away until next year, something to be doing right now, and something to be preparing for.  Working outside of a school system now, it is very easy to get stuck in a rut where every day is just a continuation of the previous; there is always work to do and what doesn't get done today will need to get done tomorrow.  My consolation, then, is that the Church gives us seasons and feasts to give rhythm and flow the the whole year.

Today, Candlemas, is one of my favorite feast days.  Two feast days, really.  In Jewish custom, not only did the first born male need to be purchased back from God with two turtledoves or two young pigeons, but a woman who had given birth was considered unclean, so purification was necessary.  Hence the two feast days.

The Gospel for today does a better job explaining:

Luke 2:22-40 Revised Standard Version Catholic Edition

And when the time came for their purification according to the law of Moses, they brought him up to Jerusalem to present him to the Lord (as it is written in the law of the Lord, “Every male that opens the womb shall be called holy to the Lord”) and to offer a sacrifice according to what is said in the law of the Lord, “a pair of turtledoves, or two young pigeons.” Now there was a man in Jerusalem, whose name was Simeon, and this man was righteous and devout, looking for the consolation of Israel, and the Holy Spirit was upon him. And it had been revealed to him by the Holy Spirit that he should not see death before he had seen the Lord’s Christ. And inspired by the Spirit[a] he came into the temple; and when the parents brought in the child Jesus, to do for him according to the custom of the law, he took him up in his arms and blessed God and said,

“Lord, now lettest thou thy servant depart in peace,
according to thy word;
for mine eyes have seen thy salvation
which thou hast prepared in the presence of all peoples,
a light for revelation to the Gentiles,
and for glory to thy people Israel.”

And his father and his mother marveled at what was said about him; and Simeon blessed them and said to Mary his mother,

“Behold, this child is set for the fall[b] and rising of many in Israel,
and for a sign that is spoken against
(and a sword will pierce through your own soul also),
that thoughts out of many hearts may be revealed.”

And there was a prophetess, Anna, the daughter of Phan′u-el, of the tribe of Asher; she was of a great age, having lived with her husband seven years from her virginity, and as a widow till she was eighty-four. She did not depart from the temple, worshiping with fasting and prayer night and day. And coming up at that very hour she gave thanks to God, and spoke of him to all who were looking for the redemption of Jerusalem.

And when they had performed everything according to the law of the Lord, they returned into Galilee, to their own city, Nazareth. And the child grew and became strong, filled with wisdom; and the favor of God was upon him.

Because of Simeon's words about Jesus being the light to the gentiles, the Church has traditionally blessed the candles to be used during the coming year: Candlemas.

There was an excellent article written in 1942 by a Fr. John Bolen titled The Wax Candle in the Liturgy, and I highly recommend reading it.  Years ago, when we started making candles for our home use, we used paraffin wax.  It was cheap and easy to work with, but recently we have switched to 100% beeswax.  If you are looking for a reason to switch to beeswax candles, the interwebs will give you plenty of reasons.  I do not, however, dip all our candles.  We use tin molds to make both tapers and pillar candles.  In my mind, it is out of economy.  When we dip candles, you always have to have around 4 lbs of wax melted so that the candles don't get stumpy.  When we pour candles, we can use every last drop.

In the sense that we prepare candles before actual Candlemas, we started celebrating weeks ago!

This year, we made white candles, as well as colored candles for our Advent wreath.  The colors we choose were Violet and Rose.  I recommend dye flakes vs pigments.  They are easy to measure and mix, and don't clog the candles.

We then took the candles to Mass with us, and they were blessed!

 We had a wonderful dinner by candlelight, and enjoyed an evening remembering that Christ came into the world to be a light to all of us.

Everything does taste better by candle light....


The Nativity scene will be packed up tomorrow, as we close out Christmastide and we will start gathering everything to start Lent in a few weeks.  All the best from our family to your's.  May your evening be a blessed one, and the coming year be full of grace and peace.

01 February 2018

Multi Factor Authentication - Duo and Yubikey

Multi Factor Authentication / 2 Factor Authentication, is not just all the rage today, but a necessity in today's ultra-connected world.  The balance between security and convenience is a hard one, but has to be weighed and measured for you, your information, and the assets you are responsible for.


I have used, implemented, advised, and researched several forms of Multi Factor Authentication (MFA).  Simply stated, MFA or 2FA just means that you are required to have two pieces to authenticate.  Generally these fall under one of three categories:  knowledge (something you know); possession (something you have), and inherence (something you are).  That means, knowing a password (knowledge) AND having an usb smart card plugged in (possession).  The implementation on many social media and shopping sites is having a password AND having a number generated by a timed one-time-password (TOTP) dongle/app (possession), although SMS is not technically 2FA because it can be spoofed, but it is still 2SV.  This could also be having a bio-metric finger print reader (inherence) and a hardware generated one time password (HOTP possession).

Some Definitions:

2FA - 2 Factor Authentication, use of 2 different MFA methods.
2SV - 2 Step Verification, use of 2 authentication methods that are NOT distinctly different.
AD - Active Directory, Microsoft enterprise level central store for usernames and passwords.
Biometrics - Using unique human attributes to authenticate.
FERPA - Family Educational Rights and Privacy Act, safeguards and security provisions to protect student information, and to allow Parents and Students reasonable access to their data.
HIPPA - Health Insurance Portability and Accountability Act of 1996, safeguards and security provisions to protect medical information
HOTP - Hardware One Time Password, password generated by physical dongle that generates the next password based on an algorithm and successive key presses.
Inherence - Inherence Factor, a factor of MFA, aspects that are integral to the individual in question, like biometrics. Something you are.
International Safe Harbor Privacy Principles - principles developed to prevent private organizations withing the European Union from accidentally disclosing or losing personal information.
Knowledge - a factor of MFA, something that is known only to the user, like a password. Something you know.
MFA - Multi Factor Authentication, any time that 2 or more unique authenticating factors are required to allow access to a resource or asset, this includes 2FA, 3FA, 4FA, etc. Factors include Knowledge, Possession, and Inherence
NFC - Near-Field Communication, wireless technology that allows communication over short distances, usually an inch or less.
NIST - National Institute of Standards and Technology, sets the standards and recommendations for MFA.
OTP - One Time Password, A password that can only be used once.  Based on time or key presses and generated based on pre-shared information and an algorithm.
PCI - Payment Card Industry, most often referring to Payment Card Industry Data Security Standard, a set of security requirements for credit card processors.
PIV - Personal Identity Verification, a standard for a specific type of smart-card that can be used as an access card.  Standardized by FIPS 201 and is used by federal agencies.
PKI - Public Key Infrastructure, all components necessary for using public key encryption.  Utilizes public and private keys for encryption.
Possession - a factor of MFA, something physical that can not be duplicated or spoofed that is used to authenticate or verify a specific user. Something you have.
SmartCard - any number of pocket sized devices that have an embedded integrated circuit.  They can contain personal identification, authentication, data storage, application processing, etc.  They can be contact based or contactless.
SMS - Short Message Service, GSM services that is used to send and receive short text messages between mobile devices.  NOTE: because they can be spoofed or read by service personel, they are not considered a Possession Factor of MFA by NIST.
Spoofing - a form of subterfuge in which communication is sent from an unknown source disguised as a source known to the receive.
TOTP - Time One Time Password, password generated by physical dongle or application that generates the next password based on an algorithm and the time.
VPN - Virtual Private Network, a private network that allows confidential and secure communication over public networks.


In 2017 we saw a huge uptick in cyber attacks.  Equifax, Yahoo, FedEx, Uber, countless facebook, gmail, and twitter accounts saw data breaches and with worms/viruses like WannaCry, NotPetya, Bad Rabbit the reality is that you can not be too careful.

Passwords can be cracked, hacked, shared, and stolen.  MFA applies a second (or third, forth, etc) level of authentication and therefore adds another layer of security.  The cost of a security breach is greater than the cost of 2FA, and the extra steps involved force you to be mindful of what you are accessing, where you are accessing it, and what the loss would mean.

Further more, if you are a business/entity that is required to use MFA to be PCI DSS, HIPAA, FERPA, or Safe Harbor compliant, then you need to put forth the effort now so you don't get blindsided later.


In my mind, any MFA solution has to have certain pieces:

1) Secure - No bypassing, no spoof-able devices, no shared devices, user tokens/certificates/passwords/etc need to be easily revokeable
2) Failover - The solution needs to be reliable. While being secure, there needs to be more than one way to authenticate the 2nd factor, in case the infrastructure for the 1st method fails.
3) Usability - If there is not end-user buy-in, it won't get used, it will get bypassed, and it will all be for nothing.... period
4) Deployability - Sometimes referenced as Scale-ability.  It should be easy to go from 10 users to 100 users overnight.
5) Maintainability - Once the solution is operational, how often will it need to be maintenance, how many help desk calls are going to be for this solution?

There are LOTS of MFA solutions, but the one I want to walk through today is Duo.  The maintainability, deployability, and usability are there, and it can be made secure.  The problem I had with their module to secure windows desktop login, was that if the machine was not connected to the internet, there was no way to verify the 2nd factor.  It does, however allow for failover to be a smartcard.  This is where the Yubikeys enter in.


Duo is well documented, and its worth trying for free for 10 users.  To set-up Duo Authentication for Windows Logon and RDP, follow their instructions here: https://duo.com/docs/rdp

For my purposes, I have the installer run from a batch file with my pertinent information.  Make sure you allow smart cards, do NOT let it fail open, and since I was securing both local and remote sessions, turn off RDP only.

msiexec.exe /i DuoWindowsLogon64.msi IKEY="" SKEY="" HOST=""

This means that if Duo can't connect to the internet, your users can still log in with the smart card.  If you use YubiKeys you can also enroll them with duo as hardware keys, to provide the OTP.

To secure Duo, I turn off the Authentication Methods that are capable of being spoofed, and I require an encrypted OS on the phone, and bio-metrics to use the app.

Now, when users log in, they get a prompt to authenticate through Duo

But what happens if the internet is disconnected, or the user is on an airplane with a laptop, etc?


This is where having the SmartCard option is key.  If you already enabled smart cards at install, then duo is already set.  To leverage a Yubikey, or any SmartCard, you will will need a PKI setup.  That starts with a Certificate Authority, then you will need your machines to accept smartcards, and finally you need a way to enroll them.

I would recommend reading the following documents if this is the road you want to go down:

Setting Up a Certificate Authority
YubiKey Smart Card Deployment Guide
YubiKey Smart Card Minidriver User Guide
YubiKey PIV Manager User's Guide
Yubico PIV Tool Command Line Guide

The down and dirty goes like this:

A) Create a Certificate Authority on a fresh server install (Found in Microsoft and Yubikey Documentation)

1. Open Server Manager and choose Add roles and features, > Next.
2. > Role-based or feature-based installation > Next.
3. > Select a server from the server pool.
4. Select your new server.
5. Under Server Roles, > Active Directory Certificate Services, > Next.
6. > Add Features, > Next.
7. > Next again.
8. > Certification Authority, > Next.
9. > Install. Allow several minutes for the process to complete.
10. > Configure Active Directory Certificate Services on the destination server, > Next.
11. > Certification Authority, > Next.
12. Choose Enterprise CA, > Next.
13. Choose Root CA, > Next.
14. Create a new private key, > Next.
15. Select the cryptographic provider, hash algorithm, and key length for the private key, > Next.
(Yubico recommends sticking with default values so you don't create a cert that is too big for the smartcards)
16. Common name and Distinguished name will be automatically populated. Confirm the values match the server name and domain name, > Next.
17. Select the validity period for the Certification Authority certificate, > Next.
18. Leave the Database locations to the default values > Next.
19. Verify all settings match the desired values, > Configure.
20. When the process completes, exit the installation wizard.

B) Install the minidriver
1. Download the minidriver: https://www.yubico.com/support/knowledge-base/categories/downloads/
2. Unzip
3. Right click the one that says it has Setup Information and click Install

C) Create an Enrollment Agent so you can enroll certs on behalf of your users.
If you want to allow users to self enroll, follow the documentation in the deployment guide above
1) Open the Certificate Template Manager by running certtmpl.msc
2) Right click on the template named Enrollment Agent

3) In the security tab, ensure that the user/users/groups that will be in charge of enrolling other users has Read and Enroll permissions on the Template.
4) Open the Certificate Authority Manager by running certsrv.msc
5) Right click Certificate Templates, under new, Choose Certificate Template to Issue.

6) Select Enrollment Agent template
7) Open certmgr.msc
8) Under Certificates - Current User expand Certificates
9) Right click, Request a New Certificate
10) Select Active Directory Enrollment Policy, and then select the Enrollment Agent template, and then click Enroll.

D) Create a smart card certificate Template
1) Open the Certificate Template Manager by running certtmpl.msc
2) Right-click Smartcard Logon, and select Duplicate Template.
3) Setup the certificate as follows:

4) Open the Certificate Authority Manager by running certsrv.msc
5) Right click Certificate Templates, under new, Choose Certificate Template to Issue.

6) Select YubiKeySC template
7) Open certmgr.msc
8) Under Certificates - Current User expand Certificates
9) Right click, Under Advanced Options, choose Enroll on Behalf of
10) Select Active Directory Enrollment Policy, and then browse and choose your Enrollment Agent cert, choose the correct user and then click Enroll.
11) The default pin is 123456
12) MAKE SURE THE USER CHANGES THEIR PIN.  It has to be 6-8 characters and can be a combination of letters and numbers.  They can change their pin by pressing CTRL-Alt-DEL and switching to the smart card with the sign in options button.

E) Resetting a SmartCard after they lock their pin
It will happen.  You can use the PIV Manager to reset it, or you can download the PIV tool, and run the following batch file:


echo Yubikey will be reset and 
echo you will erase current Certificate. 
set /P c=Are you sure you want to continue [Y/N]?
if /I "%c%" EQU "Y" goto :yes
if /I "%c%" EQU "N" goto :no
goto :choice

echo Resetting Yubikey...
~path\yubico-piv-tool -a verify-pin -P 000000
~path\yubico-piv-tool -a verify-pin -P 000000
~path\yubico-piv-tool -a verify-pin -P 000000
~path\yubico-piv-tool -a verify-pin -P 000000
~path\yubico-piv-tool -a change-puk -P 000000 -N 000001
~path\yubico-piv-tool -a change-puk -P 000000 -N 000001
~path\yubico-piv-tool -a change-puk -P 000000 -N 000001
~path\yubico-piv-tool -a change-puk -P 000000 -N 000001
~path\yubico-piv-tool -a reset
echo exiting.............

echo Yubikey was not reset. 
echo exiting.............

After the YubiKey is reset, it will have to be re-enrolled, and the old cert will need to be revoked.

Other Considerations

As I said earlier, this is just one of many options.  Start the conversation now because if you are not using any form of MFA or 2SV then ANYTHING you do is more secure than what you have right now.

I am not payed by any of the aforementioned companies, in fact, I pay them for the use of their services and devices.

Make sure you enroll your Yubikeys in Duo as well as enabling the smart card feature.  Then you can use them as a token, and don't have to rely on the app: https://duo.com/docs/yubikey

Finally, do your homework.  The more prepared you are, and the more you experiment with these items in your own environment, the better prepared you will be for the challenges ahead.