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-rsaStep 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-rsaNow we are going to modify the file titled “vars” in /etc/openvpn/easy-rsa/vars
ubuntu@firewall:~$ sudo nano /etc/openvpn/easy-rsa/varsIn 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-caYou 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 MyVpnServerCertNow that we have that configured we need to generate our Diffie-Hellman parameters file.
root@firewall:/etc/openvpn/easy-rsa# ./build-dhFinally 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.keyNow 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.gzA 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 openvpnNext 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 udpChange it to the following
proto tcpNext we have to set the correct certificate
Find the following two lines.
ca ca.crt
cert server.crt
key server.keyChange them to the following
ca certs/ca.crt
cert certs/MyVpnServerCert.crt
key certs/MyVpnServerCert.keyNow we need to set the correct Diffie-Hellman parameters.
Find the line that states
dh dh1024.pemChange it to the following
dh dh2048.pemNext we need to configure the vpn client address that is issues out.
Locate the following line
server 10.8.0.0 255.255.255.0Replace it with the following
server 192.168.100.0 255.255.255.0Next 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-cnChange it to the following
duplicate-cnNext just need to enable the shared secret
Find the following line.
;tls-auth ta.key 0Change it to the following
tls-auth certs/ta.key 0Finally we just enable logging to help with our sanity
Find the following line
;log openvpn.logChange it to the following
log openvpn.logNow that the openvpn server configuration is done we just need to start it.
service openvpn startStep 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/openvpnNow we add the following two lines inside our openvpn service file
auth required pam_unix.so shadow nodelay
account required pam_unix.soClose the file then run the following command
root@firewall:/etc/openvpn#groupadd openvpnStep 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_forwardNow 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 MASQUERADENow 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.confFind the following line
#net.ipv4.ip_forward=1Change it to the following
net.ipv4.ip_forward=1Finally 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.localFind the following line.
exit 0Before 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 MASQUERADESave 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# exitNow 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 ~/ClientConfNow 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.confFirst we set the correct protocol
Find the following line
proto udpChange it to the following
proto tcpNext we have to set the correct remote address
Find the following
remote my-server-1 1194Change it to the following
remote YOUR-SERVER-PUBLIC-IP 1194After that we have to set the correct certificates
Find the following lines
ca ca.cert
cert client.crt
key client.keyChange them to the following
ca ca.cert
cert TestClient.crt
key TestClient.keyNext we enable the shared secret
Find the following line
;tls-auth ta.key 1Change it to the following
tls-auth ta.key 1Finally we enable the pam module
Add the following line to the bottom of the config
auth-user-passAll 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 TestUserThat’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 ~/ClientConfNow hand your client the ClientConf.tar.gz and the username/password you create for them.