Build your own combined OpenVPN/WiKID server for a VPN with built-in two-factor authentication using Packer.
In past tutorials, we have added one-time passwords to OpenVPN and created a WiKID server using Packer. In this tutorial we create a combined OpenVPN/WiKID server using Packer. Packer allows us to create VMware, VirtualBox, EC2, GCE, Docker, etc images using code. Note that combining your two-factor authentication server and VPN server on one box may or may not be the best solution for you. We typically like separation of duties for security and flexibility. However, if you need something fast - the PCI auditors arrive Monday - or you are in a repressive state and just need a secure outbound connection for a short period of time. And you still have some flexibility. You can add more services to the WiKID server. You can disable the OpenVPN server and instead switch to a different VPN.
Build the Combined Server
First, download and install Packer.
Checkout our Packer scripts from GitHub. The scripts consist of a main JSON file that tells Packer what do it, an http directory with Anaconda build scripts, a files directory that gets uploaded to the image and provisioners that run after the image is built. Basically Packer starts with some source such as an ISO or AMI, builds the server based on Anaconda (at least for CentOS), uploads any files and then runs the provisioners. Packer is primarily geared toward creating idempotent servers. In our case, we are using it to execute the commands, allowing us to run one command instead of about 50 (just for the provisioning).
Before building, you need to edit a few files. First, edit /files/vars. This is the standard vars file for creating the OpenVPN certs. Just enter your values for the cert fields.
# These are the default values for fields # which will be placed in the certificate. # Don't leave any of these fields blank. export KEY_COUNTRY="US" export KEY_PROVINCE="GA" export KEY_CITY="Atlanta" export KEY_ORG="WiKID Systems Inc" export KEY_EMAIL="firstname.lastname@example.org" export KEY_OU="WiKID Systems, Inc"
Next, you need to edit the shared secret in /files/server. This file will tell PAM which RADIUS server to use. In this case, it is talking straight to the WiKID server. The shared secret is used to encode the radius traffic. Since WiKID is running on the same server, keep the localhost as the server:
# server[:port] shared_secret timeout (s) 127.0.0.1 secret 3
You will need this shared secret later.
Take a look in centos-6-x86-64.json. You can run it as is, but you might like to edit a few things. You should confirm the source_ami (the listed ami is in the US-East) or switch it to one of your preferred CentOS AMIs. If you are building on VMware or VirtualBox, you will want to change the iso_url to the location of the CentOS ISO on your hard drive and update the MD5Sum. You may want to edit the names and descriptions. You may also want to change the EC2 region. Most importantly, you can change the ssh_password which is the root password.
Once you are happy with the JSON file, you can verify it with Packer:
$packer_location/packer verify centos-6-x86-64.json
If that works, build it. You can specify the target platform on the command line:
$packer_location/packer build --only=virtualbox-iso centos-6-x86-64.json
If you build for EC2, put the required credentials in the command line:
$packer_location/packer build -var 'aws_access_key=XXXXXXXXXXXXXXXXXXXX' -var 'aws_secret_key=XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX' --only=amazon-ebs centos66.json
If you watch the commands run, you will see a complete OpenVPN server being built complete with fresh certificates!
Configure the WiKID two-factor authentication server
Once it is created, you will need to launch the AMI or import the virtual machine. Start VirtBox and select File, Import Appliance. Point it to output-virtualbox-iso directory created by the build command and open the OVF file. Make any changes you may want to the virtual machine (eg memory or network) and start the server.
Login using root/wikid or whatever you may have set the root password as in the JSON file. We will be configuring the WiKID server using the quick-start configuration option. Copy the file to the current directory:
cp /opt/WiKID/conf/sample-quick-setup.properties wikid.conf
Edit wikid.conf per those instructions. Use the external IP address of your server or EC2 instance zero-padded as the domaincode. So, 126.96.36.199 becomes 054163165073. For the RADIUS host use the localhost and the shared secret you created in /files/server above:
information for setting up a RADIUS host radiushostip=127.0.0.1 radiushostsecret=secret ; *NOTE*: YOU SHOULD REMOVE THIS SETTING AFTER CONFIGURATION FOR SECURITY
If you are on a VM, you can configure the network by running:
On EC2, you can just configure the WiKID server:
wikidctl quick-setup configfile=wikid.conf
You will see configuration information scroll past. Start the WiKID server:
You will be prompted for the passphrase you set in wikid.conf. Browse to the WIKIDAdmin interface at https://yourserver.com/WiKIDAdmin/ and you should see your domain created, your radius network client configured and all the required certs completed.
Before leaving the server, you should add your username as an account on the server with 'useradd $username'. There is no need to add a password.
Register the WiKID Software token
Start the token and select "Add a Domain". Enter the domain identifier code you set in wikid.conf and you should be double-prompted to set your PIN. Do so and you will get back a registration code. Go to the WiKIDAdmin web UI and click on the Users Tab, then Manually Validate a User. Click on your registration code and enter your username. This process associates the token (and the keys that were exchanged) with the user.
Setup the VPN client
Download the ca.crt to the client:
scp -i ~/Downloads/wikid.pem email@example.com:/etc/openvpn/ca.crt .
Edit the client.conf OpenVPN file. Set the remote server as your combined WiKID/OpenVPN server:
# The hostname/IP and port of the server. # You can have multiple remote entries # to load balance between the servers. remote yourserver.com 1194
Comment out the lines for the cert and key. Leaving only the CA. Since we are using WiKID to authenticate and identify the user, they are not needed.
ca ca.crt #cert client.crt #key client.key
At the bottom of the file, tell the client to prompt for a password:
Now start the OpenVPN client:
sudo openvpn client.conf
You will be prompted for a username and a password. Request a passcode from your WiKID token and enter it into the password field. You should be granted accesss.