Updated: Added how to enable the pam plugin for openvpn
Recently I have been digging deep into openstack and came across a personal need to gain access to private network configured within openstack from my external machine. Rather than giving each machine a floating ip. Below is the simple network topology we will setup.
Note: We want the vpn users to exist on 192.168.100.0/24
This guide is going to assume the following.
- You already have a openstack cloud provider / personal lab.
- You have a public and private network with corresponding subnets. Note: The subnet can be using dhcp and have a gateway set it won’t interfere.
- You have already create instances on your private network and a instance on your public network with a public ip associated with it to act as the firewall/vpn provider
- You are using ubuntu for your firewall/vpn distribution
Step 1
First thing that must be done is installing the required packages.
ubuntu@firewall:~$ sudo apt-get install openvpn easy-rsa
Step 2
After the packages are installed we will now need to generate our certificates. The first certificate we are going to generate is our RootCa. If you already have a root ca generated you can utilize your own.
We create a easy-rsa folder in our openvpn folder and copy over the scripts.
ubuntu@firewall:~$ sudo mkdir /etc/openvpn/easy-rsa
ubuntu@firewall:~$ sudo cp -r /usr/share/easy-rsa/* /etc/openvpn/easy-rsa
Now we are going to modify the file titled “vars” in /etc/openvpn/easy-rsa/vars
ubuntu@firewall:~$ sudo nano /etc/openvpn/easy-rsa/vars
In this file you will want to modify the following variables. Within the file.
KEY_COUNTRY = Country of business code ex."US"
KEY_PROVINCE = Province / State of issuer ex. "Texas"
KEY_CITY = City of issuer ex. "Dallas"
KEY_ORG = Organization the certificate belongs to. ex."EvilCorp"
KEY_EMAIL = Administration email for certificate. ex. "admin@evilcorp.com"
KEY_CN = The common name for the cert ex. "XYZ Root CA"
KEY_NAME = The name of the certificate ex."XYZ ROOT CA"
KEY_OU = Organization Unity ex."Administration"
KEY_ALTNAMES = Alternative Name for the certificate "XYZ Root CAFORREAL"
Now that we have configured the variables we need to generate the certificate. For ease of use we will also drop into a root terminal session. When running the build-ca command you will be prompted for information.
ubuntu@firewall:~$ sudo bash
root@firewall:~# cd /etc/openvpn/easy-rsa
root@firewall:/etc/openvpn/easy-rsa# source vars
root@firewall:/etc/openvpn/easy-rsa# ./clean-all
root@firewall:/etc/openvpn/easy-rsa# ./build-ca
You should now have to files in the keys directory ca.crt and ca.key.
Next we need to generate our vpn server’s certificates. You will be prompted for input.
Note: You can change “MyVpnServerCert” to whatever name you want Note: Make sure when it asks if you want to sign the certificate that you sign it or else there will be problems
root@firewall:/etc/openvpn/easy-rsa# ./build-key-server MyVpnServerCert
Now that we have that configured we need to generate our Diffie-Hellman parameters file.
root@firewall:/etc/openvpn/easy-rsa# ./build-dh
Finally the last thing we need to generate a shared secret file to help prevent against DDOS and other Nasty things.
root@firewall:/etc/openvpn/easy-rsa# openvpn --genkey --secret ta.key
Now we copy these files we have generated to the /etc/openvpn/certs folder.
root@firewall:/etc/openvpn/easy-rsa# mkdir /etc/openvpn/certs
root@firewall:/etc/openvpn/easy-rsa/keys# cd keys
root@firewall:/etc/openvpn/easy-rsa/keys# cp ca.crt /etc/openvpn/certs/
root@firewall:/etc/openvpn/easy-rsa/keys# cp MyVpnServerCert.crt /etc/openvpn/certs/
root@firewall:/etc/openvpn/easy-rsa/keys# cp MyVpnServerCert.key /etc/openvpn/certs/
root@firewall:/etc/openvpn/easy-rsa/keys# cp dh2048.pem /etc/openvpn/certs/
root@firewall:/etc/openvpn/easy-rsa/keys# cp ta.key /etc/openvpn/certs/
root@firewall:/etc/openvpn/easy-rsa/keys# cd ../
Step 3
Now we need to configure the openvpn server itself. First we will copy the example configuration file for openvpn to our openvpn folder.
root@firewall:/etc/openvpn/easy-rsa# cd /etc/openvpn
root@firewall:/etc/openvpn# cp /usr/share/doc/openvpn/examples/sample-config-files/server.conf.gz .
root@firewall:/etc/openvpn# gunzip -d server.conf.gz
A file named “server.conf” should be in /etc/openvpn. There is quite a few changes we must make to this.
root@firewall:/etc/openvpn# nano server.conf
*First we enable the openvpn pam plugin
At the top of the file add the following line
plugin /usr/lib/openvpn/openvpn-plugin-auth-pam.so openvpn
Next we have to set the correct protocol
By default it is set to udp which is fine for most networks. However certain providers have a problem with udp tunneled traffic dropping. Because of this we set it to tcp.
Find the line that states the following.
proto udp
Change it to the following
proto tcp
Next we have to set the correct certificate
Find the following two lines.
ca ca.crt
cert server.crt
key server.key
Change them to the following
ca certs/ca.crt
cert certs/MyVpnServerCert.crt
key certs/MyVpnServerCert.key
Now we need to set the correct Diffie-Hellman parameters.
Find the line that states
dh dh1024.pem
Change it to the following
dh dh2048.pem
Next we need to configure the vpn client address that is issues out.
Locate the following line
server 10.8.0.0 255.255.255.0
Replace it with the following
server 192.168.100.0 255.255.255.0
Next we need to configure our “route” to the 192.168.1.0/24 network.
Find the following line
;push "route 192.168.20.0 255.255.255.0"
Under that line add the following line.
push "route 192.168.1.0 255.255.255.0"
Next we enable the duplicate cn
This allows us to issue one client cert that is reused by others. We do this so we only need to hand out one set of client certificates.
Find the following line
;duplicate-cn
Change it to the following
duplicate-cn
Next just need to enable the shared secret
Find the following line.
;tls-auth ta.key 0
Change it to the following
tls-auth certs/ta.key 0
Finally we just enable logging to help with our sanity
Find the following line
;log openvpn.log
Change it to the following
log openvpn.log
Now that the openvpn server configuration is done we just need to start it.
service openvpn start
Step 5
We need to create the pam service file and user group for our openvpn users.
root@firewall:/etc/openvpn# touch /etc/pam.d/openvpn
root@firewall:/etc/openvpn# nano /etc/pam.d/openvpn
Now we add the following two lines inside our openvpn service file
auth required pam_unix.so shadow nodelay
account required pam_unix.so
Close the file then run the following command
root@firewall:/etc/openvpn#groupadd openvpn
Step 6
To finish the server configuration we need to allow for our vpn server to act as a router.
To enable the functionality immediately we need to do the following.
Run the following command to enable ip_forwarding
root@firewall:/etc/openvpn# echo "1" > /proc/sys/net/ipv4/ip_forward
Now the iptables to allow our packets to be forward to the correct destination.
Note: the eth1 interface is important in the POSTROUTING if you pick the wrong interface you will not be able to communicate with the private network
root@firewall:/etc/openvpn# iptables -A FORWARD -m state --state RELATED,ESTABLISHED -j ACCEPT
root@firewall:/etc/openvpn# iptables -A FORWARD -s 192.168.100.0/24 -j ACCEPT
root@firewall:/etc/openvpn# iptables -A FORWARD -j REJECT
root@firewall:/etc/openvpn# iptables -t nat -A POSTROUTING -s 192.168.100.0/24 -o eth1 -j MASQUERADE
Now we just need to make it permanent.
First to ensure that ip forwarding is always enabled we need to modify the sysctl configuration.
root@firewall:/etc/openvpn# nano /etc/sysctl.conf
Find the following line
#net.ipv4.ip_forward=1
Change it to the following
net.ipv4.ip_forward=1
Finally we persist the iptables data.
We achieve this by doing it the lazy way. By modifying our /etc/rc.local file.
root@firewall:/etc/openvpn# nano /etc/rc.local
Find the following line.
exit 0
Before that line add the following
iptables -A FORWARD -m state --state RELATED,ESTABLISHED -j ACCEPT
iptables -A FORWARD -s 192.168.100.0/24 -j ACCEPT
iptables -A FORWARD -j REJECT
iptables -t nat -A POSTROUTING -s 192.168.100.0/24 -o eth1 -j MASQUERADE
Save the file and thats it server is configured and will survive a reboot.
Step 7
We will now create the certificate that we will hand our clients.
Note: You can change ClientCert to whatever you want. Note: Make sure to sign the certificate.
ubuntu@firewall:~$ sudo bash
root@firewall:~# cd /etc/openvpn/easy-rsa
root@firewall:/etc/openvpn/easy-rsa# source vars
root@firewall:/etc/openvpn/easy-rsa# ./build-key ClientCert
root@firewall:/etc/openvpn/easy-rsa# exit
Now we copy them to a folder in our home directory
ubuntu@firewall:~$ mkdir ~/ClientConf
ubuntu@firewall:~$ cd /etc/openvpn/easy-rsa/keys
ubuntu@firewall:~$ sudo cp ca.crt ~/ClientConf
ubuntu@firewall:~$ sudo cp ClientCert.crt ~/ClientConf
ubuntu@firewall:~$ sudo cp ClientCert.key ~/ClientConf
ubuntu@firewall:~$ sudo cp ta.key ~/ClientConf
Now we need to copy the sample client configuration file and modify it.
ubuntu@firewall:~$ cd ~/ClientConf
ubuntu@firewall:~$ cp /usr/share/doc/openvpn/examples/sample-config-files/client.conf .
ubuntu@firewall:~$ nano client.conf
First we set the correct protocol
Find the following line
proto udp
Change it to the following
proto tcp
Next we have to set the correct remote address
Find the following
remote my-server-1 1194
Change it to the following
remote YOUR-SERVER-PUBLIC-IP 1194
After that we have to set the correct certificates
Find the following lines
ca ca.cert
cert client.crt
key client.key
Change them to the following
ca ca.cert
cert TestClient.crt
key TestClient.key
Next we enable the shared secret
Find the following line
;tls-auth ta.key 1
Change it to the following
tls-auth ta.key 1
Finally we enable the pam module
Add the following line to the bottom of the config
auth-user-pass
All thats left from here is to create our openvpn user
Note: We do this for each unique user we want to have access to the vpn
Note: We set their shell to /bin/false so they do not have ssh access
Note: You can set TestUser to whatever you want
ubuntu@firewall:~$ sudo bash
root@firewall:~# useradd -g "openvpn" -s /bin/false TestUser
root@firewall:~# passwd TestUser
That’s it if everything works out well the openvpn server will be configured. Permissions will have to be changed on the files in the ~/ClientConf folder.
ubuntu@firewall:~$ sudo chown -R user:user ~/ClientConf
ubuntu@firewall:~$ tar -czf ClientConf.tar.gz ~/ClientConf
Now hand your client the ClientConf.tar.gz and the username/password you create for them.