OpenVPN DC

From Indie IT Wiki

This is still a work in progress

Introduction

OpenVPN is a secure VPN technology with clients available for Windows, MacOS(OSX), Linux, iOS and Android.

A large proportion of office setups use a Windows domain for authentication and management with either a Windows or Samba4 domain controller. To keep things simple for users it is often required to use the same credentials to login to the domain and the VPN.

There are a few design decisions to be discussed first...

1/ Routed or Bridged
If you're dealing with purely IP based protocols then the preference is going to be for routed. If you bridge your connection then you're going to get extra traffic such as ARP, Bonjour etc potentially travelling over your VPN link. Given that VPN's are generally lower bandwidth connections this is undesirable. Routed introduces it's own issues but these are easy to deal with.

2/ Where to install the OpenVPN server
Generally, in these days of virtualisation, the preference is overwhelmingly for a separate, dedicated VM instance. If your firewall can host an OpenVPN server it's worth considering running it there, mainly because it reduces routing problems (the firewall is usually the default gateway for most networks).

3/Authentication
There are a number of ways to authenticate an OpenVPN session, either certificates, username&password or a combination of both. Here we'll use both.


This setup is based on an Ubuntu 16.04.03 LTS server. It'll use standard repo packages, so no compilation or messing with PPA or other addon repos. We can argue the pros & cons of this approach somewhere else.

So, assuming you've got a nice , freshly installed and updated Ubuntu server, with ssh installed...

apt-get install openvpn easy-rsa openvpn-auth-ldap 

This installs the openvpn server, the plugin ldap authentication module and a set of scripts making certificate manage simple.

cd /etc/openvpn/
make-cadir openvpn-ca
cd openvpn-ca/
vi vars
source ./vars
./build-ca
./build-dh
./build-key-server server
./build-key dummy
./revoke-full dummy
cp keys/crl.pem /etc/openvpn
openvpn --genkey --secret keys/ta.key

Ok, so what's going on here.
We need to create a certificate authority (CA) to manage the certificates we're going to generate for the server and the various clients. Only a client with a properly signed certificate will be allowed to connect, before we even get to authenticating the user. We then create the server certificate.
The 'dummy' certificate is used to create the initial Certificate Revocation List (CRL). If a client machine is lost or stolen we can block it by adding it to the CRL
The ta.key is just another layer of authentication - effectively a pre-shared password.

You'll need a server config file. This is a reasonable starting point. Make sure to adjust the dns & domain settings for your network.

port 1194
dev tun
proto udp
ca /etc/openvpn/openvpn-ca/keys/ca.crt
cert /etc/openvpn/openvpn-ca/keys/server.crt
key /etc/openvpn/openvpn-ca/keys/server.key  # This file should be kept secret
dh /etc/openvpn/openvpn-ca/keys/dh2048.pem
tls-auth /etc/openvpn/openvpn-ca/keys/ta.key 0 # This file is secret
key-direction 0
plugin /usr/lib/openvpn/openvpn-auth-ldap.so "/etc/openvpn/auth/ldap.conf"
user nobody
group nogroup
server 10.8.0.0 255.255.255.0
ifconfig-pool-persist ipp.txt
keepalive 10 60
cipher AES-256-CBC
auth SHA512
comp-lzo
status      status.log
log         openvpn.log
log-append  openvpn.log
push "dhcp-option DNS 192.168.12.5"
push "redirect-gateway def1"
push "dhcp-option DOMAIN myinternaldomain.com"

The next thing you'll need is a config file for the LDAP authentication. Here we're authenticating against a Domain Controller that allows non-SSL/TLS connections. We'll keep it simple for the moment - connecting to a DC with TLS will be the subject of our next exciting episode. You'll need to tweak the config file below with your domain settings. It's also expecting a user account (vpnconnect) to aloow us to bind to and query LDAP, and a group (vpn-users) in which to place users who are allowed to use the VPN.

## LDAP auth config file against a Samba DC with domain DCDOM.HOME
<LDAP>
# LDAP server URL
URL ldap://192.168.12.5:389
# Bind DN (If your LDAP server doesn't support anonymous binds)
BindDN CN=vpnconnect,CN=Users,DC=DCDOM,DC=HOME
# BindDN admin@test.com
# Bind Password
Password whatever
# Network timeout (in seconds)
Timeout 15
# Enable Start TLS
TLSEnable no
# Follow LDAP Referrals (anonymously)
FollowReferrals yes
</LDAP>
<Authorization>
# Base DN
BaseDN "OU=Staff,DC=DCDOM,DC=HOME"
# User Search Filter
#SearchFilter "(&(uid=%u)(accountStatus=active))"
#SearchFilter "(&(sAMAccountName=%u)(msNPAllowDialin=TRUE))"
SearchFilter "(&(sAMAccountName=%u))"
RequireGroup true
<Group>
  BaseDN "OU=Groups,DC=DCDOM,DC=HOME"
  SearchFilter "(cn=vpn-users)"
  MemberAttribute "member"
</Group>
</Authorization>

The next thing we're going to need is a client config file. These days, most OpenVPN implementations support a single unified config file, rather than the older config file + separate certs. Essentially the unified OVPN file is just a concatenation of the old config file and the certs with a few delimiters. It can be generated my hand, but this useful script *h/t to Eric Jodoin and Eric Maasdorp) https://serverfault.com/questions/483941/generate-an-openvpn-profile-for-client-user-to-import makes life easier.

You'll need a template file, which looks something like this

client
dev tun
proto udp
remote server.wherever.com 1194
resolv-retry infinite
nobind
persist-key
persist-tun
;mute-replay-warnings
remote-cert-tls server
key-direction 1
auth SHA512
cipher AES-256-CBC
comp-lzo
verb 3
# Silence repeating messages
;mute 20