OpenVPN Server on Centos7 with Active Directory authentication.

The following will document how to install an OpenVPN server on CentOs7 with LDAP authentication.

When setting up OpenVPN always use an UDP port, they are stateless and do not answer to any requests like TCP does. Also open the port in your firewall and forward it to the IP of the CentoOS machine. Finally you will need to advertise the route and subnet of the VPN service, in this case 10.10.0.0/16, on your local network.

First we need to install and update all the necessary components.

Runt the following commands in bash.

yum update -y
yum install epel-release -y
yum update -y
yum install openvpn wget nano -y
wget -O /tmp/easyrsa https://github.com/OpenVPN/easy-rsa-old/archive/2.3.3.tar.gz
cd /tmp/
tar xfz /tmp/easyrsa
mkdir /etc/openvpn/easy-rsa
mkdir -p /etc/openvpn/ccd
cp -rf easy-rsa-old-2.3.3/easy-rsa/2.0/* /etc/openvpn/easy-rsa
cp /etc/openvpn/easy-rsa/openssl-1.0.0.cnf /etc/openvpn/easy-rsa/openssl.cnf
chown openvpn /etc/openvpn/easy-rsa/
mkdir -p /etc/openvpn/easy-rsa/keys

Then we create a configuration file for our OpenVPN server. Make the neccesary changes.

cat <<'EOF' > /etc/openvpn/server.conf
port 1194
proto udp
dev tun
ca ca.crt
cert centosvpn.crt
key centosvpn.key  # This file should be kept secret
dh dh2048.pem
topology subnet
server 10.10.0.0 255.255.0.0
#ifconfig-pool-persist ipp.txt
push "route 192.168.0.0 255.255.255.0"
#client-config-dir ccd
push "dhcp-option DNS 192.168.0.10"
push "dhcp-option DNS 192.168.0.11"
push "dhcp-option DOMAIN domain.local"
client-to-client
duplicate-cn
keepalive 10 120
tls-auth ta.key 0 # This file is secret
cipher AES-256-GCM
compress lz4-v2
push "compress lz4-v2"
max-clients 100
user nobody
group nobody
persist-key
persist-tun
status openvpn-status.log
log-append openvpn.log
verb 5
explicit-exit-notify 1
#username-as-common-name
#plugin /usr/lib64/openvpn/plugin/lib/openvpn-auth-ldap.so /etc/openvpn/auth.activedirectory.conf
EOF

The below is the IP subnet for VPN clients. This is the pool of IPs that will be assigned to clients when they connect to the open vpn server.

server 10.10.0.0 255.255.0.0"

The following advertises the network to VPN clients, this is the network you want access to. Change this to your network subnet that your server sits in.

push "route 192.168.0.0 255.255.255.0"

These lines advertise the DNS server and the domain name to VPN clients. This will be used for name resolution for clients. This allows the clients to search your domain name and connect to machines without having to use the FQDN.

push "dhcp-option DNS 192.168.0.10"
push "dhcp-option DNS 192.168.0.11"
push "dhcp-option DOMAIN domain.local"

Next we make some changes to the rsa variables before we build the server certificates.

nano /etc/openvpn/easy-rsa/vars
# change the following
export KEY_COUNTRY="CA"
export KEY_PROVINCE="AB"
export KEY_CITY="Calgary"
export KEY_ORG="NerdDrvel"
export KEY_EMAIL="admin@nerdrivel.com"
export KEY_EMAIL=admin@nerddrivel.com
export KEY_CN=domain.local
#export KEY_NAME=centosvpn
#export KEY_OU=IT

Once you made the above changes run the following commands in bash.

cd /etc/openvpn/easy-rsa
source /etc/openvpn/easy-rsa/vars
./clean-all
./build-ca
./build-key-server centosvpn 
./build-dh
cd /etc/openvpn/easy-rsa/keys
cp dh2048.pem ca.crt centosvpn.crt centosvpn.key /etc/openvpn
cd /etc/openvpn/
mkdir ccd

Note the last command “mkdir ccd” is not necessary, but it’s good to have it there just in case. This is the client configuration directory. Uncomment this following line in your server.conf to enable it.

#client-config-dir ccd

Next build your super secret ta.key file.

openvpn --genkey --secret ta.key

Then create your client key and certificates.

cd /etc/openvpn/easy-rsa/
./build-key client

You will see the something like the following.

Using configuration from /etc/openvpn/easy-rsa/openssl.cnf
Check that the request matches the signature
Signature ok
The Subject’s Distinguished Name is as follows
countryName :PRINTABLE:’CA’
stateOrProvinceName :PRINTABLE:’AB’
localityName :PRINTABLE:’Calgary’
organizationName :PRINTABLE:’NerdDrivel’
organizationalUnitName:PRINTABLE:’DevOps’
commonName :PRINTABLE:’domain.local’
name :PRINTABLE:’centosvpn’
emailAddress :IA5STRING:’dspedzia@flyht.com’
Certificate is to be certified until Feb 10 01:05:22 2030 GMT (3650 days)
Sign the certificate? [y/n]:y

1 out of 1 certificate requests certified, commit? [y/n]y
Write out database with 1 new entries
Data Base Updated

Next we will stop and disable the firewall.

systemctl stop firewalld.service
systemctl disable firewalld.service

Next change the ownership and permissions on your VPN configuration file. Lock it down so only the service account can access it.

chown root:openvpn /etc/openvpn/server.conf
chmod 750 /etc/openvpn/server.conf

Then we will enable Nat forwarding and restart the network.

echo "net.ipv4.ip_forward = 1" >> /etc/sysctl.conf
systemctl restart network

Then disable selinux, it will not allow you to connect if it is still enabled.

nano /etc/selinux/config

Change the following lines in the file. Changes will not take affect until you reboot the machine.

SELINUX=disabled
SELINUXTYPE=minimum

Next copy the sample unit file to the systemd folder.

cp /usr/lib/systemd/system/openvpn-server@.service /etc/systemd/system/

Edit the unit file.

nano /etc/systemd/system/openvpn-server@.service

Change the following.

WorkingDirectory=/etc/openvpn

Then reload the systemctl dawmon and enable the VPN service.

systemctl daemon-reload
systemctl  enable openvpn-server@server.service

Note that the tailing service name after the @ above must reflect the name of the of your cont file. So /etc/openvpn/server.conf will be openvpn-server@server.service. If you named your conf file /etc/openvpn/myvpnserver.conf your service name should be openvpn-server@myvpnserver.service.

Finally reboot your machine.

shutdown -r now

Check the status of your VPN service.

systemctl status openvpn-server@server.service

Make sure your service is staying up and running without issues.

Make sure you test your VPN and can connect only using the certificate. As next we will enable LDAP authentication on the VPN server.

LDAP Auth Installation

Before enabling the LDAP authentication method you will need a VPN user account in your active directory, and a VPN group.

The user will be used to bind to AD and search for users, while the group will be used to grant users permission to connect to VPN. When you add a user to the group they will be allowed to connect to the OpenVPN server.

In my case I have an LDAP Read Only user to bind to LDAP/AD

First you need to search the yum repo for an up to date ldap open vpn plugin.

yum search openVPN | grep ldap

Then install the ldap authentication plugin for Open VPN with the following.

yum install openvpn-auth-ldap.x86_64

Next create and edit your ldap authentication file.

touch > /etc/openvpn/auth/auth.activedirectory.conf
nano /etc/openvpn/auth/auth.activedirectory.conf

Add the following to your auth.*.conf file.

<LDAP>
    # LDAP server URL
    URL ldap://192.168.0.10:389
 
    # Bind DN (If your LDAP server doesn't support anonymous binds)
    BindDN "CN=LDAP Read Only,OU=Users,DC=domain,DC=local"
 
    # Bind Password
    Password "somepassword"
 
    # Network timeout (in seconds)
    Timeout 15
 
    # Enable Start TLS
    TLSEnable no
 
    # Follow LDAP Referrals (anonymously)
    FollowReferrals no
 
    # TLS CA Certificate File
    TLSCACertFile /usr/local/etc/ssl/ca.pem
 
    # TLS CA Certificate Directory
    TLSCACertDir /etc/ssl/certs
 
    # Client Certificate and key
    # If TLS client authentication is required
    TLSCertFile /usr/local/etc/ssl/client-cert.pem
    TLSKeyFile /usr/local/etc/ssl/client-key.pem
</LDAP>
 
<Authorization>
    # Base DN
    BaseDN "DC=domain,DC=local"
 
    # User Search Filter
    #SearchFilter "(&(uid=%u)(accountStatus=active))"
    SearchFilter "(&(sAMAccountName=%u))"
 
    # Require Group Membership
    RequireGroup true
 
    <Group>
        BaseDN "OU=Security,OU=Groups,DC=domain,DC=local"
        SearchFilter "(|(cn=CentOS VPN))"
        MemberAttribute "member"
    </Group>
</Authorization>

The LDAP heading references the URL option this is the address of the AD server on the domain, IP is preferred.

The BindDN specifically cn=LDAP Read Only is the user account that is used for domain binding to resolve users that need to be validated against the domain.

This user was created specifically just for this purpose and is not part of the VPN group. Under the Authorization XML heading BaseDn is where the VPN looks for users that will be authenticated via OpenVPN.

SearchFilter in this case looks for sAMAccountName, which is the domain logon user id.

RequireGroup set to true means that VPN users need to be part of a specific group to be granted permissions to connect to the VPN.

The Group XML heading references BaseDN, this is where the VPN will look for the Group members that are authorized to access the VPN.

The SearchFIlter in the Group heading is the group name the VPN will look for authorized users.

Finally uncomment the following lines in your /etc/openvpn/server.conf file.

username-as-common-name
plugin /usr/lib64/openvpn/plugin/lib/openvpn-auth-ldap.so /etc/openvpn/auth/auth.activedirectory.conf

Then restart the VPN service

systemctl restart openvpn-server@server.service

Lastly you will need a OVPN file for your clients to use.

The following is a Windows OVPN file format.

Note that auth-user-pass is only used with LDAP suthentication, if you want to test the VPN server just with the certificate comment that out.

client
dev tun
cipher AES-256-GCM
compress lz4-v2
tls-client
tls-auth ta.key 1
remote-cert-tls server
auth-user-pass
keepalive 10 120
proto udp
remote 1.1.1.1 udp
topology subnet
pull
<ca>
-----BEGIN CERTIFICATE-----
ca.crt contents
-----END CERTIFICATE-----
</ca>
<cert>
-----BEGIN CERTIFICATE-----
client.crt contents
-----END CERTIFICATE-----
</cert>
<key>
-----BEGIN PRIVATE KEY-----
client.key contents
-----END PRIVATE KEY-----
</key>
<tls-auth>
-----BEGIN OpenVPN Static key V1-----
ta.key contents
-----END OpenVPN Static key V1-----
</tls-auth>

remote 1.1.1.1 is your eternal IP address.

2 thoughts on “OpenVPN Server on Centos7 with Active Directory authentication.

Add yours

    1. Not any time soon.
      There shouldn’t be much difference between 7 and 9. Installation might be a bit different and use `dnf` instead of `yum`, however the configuration should remain fairly similar.

Leave a comment

This site uses Akismet to reduce spam. Learn how your comment data is processed.

Create a free website or blog at WordPress.com.

Up ↑