Thursday, September 2, 2010

CentOS - point-to-point VPN tunneling with OpenVPN

SkyHi @ Thursday, September 02, 2010
This tutorial will walk you through setting up a point-to-point VPN tunnel between your Cloud Servers. This type of connection will use the internal network interface (eth1) so you will not be charged for bandwidth. This walk-through is designed for CentOS.
The following items are assumed with this tutorial:
  • You have setup your server according to the setup guide
  • This server is brand new with no software installed
  • You are logged in as a non-privileged user with sudo privileges


Contents

[hide]

The Plan

Our initial design will consist of two different servers -- we will call them ServerA and ServerB. The IP addresses for each server are defined below:
ServerA ServerB
10.100.1.20 10.100.1.50
(Note that we are using the internal interface only)

The plan is to create a point-to-point VPN between ServerA and ServerB so they can communicate on their own private network. The following processes will walk you through creating three different types of VPN connections:
  • Simple VPN (no security or encryption)
  • Static Key VPN (simply 128-bit security)
  • Full TLS VPN (revolving-key encryption)
We will build each type of VPN tunnel and then build on the one previously. For instance, if you would like a full TLS-enabled VPN please run through all of the examples shown below.

Simple VPN

The first VPN link that we will create is a simple point-to-point link with no encryption or security. This will literally form a virtual link between two servers for communication. This is the simplest form of VPN communication and is generally not recommended. The process will be the same for each server with server specific changes being noted.

Update Your System

First we need to make sure that our system is up to date. Run the following command to update your system:
# sudo yum -u update

Add the DAG repository

By default OpenVPN does not come as a pre-compiled binary; however, there are places where people have pre-compiled it for us. We will use the DAG repository which houses one of those pre-compiled versions but first we need to tell our server where it is located.
Let's add the repository by adding an entry into YUM, the default package manager for CentOS.
# sudo nano -w /etc/yum.repos.d/dag.repo
You will need to add the following lines into this file.
[dag]
name=Dag RPM Repository for Red Hat Enterprise Linux
baseurl=http://apt.sw.be/redhat/el$releasever/en/$basearch/dag
gpgcheck=1
enabled=1
Once you have pasted the lines press CTRL-X on your keyboard to exit the application. You will be asked if you would like to save the file, simply press Y and then press Enter to accept the default file name. The program will now exit.
Next we need to add the GPG key that signs each of the packages in the DAG repository but first we need to download it.
# wget http://dag.wieers.com/packages/RPM-GPG-KEY.dag.txt
In this file there are a few lines that need to be removed before we can import it otherwise an error will result. Type the following line to open the editor.
# nano RPM-GPG-KEY.dag.txt
In this screen you will see several lines and a bunch of random letters and numbers. Delete the following lines:
The following public key can be used to verify RPM packages
downloaded from  http://dag.wieers.com/apt/  using 'rpm -K'
if you have the GNU GPG package.
Questions about this key should be sent to:
Dag Wieers 
Once you have those lines deleted simply press CTRL-X to exit the program. It will prompt you to save the file, press Y and Enter.
Now we need to import the GPG key that we just modified otherwise the installation will fail. Type the following command:
# sudo rpm --import RPM-GPG-KEY.dag.txt

Install OpenVPN

We are now ready to install OpenVPN on our server. Type the following command to install OpenVPN:
# sudo yum -y install openvpn

Remove DAG repository

Now that we have added our software we need to remove the DAG repository to protect the integrity of your updates. Run the following command below:
# sudo rm /etc/yum.repos.d/dag.repo

Create Client Server

At this point please proceed with performing the above actions on your second server. In our example we will perform the above actions on ServerB.

Create VPN Link

Now we are ready to create our VPN link between ServerA and ServerB.

ServerA Commands

To create the link on ServerA run the following command:
# sudo /usr/sbin/openvpn --remote 10.100.1.50 --dev tun1 --ifconfig 172.16.1.1 172.16.1.2
This command will create a VPN link with ServerB (10.100.1.50). It will also prepare a virtual interface called tun1 and will assign the IP 172.16.1.1 to it. The associated routes for this will be created as well.

ServerB Commands

To create the link on ServerB run the following command:
# sudo /usr/sbin/openvpn --remote 10.100.1.20 --dev tun1 --ifconfig 172.16.1.2 172.16.1.1
This command will create a VPN link with ServerA (10.100.1.20). It will also prepare a virtual interface called tun1 and will assign the IP 172.16.1.2 to it. The associated routes for this will be created as well.

Test VPN Link

Once you have executed the commands above on each server then the VPN link will be setup. Keep in mind that this is a clear text link and all traffic can be seen. You will see the following warning as the VPN link is established:
******* WARNING *******: all encryption and authentication features 
disabled -- all data will be tunnelled as cleartext
If the link has been established successfully you will see the following on each server:
Wed Aug  5 16:59:59 2009 Peer Connection Initiated with 10.100.1.50:1194
Wed Aug  5 17:00:01 2009 Initialization Sequence Completed
Note that the IP will vary depending on your setup
Open up two more connections to your servers via SSH and perform a ping test from each. In our test environment we will perform a test on ServerA and we will ping ServerB but we will use the VPN tunnel instead. To force traffic over the VPN tunnel simply ping the VPN IP for ServerB which is 172.16.1.2.
# ping 172.16.1.2
PING 172.16.1.2 (172.16.1.2) 56(84) bytes of data.
64 bytes from 172.16.1.2: icmp_seq=1 ttl=64 time=4.00 ms
64 bytes from 172.16.1.2: icmp_seq=2 ttl=64 time=0.000 ms
64 bytes from 172.16.1.2: icmp_seq=3 ttl=64 time=0.000 ms
Do the same thing on ServerB. You should see similar results. If you see Request Timed Out then your VPN link might not be established. Please check your IP addresses and attempt to establish the link again.
To finish your testing and close the link simply press Control-C on each server to close the VPN link.

Static Key VPN

Now that we have an established VPN link it is time to secure it a little bit. In this step we will create a 128-bit security key that will be stored on each server and used to encrypt our traffic over the VPN tunnel.

Creating the Key

Creating the VPN key is surprisingly simple. You will need to create the key on one server and then copy it to the other server. In our example we will use ServerA to create the key and use SCP to copy it to ServerB.
For this part of the setup we will need to change to super user mode. Type the following command:
# su
Enter your root password when prompted.
Now we need to go to the directory where we will store our static key.
# cd /usr/share/doc/openvpn-2.0.9/
Once there we will need to produce our static key. To produce it type the command below to create a static key file called key.
# openvpn --genkey --secret key
If you perform a directory listing (ls) you will see a file called key in the directory. We will use this when starting our VPN connection.
For now we will remain as the super user for the remainder of this article.

Copy the Key

We need to copy our static key over to ServerB so they are using the same credentials. If you do not perform this step then your VPN link will fail to establish. To copy the key we will use the SCP (Secure Copy) command to copy the file over SSH. Run the following command below to copy the key file over. Note that you will need to change the IP address in the example below to match your second server.
# scp key root@10.100.1.20:/usr/share/doc/openvpn-2.0.9/
The first prompt you will receive is asking you to accept the SSH fingerprint key... simply type yes and press Enter. You will then be prompted for your root password -- enter it here.
If the copy was successful you should see something like this:
key                                           100%  636     0.6KB/s   00:00

Creating the VPN link

Now that we have our key created the key and copied it to ServerB it is time to setup our link again. Type the command below to setup the VPN link. Be sure to note that the command is the same for each server but the key is appended to the command. Note that since we are using super user mode some directives will be different.

ServerA Commands

To create the link on ServerA run the following command:
# /usr/sbin/openvpn --remote 10.100.1.50 --dev tun1 --ifconfig 172.16.1.1 172.16.1.2 --secret key
This command will create a VPN link with ServerB (10.100.1.50). It will also prepare a virtual interface called tun1 and will assign the IP 172.16.1.1 to it. The associated routes for this will be created as well.

ServerB Commands

Before we can enter the command we will need to go to the correct directory and enter super user mode as well as create the link. Run the following commands:
# su
# cd /usr/share/doc/openvpn-2.0.9
# /usr/sbin/openvpn --remote 10.100.1.20 --dev tun1 --ifconfig 172.16.1.2 172.16.1.1 --secret key
This command will create a VPN link with ServerA (10.100.1.20). It will also prepare a virtual interface called tun1 and will assign the IP 172.16.1.2 to it. The associated routes for this will be created as well.

Test the VPN link

As with the previous setup go ahead and test the link by pinging each side of your VPN tunnel.

TLS-enabled VPN

Now that we have a functioning VPN connection and have proved that we can use 128-bit static keys it is now time to beef up our security a bit. The following steps will walk you through setting up TLS-based security with regenerative security on timed intervals. This process will involved creating server and client certificates along with a certificate authority to authenticate those certificates.
We will go ahead and tear down the existing VPN tunnel that we setup by pressing Control-C on each server. You should be returned back to the command prompt. You'll notice that we are still logged in as the super user -- this is okay.

Easy-RSA

To create our keys and certificates we will use three programs (build-ca, build-key, and build-key-server) that ship with OpenVPN. Follow the steps below to create the necessary items.

Setup

First we need to perform some additional setup functions for Easy-RSA on ServerA. The first thing we need to do is make sure that we are in the correct directory:
# cd /etc/openvpn
You'll notice that there is nothing in this directory if you 'ls' it. To prepare all of the files run the following commands below:
# mkdir easy-rsa
# cp -R /usr/share/doc/openvpn-2.0.9/easy-rsa/2.0/* easy-rsa/
# chmod -R 777 easy-rsa/
# cd easy-rsa/
Now we need to setup the correct environment variables. Run the following command: (Note the double periods)
# . ./vars
Now clean up everything:
# ./clean-all

Create Certificate Authority (CA)

We are now ready to build are certificate authority (CA). To build this simply run the following command:
# ./build-ca
You will be asked a series of questions. You may choose to answer none or all of them. Keep in mind that these will show up on your certificate if it is inquired upon. The values we are using in our example are being shown:
  • Country Name: US
  • State or province: TX
  • Locality Name: San Antonio
  • Organization Name: Rackspace
  • Organizational Unit Name:
  • Common Name: OpenVPN-CA (you can choose what you'd like here)
  • Email Address: support@rackspacecloud.com
Once you complete these items you will be taken back to your command prompt. Your ca.key and ca.crt files will be stored in the keys directory.

Create Server Certificate

Now we are ready to generate the certificate for the server's side of the VPN tunnel. Run the following command:
# ./build-key-server ServerA
You'll note that we used the server name of ServerA for the key. This will help us better identify that this is for ServerA which is the master VPN server.
You will be asked the same questions again and a few additional questions. The answers we have used for our demonstration are listed here:
  • Country Name: US
  • State or province: TX
  • Locality Name: San Antonio
  • Organization Name: Rackspace
  • Organizational Unit Name:
  • Common Name: ServerA (note that we used our server name)
  • Email Address: support@rackspacecloud.com
  • A challenge password:
  • An optional company name:
  • Sign the certificate: Y
  • Commit: Y
You will notice the two review questions at the end... simply press Y to those questions.

Create Client Certificate

Now we are ready to build the client certificate for ServerB. Run the following command:
# ./build-key ServerB
Notice that we used ServerB for the certificate name. You will be presented with the same questions as above with the client certificate. The only difference is that we will use ServerB for the Common Name.
Once the certificate has been saved you will see them in /etc/openvpn/easy-rsa/keys.

Create Diffie Hellman Keys

The final step in creating your TLS keys is producing the Diffie Hellman, or DH, keys. Run the following command to produce them:
# ./build-dh
You will see a series of characters run across the screen. This process may take up to 30 seconds or more to complete. Upon completion you will be returned to the command prompt.

Copy Keys

Now that we have the keys and certificates created it is time to put them in an appropriate spot.

Server A (TLS Server)

We will be storing our keys in /etc/openvpn/keys on both servers; however, we would like to keep them in the original directory on ServerA for regeneration purposes. To do this we will create a symbolic link:
# ln -s /etc/openvpn/easy-rsa/keys /etc/openvpn/keys

Server B (TLS Client)

ServerB doesn't currently have any of the keys installed so we will need to copy the keys from ServerA to ServerB. Run the following commands on ServerA to copy them over:
# scp -r /etc/openvpn/keys root@10.100.1.50:/etc/openvpn/keys
Now we have the keys you need on each server. However we need to remove some files from ServerB as they really shouldn't be there. To fix this we'll log into ServerB through SSH and run the following commands:
# rm -f /etc/openvpn/keys/*.pem
# rm -f /etc/openvpn/keys/ServerA*
# rm -f /etc/openvpn/keys/index*
# rm -f /etc/openvpn/keys/serial*
You should be left with five (5) files remaining.

Create VPN Link

Now we are ready to establish our TLS-enabled VPN link between ServerA and ServerB.

Server A (TLS Server)

Run the following command in super user mode to establish the VPN tunnel:
# /usr/sbin/openvpn --remote 10.100.1.50 --dev tun1 --ifconfig 172.16.1.1 172.16.1.2 --tls-server 
     --dh /etc/openvpn/keys/dh1024.pem --ca /etc/openvpn/keys/ca.crt 
     --cert /etc/openvpn/keys/ServerA.crt --key /etc/openvpn/keys/ServerA.key 
     --reneg-sec 60 --verb 5

Server B (TLS Client)

Run the following command in super user mode to establish the VPN tunnel:
# /usr/sbin/openvpn --remote 10.100.1.20 --dev tun1 --ifconfig 172.16.1.2 172.16.1.1 --tls-client 
     --ca /etc/openvpn/keys/ca.crt --cert /etc/openvpn/keys/ServerB.crt --key /etc/openvpn/keys/ServerB.key 
     --reneg-sec 60 --verb 5

Once you run the appropriate line on each server you will see a page or two of text scroll across the terminal. There are a few lines that we need to pay attention to:
Wed Aug  5 23:11:18 2009 us=378185 Control Channel: TLSv1, cipher TLSv1/SSLv3 DHE-RSA-AES256-SHA, 1024 bit RSA
This line above means that we are now using TLSv1 to encrypt our data channel. Great!


Wed Aug  5 23:11:18 2009 us=378185 [ServerA] Peer Connection Initiated with 10.1001.1.20:1194
This line above means that our VPN tunnel has been established.

Test Your Link

With the VPN tunnel established you may open up new SSH connections to your server and perform connection tests using the 172.16.1.1 and 172.16.1.2 IP addresses. All traffic using these addresses will flow over the VPN tunnel. Once you are done testing you may bring down the tunnel by pressing Control-C on each server.

Logging

One thing to note is that on each of the openvpn commands we executed we used the command line argument --verb 5. This will raise the verbosity level of the application, in other words, the application logs more information. You will see quite a bit of information with this level including read and write activities across the VPN, key generation, and more. If you would like to turn off verbosity simply leave the --verb 5 off the command.

Startup Script

We've tested and proved that our VPN tunnel is working but setting up the tunnel manually is simply not effective. To accomplish this we will need to create a file in /etc/openvpn/ that our startup script will load. The server and client configuration files will be different so please be sure to use the correct configuration.

Server Script

To create a configuration for the file you will need to open your favorite text editor. For our example we will use nano:
# nano -w /etc/openvpn/server.conf
For the sake of simplicity we are only going to give the startup script for a TLS-enabled VPN tunnel. This particular tunnel configuration will allow you to setup a 1024-bit encrypted VPN tunnel and the VPN network will be 172.16.1.0/24.
local 10.1.100.20                    # Replace with your internal (eth1) IP
port 1194
proto udp
dev tun
ca /etc/openvpn/keys/ca.crt
cert /etc/openvpn/keys/ServerA.crt   # Replace with the key/certificate pair you created
key /etc/openvpn/keys/ServerA.key    # Replace with the key/certificate pair you created
dh /etc/openvpn/keys/dh1024.pem
server 172.16.1.1 255.255.255.0      # This is the network range that your server will give out.  These MUST be non-routeable.
ifconfig-pool-persist ipp.txt
keepalive 10 120
comp-lzo
user nobody
group nobody
status openvpn-status.log
verb 3
client-to-client
After you have entered this information into the text editor simply press Control-X to exit, then Y to save followed by the Enter key.

Client Script

To create a configuration for the file you will need to open your favorite text editor. For our example we will use nano:
# nano -w /etc/openvpn/client.conf
For the sake of simplicity we are only going to give the startup script for a TLS-enabled VPN tunnel. This particular tunnel configuration will allow you to setup a 1024-bit encrypted VPN tunnel that will pull an IP address from the VPN pool.
client
dev tun
local 10.1.100.50                   # Replace with your internal (eth1) IP
port 1194
proto udp
remote 10.1.100.20 1194             # Replace with your VPN server's IP
nobind
persist-key
persist-tun
ca /etc/openvpn/keys/ca.crt
cert /etc/openvpn/keys/ServerB.crt  # Replace with the key/certificate pair you created
key /etc/openvpn/keys/ServerB.key   # Replace with the key/certificate pair you created
comp-lzo
verb 3
After you have entered this information into the text editor simply press Control-X to exit, then Y to save followed by the Enter key.

Final Steps

Once you have the files saved it is time to enable the OpenVPN service. Type the following commands on the client and server:
# /sbin/chkconfig openvpn on
You may also start the service by typing either of the following commands on the server and client:
# /etc/init.d/openvpn start

-OR-

# service openvpn start
You can verify that the service is running by typing:
# service openvpn status
You can see the interface information by typing the following:
# /sbin/ifconfig tun0

Summary

Hopefully this has given some insight on how to setup VPN tunneling with OpenVPN. These examples are just skimming the surface of the types of VPN configurations that are possible with OpenVPN.
--Kelly Koehn 00:02, 6 August 2009 (CDT)

REFERENCES

http://cloudservers.rackspacecloud.com/index.php/CentOS_-_VPN_tunneling_with_OpenVPN