Wednesday, May 16, 2012

Secure Remote Access To Your Home Network Using pfSense and OpenVPN



In my previous post, I described how to install and setup pfSense in a home network and offered some configuration recommendations based on my own experiences. In this post, I will describe how to set up Virtual Private Network (“VPN”) access in pfSense using OpenVPN. Once configured, you’ll be able to use an OpenVPN client in Windows or Linux to securely access your home network remotely using either X.509 PKI authentication (public key infrastructure using X.509-based certificates and private keys) or pre-shared private key authentication.
pfSense (i.e., “making sense of packet filtering”) is a customized version of FreeBSD tailored specifically for use as a perimeter firewall and router, and can be managed entirely from a web-based or command line interface. In addition to being a firewall and routing platform, pfSense includes a long list of other features, as well as a package system allowing its capabilities to be expanded even further. pfSense is free, open source software distributed under the BSD license.
OpenVPN is a lightweight VPN software application supporting both remote access and site-to-site VPN configurations. It uses SSL/TLS security for encryption and is capable of traversing network address translation devices and firewalls. The OpenVPN community edition is free, open source software and portable to most major operating systems, including Linux, Windows 2000/XP/Vista/7, OpenBSD, FreeBSD, NetBSD, Mac OS X, and Solaris. It is distributed under the GPL license version 2.
The versions for the software used in this post were as follows:
  • OpenVPN for Windows v2.2.2
  • OpenVPN for Ubuntu, version 2.2.0-2ubuntu1
  • pfSense v2.0.1
  • Ubuntu v11.10 (x64)
  • Windows 7 Professional (x64)
  • OpenVPN Authentication
    Before walking through the steps necessary to configure the OpenVPN server in pfSense and OpenVPN client software in Windows and Linux, let’s discuss the differences between the two methods used by OpenVPN in most situations to authenticate peers (clients and servers) to one another: X.509 PKI and pre-shared private keys.
    In the X.509 PKI authentication method, the private keys of the peers are kept secret and its public key made publicly available via “certificates” based on the ITU-T X.509 standard. The goal of a certificate is to certify that a public key belongs to the person or entity claiming to be its owner, or more accurately, the person/entity owning the corresponding private key. To achieve this certification, a certificate is signed by an authority that can be trusted by everyone: the Certification Authority (“CA”). In OpenVPN, a CA certificate and its corresponding private key is generated locally, as well as individual certificates and private keys for the OpenVPN server (located in pfSense in our case) and each OpenVPN client. The CA and its associated private key are then used to sign the server and client certificates during the process of generating them. Then, when a VPN session is established, both server and client will authenticate the other by, among other things, verifying that the certificate each presents to the other was signed by the CA.
    The X.509 PKI method has a number of advantages compared to the pre-shared key approach. First, the server only needs its own signed certificate and private key – it doesn’t need to know anything about the certificates associated with the client(s), only that they were signed by the CA certificate. Second, because the server can perform this signature verification without needing access to the CA private key, the CA key can be stored somewhere safe and secure. Finally, individual clients can be disabled simply be adding their certificates to a CRL (“Certification Revocation List”) located on the server. The Certification Revocation List allows compromised certificates to be selectively rejected without requiring that the entire PKI be rebuilt. This is the primary reason that X.509 PKI is considered the preferred method for implementing remote client access using OpenVPN – the ability to revoke access to individual machines. Alas though, there are some issues to be considered when using this approach. One of course is the integrity of the CA private key, which ensures the security of the PKI. Anyone with access to the this key can generate certificates to be used to gain VPN access to a network, so it must be kept secure and never distributed to clients or servers. Another is that creating and managing OpenVPN certificates and private keys may be a bit tedious, particularly if all you want to do is setup personal VPN access to your home network.
    In the pre-shared key authentication method, a single static 2048-bit private RSA key is generated and copied to the OpenVPN server and client. This shared key approach is typically used for site-to-site connections involving, say, two pfSense boxes located at a main office and a remote office, with one acting as the OpenVPN server and the other as the client. However, it also offers the simplest setup for getting a VPN connection to your network up and running quickly with minimal configuration. There are some shortcomings with this method though that should be considered before using it. First, it doesn’t scale terribly well. Each client needing VPN access must have a unique OpenVPN server and TCP or UDP port defined in pfSense. This can be a pain to manage as the number of clients grows. This pain can be blunted a bit if you issue the same shared key to each client, but if the key is compromised, a new key must be generated and securely provided to the OpenVPN server and all clients. Another problem with this method is that these keys exist in plaintext on each OpenVPN client (it also exists in plain text in pfSense but presumably access to that machine is further restricted) resulting in security that’s perhaps less than desirable.
    In summary then, the X.509 PKI method offers scalability and arguably better security, but may be cumbersome for some to setup and manage; while the pre-shared key method is easier to setup, and likely just fine for implementations with a limited number of remote VPN clients. The remainder of this post will discuss how to configure a VPN using either method, but you’ll need to determine which approach best meets your needs.
    Installing OpenVPN
    OpenVPN comes pre-installed in pfSense so we’ll begin by installing OpenVPN on Windows and Linux, then use it to generate the necessary client and server keys and certificates. OpenVPN provides a set of batch files/scripts based on OpenSSL collectively called “easy-rsa” that will make the task of generating these certificates and keys much easier. To help explain the steps involved, we’ll generate the following certificates and keys:
    ca.key
    ca.crt
    pfsense.key
    pfsense.crt
    bob.key
    bob.crt
    static-bob.key
    Then we’ll copy these keys to the machines that need them and put them to work to create an OpenVPN connection to a home network that uses the subnet 192.168.10.0/24. Doing so will involve creating another subnet, 192.168.20.0/24, for our OpenVPN server and clients, and designating UDP port 13725 for the OpenVPN server to use to listen on for incoming VPN requests (See Figure 1).
    Screenshot of example network using OpenVPN server and pfSense
    Figure 1

      Installing OpenVPN and creating certificates and keys in Windows
    OpenVPN for Windows can be installed using the Windows Installer file located at the OpenVPN download page. During the install, accept all defaults, including the installation of the TAP-Win32 adapter. After it is installed, OpenVPN will associate itself with files having the .ovpn extension.
    Now we’re ready to generate the various certificates and keys. First though, a little pre-configuration is needed. Create the folder c:\openssl\ssl then copy the file c:\Program Files (x86)\OpenVPN\easy-rsa\openssl-1.0.0.cnf to this folder and change the file name to openssl.cnf. Next, open a command prompt and change folders to c:\Program Files (x86)\OpenVPN\easy-rsa\. Run the following batch file, which will copy the file vars.bat.sample to vars.bat. Note: this will overwrite any preexisting vars.bat file:
    init-config.bat
    Open the file c:\Program Files(x86)\OpenVPN\easy-rsa\vars.bat with a text editor and change this line:
    set HOME=%ProgramFiles%\OpenVPN\easy-rsa
    to this line:
    set HOME=%ProgramFiles(x86)%\OpenVPN\easy-rsa
    While in vars.bat, take a look at the values associated with the variables KEY_COUNTRY, KEY_PROVINCE, KEY_CITY, KEY_ORG, and KEY_EMAIL. Assigning values to these variables helps speed the process of generating the various certificates and keys by initializing these common variables when the various easy-rsa batch files are invoked. You may leave them at their default values or change them if desired, however, don’t leave any blank. You may also wish to increase the variable KEY_SIZE from 1024 to 2048. However, note that this will increase the VPN SSL/TLS negotiation time. The remaining variables can remain at their default values. Now, make sure your at c:\Program Files (x86)\OpenVPN\easy-rsa\, then run the following batch files:
    vars.bat
    clean-all.bat
    Running this sequence of commands for the first time will create the folder c:\Program Files (x86)\OpenVPN\easy-rsa\keys\, which serves to hold the certificates and keys we generate (You can define the location of this folder using the variable KEY_DIR in vars.bat). Also note that from now on, each time you run this sequence to create new certificates and keys, any existing certificates and keys in the keys folder will be deleted.
    Okay then, let’s generate the CA certificate and CA private key. The only value which must be explicitly entered when requested is for the variable “Common Name,” which is set to “openvpn-ca” in the following example. An optional “Organization Unit Name” and “Name” value is also requested and may be modified if desired:
    C:\Program Files (x86)\OpenVPN\easy-rsa>build-ca.bat
    Loading 'screen' into random state - done
    Generating a 1024 bit RSA private key
    ...........................................................................++++++
    ...................................++++++
    writing new private key to 'keys\ca.key'
    -----
    You are about to be asked to enter information that will be incorporated
    into your certificate request.
    What you are about to enter is what is called a Distinguished Name or a DN.
    There are quite a few fields but you can leave some blank
    For some fields there will be a default value,
    If you enter '.', the field will be left blank.
    -----
    Country Name (2 letter code) [US]:
    State or Province Name (full name) [CA]:
    Locality Name (eg, city) [SanFrancisco]:
    Organization Name (eg, company) [OpenVPN]:
    Organizational Unit Name (eg, section) [changeme]:
    Common Name (eg, your name or your server's hostname) [changeme]:openvpn-ca
    Name [changeme]:
    Email Address [mail@host.domain]:
     
    C:\Program Files (x86)\OpenVPN\easy-rsa>
    Now, if you navigate to c:\Program Files (x86)\OpenVPN\easy-rsa\keys\, you should see the newly minted CA certificate (ca.crt) and CA private key (ca.key) files.
    Next, we’ll generate a certificate and private key for the OpenVPN server that resides in pfSense. Here we’ll need to pass a text string to the batch file when invoking it. That text string then becomes the name for the server’s certificate and private key. In this example, we’ll use the text string “pfsense.” As in the previous step, most values will be automatically initialized by vars.bat. Once again, the value for Common Name must be explicitly entered, which we will set to “pfsense” to match the name of the server key. This batch file will also seek to define some additional optional attributes, including the “challenge password,” used in certificate revocation, which we will leave blank, and the “company name,” which you may fill in if desired. Finally, you’ll be asked to sign the server’s certificate using the CA certificate. Review the server certificate carefully, then select “y” to sign and then to commit the signature:
    C:\Program Files (x86)\OpenVPN\easy-rsa>build-key-server.bat pfsense
    Loading 'screen' into random state - done
    Generating a 1024 bit RSA private key
    .......++++++
    ...........................++++++
    writing new private key to 'keys\pfsense.key'
    -----
    You are about to be asked to enter information that will be incorporated
    into your certificate request.
    What you are about to enter is what is called a Distinguished Name or a DN.
    There are quite a few fields but you can leave some blank
    For some fields there will be a default value,
    If you enter '.', the field will be left blank.
    -----
    Country Name (2 letter code) [US]:
    State or Province Name (full name) [CA]:
    Locality Name (eg, city) [SanFrancisco]:
    Organization Name (eg, company) [OpenVPN]:
    Organizational Unit Name (eg, section) [changeme]:
    Common Name (eg, your name or your server's hostname) [changeme]:pfsense
    Name [changeme]:
    Email Address [mail@host.domain]:
     
    Please enter the following 'extra' attributes
    to be sent with your certificate request
    A challenge password []:
    An optional company name []:
    Using configuration from openssl-1.0.0.cnf
    Loading 'screen' into random state - done
    Check that the request matches the signature
    Signature ok
    The Subject's Distinguished Name is as follows
    countryName           :PRINTABLE:'US'
    stateOrProvinceName   :PRINTABLE:'CA'
    localityName          :PRINTABLE:'SanFrancisco'
    organizationName      :PRINTABLE:'OpenVPN'
    organizationalUnitName:PRINTABLE:'changeme'
    commonName            :PRINTABLE:'pfsense'
    name                  :PRINTABLE:'changeme'
    emailAddress          :IA5STRING:'mail@host.domain'
    Certificate is to be certified until Jan 18 16:03:14 2022 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
     
    C:\Program Files (x86)\OpenVPN\easy-rsa>
    Finally, let’s generate our client certificate and key following steps similar to the ones we used above for creating the server certificate and key. This time, however, the text string we pass to the batch file will become the name for the client certificate and key. In this example, we’ll use the text string “bob,” and set the Common Name value to be the same. Review the client certificate carefully, then select “y” to sign and then to commit the signature. You’ll need to run this same batch file for each client you want to grant VPN access to – and remember, you’ll need to use a unique key name/Common Name combination for each one:
    C:\Program Files (x86)\OpenVPN\easy-rsa>build-key.bat bob
    Loading 'screen' into random state - done
    Generating a 1024 bit RSA private key
    ...........................++++++
    ....++++++
    writing new private key to 'keys\bob.key'
    -----
    You are about to be asked to enter information that will be incorporated
    into your certificate request.
    What you are about to enter is what is called a Distinguished Name or a DN.
    There are quite a few fields but you can leave some blank
    For some fields there will be a default value,
    If you enter '.', the field will be left blank.
    -----
    Country Name (2 letter code) [US]:
    State or Province Name (full name) [CA]:
    Locality Name (eg, city) [SanFrancisco]:
    Organization Name (eg, company) [OpenVPN]:
    Organizational Unit Name (eg, section) [changeme]:
    Common Name (eg, your name or your server's hostname) [changeme]:bob
    Name [changeme]:
    Email Address [mail@host.domain]:
     
    Please enter the following 'extra' attributes
    to be sent with your certificate request
    A challenge password []:
    An optional company name []:
    Using configuration from openssl-1.0.0.cnf
    Loading 'screen' into random state - done
    Check that the request matches the signature
    Signature ok
    The Subject's Distinguished Name is as follows
    countryName           :PRINTABLE:'US'
    stateOrProvinceName   :PRINTABLE:'CA'
    localityName          :PRINTABLE:'SanFrancisco'
    organizationName      :PRINTABLE:'OpenVPN'
    organizationalUnitName:PRINTABLE:'changeme'
    commonName            :PRINTABLE:'bob'
    name                  :PRINTABLE:'changeme'
    emailAddress          :IA5STRING:'mail@host.domain'
    Certificate is to be certified until Jan 18 16:14:39 2022 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
     
    C:\Program Files (x86)\OpenVPN\easy-rsa>
    To further protect VPN access, you may wish to password-protect the client’s private key. To do this we’ll need modify the build-key.bat file so it will prompt us to enter a password that will be used in conjunction with generating the private key. First, copy build-key.bat as build-key-pass.bat, then open build-key-pass.bat in your text editor and remove the option -nodes from the line containing the openssl command and save the file (See line 4). Now, anyone (including you) wishing to use this key when starting the VPN connection will need to enter the correct password:
    1@echo off
    2cd %HOME%
    3rem build a request for a cert that will be valid for ten years
    4openssl req -days 3650 -nodes -new -keyout %KEY_DIR%\%1.key -out %KEY_DIR%\%1.csr -config %KEY_CONFIG%
    5rem sign the cert request with our ca, creating a cert/key pair
    6openssl ca -days 3650 -out %KEY_DIR%\%1.crt -in %KEY_DIR%\%1.csr -config %KEY_CONFIG%
    7rem delete any .old files created in this process, to avoid future file creation errors
    8del /q %KEY_DIR%\*.old
    That’s it for installing OpenVPN and building your X.509 PKI in Windows. If you plan to use the pre-shared private key authentication method, you need only to generate a single 2048-bit RSA key that will be used in both the OpenVPN server and client(s). Navigate to where you want the key to be generated and then issue the following command. In this example, we’ll use “static-bob” as the key file name and place it in the same folder our other certificates and keys are located:
    cd c:\Program Files (x86)\OpenVPN\easy-rsa\keys\
    openvpn --genkey --secret static-bob.key
      Installing OpenVPN and creating certificates and keys in Linux
    If you’ve been following the installation and configuration of OpenVPN under Windows to this point, the steps used under Linux will seem familiar. To begin, download and install OpenVPN using the distribution’s package manager. Using the Debian-based Ubuntu as an example:
    sudo apt-get update
    sudo apt-get install openvpn
    Now copy the OpenVPN scripts used to generate the various certificates and keys into a new directory and take ownership of those files:
    sudo mkdir /etc/openvpn/easy-rsa/
    sudo cp -r /usr/share/doc/openvpn/examples/easy-rsa/2.0/* /etc/openvpn/easy-rsa/
    sudo chown -R $USER /etc/openvpn/easy-rsa/
    We’re now ready to generate the various certificates and keys. Start by opening the file /etc/openvpn/easy-rsa/vars with your text editor and take a look at the variables KEY_COUNTRY, KEY_PROVINCE, KEY_CITY, KEY_ORG, and KEY_EMAIL. Assigning values to these variables in vars helps speed the process of generating the various certificates and keys by initializing these common variables in the various easy-rsa scripts. You may leave them at their default values or change them if desired, however, don’t leave any blank. You may also wish to increase the variable KEY_SIZE from 1024 to 2048. However, keep in mind this will increase the VPN SSL/TLS negotiation time. The remaining variables can remain at their default values. Now, open a terminal, and run the following:
    cd /etc/openvpn/easy-rsa/
    source vars && ./clean-all
    Running this sequence of commands for the first time will create the directory /etc/openvpn/easy-rsa/keys/, which will hold the certificates and keys we generate (You can define the location of this folder using the variable KEY_DIR in vars). Also note that from now on, each time you run this sequence to create new certificates and keys, any existing certificates and keys in the keys directory will be deleted. Okay then, let’s generate the CA private key and CA certificate. The script uses the “Organization Name” value as the default value for “Common Name,” however, we’ll change this to “openvpn-ca” in the following example. Values for “Organization Unit Name” and “Name” will also be requested and may be modified if desired:
    iceflatline@test:/etc/openvpn/easy-rsa$ ./build-ca
    Generating a 1024 bit RSA private key
    ...........++++++
    ...++++++
    writing new private key to 'ca.key'
    -----
    You are about to be asked to enter information that will be incorporated
    into your certificate request.
    What you are about to enter is what is called a Distinguished Name or a DN.
    There are quite a few fields but you can leave some blank
    For some fields there will be a default value,
    If you enter '.', the field will be left blank.
    -----
    Country Name (2 letter code) [US]:
    State or Province Name (full name) [CA]:
    Locality Name (eg, city) [SanFrancisco]:
    Organization Name (eg, company) [Fort-Funston]:
    Organizational Unit Name (eg, section) []:
    Common Name (eg, your name or your server's hostname) [Fort-Funston CA]:openvpn-ca
    Name []:
    Email Address [me@myhost.mydomain]:
    iceflatline@test:/etc/openvpn/easy-rsa$
    Now, if you navigate to /etc/openvpn/easy-rsa/keys/, you should see the newly minted CA certificate (ca.crt) and CA private key (ca.key) files.
    Next, we’ll generate a certificate and private key for the OpenVPN server that resides in pfSense. Here we’ll need to pass a text string to the script when invoking it. That text string then becomes the name for the server’s certificate and private key. In this example, we’ll use the text string “pfsense.” As in the previous step, most values will be automatically initialized by vars. We’ll leave the Common Name value at the default “pfsense” to match the name of the server key. This script will also seek to define some optional attributes, including the “challenge password,” which we will leave blank, and the “company name,” which may be filled in if desired. Finally, you’ll be asked to sign the server’s certificate using the CA certificate. Review the values in the server certificate carefully, then select “y” to sign and then to commit the signature:
    iceflatline@test:/etc/openvpn/easy-rsa$ ./build-key-server pfsense
    Generating a 1024 bit RSA private key
    ..............................++++++
    ....++++++
    writing new private key to 'pfsense.key'
    -----
    You are about to be asked to enter information that will be incorporated
    into your certificate request.
    What you are about to enter is what is called a Distinguished Name or a DN.
    There are quite a few fields but you can leave some blank
    For some fields there will be a default value,
    If you enter '.', the field will be left blank.
    -----
    Country Name (2 letter code) [US]:
    State or Province Name (full name) [CA]:
    Locality Name (eg, city) [SanFrancisco]:
    Organization Name (eg, company) [Fort-Funston]:
    Organizational Unit Name (eg, section) []:
    Common Name (eg, your name or your server's hostname) [pfsense]:
    Name []:
    Email Address [me@myhost.mydomain]:
     
    Please enter the following 'extra' attributes
    to be sent with your certificate request
    A challenge password []:
    An optional company name []:
    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:'US'
    stateOrProvinceName   :PRINTABLE:'CA'
    localityName          :PRINTABLE:'SanFrancisco'
    organizationName      :PRINTABLE:'Fort-Funston'
    commonName            :PRINTABLE:'pfsense'
    emailAddress          :IA5STRING:'me@myhost.mydomain'
    Certificate is to be certified until Jan 18 16:42:16 2022 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
    iceflatline@test:/etc/openvpn/easy-rsa$
    Finally, let’s generate our client certificate and key following steps similar to the ones we used above for creating the server certificate and key. This time, however, the text string we pass to the script will become the default name for the client certificate and key. In this example, we’ll use the text string “bob,” which will also become the default value for the Common Name. Review the client certificate carefully, then select “y” to sign and then to commit the signature. You’ll need run the this same script for each client you want to grant access to – and remember, you’ll need to use a unique key name/Common Name combination for each one:
    iceflatline@test:/etc/openvpn/easy-rsa$ ./build-key bob
    Generating a 1024 bit RSA private key
    .....................++++++
    ..........................................++++++
    writing new private key to 'bob.key'
    -----
    You are about to be asked to enter information that will be incorporated
    into your certificate request.
    What you are about to enter is what is called a Distinguished Name or a DN.
    There are quite a few fields but you can leave some blank
    For some fields there will be a default value,
    If you enter '.', the field will be left blank.
    -----
    Country Name (2 letter code) [US]:
    State or Province Name (full name) [CA]:
    Locality Name (eg, city) [SanFrancisco]:
    Organization Name (eg, company) [Fort-Funston]:
    Organizational Unit Name (eg, section) []:
    Common Name (eg, your name or your server's hostname) [bob]:
    Name []:
    Email Address [me@myhost.mydomain]:
     
    Please enter the following 'extra' attributes
    to be sent with your certificate request
    A challenge password []:
    An optional company name []:
    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:'US'
    stateOrProvinceName   :PRINTABLE:'CA'
    localityName          :PRINTABLE:'SanFrancisco'
    organizationName      :PRINTABLE:'Fort-Funston'
    commonName            :PRINTABLE:'bob'
    emailAddress          :IA5STRING:'me@myhost.mydomain'
    Certificate is to be certified until Jan 18 16:45:31 2022 GMT (3650 days)
    Sign the certificate? [y/n]:y
     
    1 out of 1 certificate requests certified, commit? [y/n]n
    CERTIFICATION CANCELED
    iceflatline@test:/etc/openvpn/easy-rsa$
    To further protect access into your network, you may wish to password-protect the client’s private key. To do this simply run the ./build-key-pass script instead instead of ./build-key. You will be prompted to enter a password that will be used in conjunction with generating the private key. Now, anyone (including you) wishing to use this key will need to enter the correct password.
    That’s it for installing OpenVPN and building your X.509 PKI in Linux. If you plan to use the pre-shared private key authentication method instead, you need only to generate a single 2048-bit RSA key that will be used in both the OpenVPN server and client(s). Navigate to where you want the key to be generated and then issue the following command. In this example, we’ll use “static-bob” as the key file name and place it in the same directory our other certificates and keys are located:
    cd /etc/openvpn/easy-rsa/keys/
    openvpn --genkey --secret static-bob.key
    Configuring OpenVPN: X.509 PKI Authentication
    Now that we’ve installed OpenVPN client software in Windows and Linux, and generated the various certificates and keys, let’s move on and discuss how to configure these clients, as well as the OpenVPN server in pfSense, for VPN access into our home network using the X.509 PKI authentication method. However, before we do, now would be a good time to move the file ca.key to a secure location. Recall, that the privacy of this key is what ensures the security of your entire PKI.
      OpenVPN Server configuration in pfSense for X.509 PKI authentication
    To configure the OpenVPN server in pfSense for X.509 PKI authentication, we’ll start by importing the server certificate and private key we created, as well as our CA certificate.
    Log into your pfSense box’s “webConfigurator” interface and navigate to System->Cert Manager->CA. To import a new CA, select the “+” icon. Add a name for your CA (e.g., “OpenVPN Server CA #1″) under “Desriptive name,” then click on the drop down list under “Method” and ensure that “Import and existing Certficate Authority” is selected. Carefully and securely copy the contents of the ca.crt file from the machine you generated it on and paste it into this field, then select “Save.”
    Now, navigate to System->Cert Manager->Certificates and select the “+” icon to import a new certificate and its private key. Add a name for your certificate (e.g., “OpenVPN Server Cert #1″) under “Desriptive name,” then click on the drop down list under “Method” and ensure that “Import and existing Certficate” is selected. Carefully and securely copy the contents of the pfsense.crt file from the machine you generated it on and paste it into the “Certificate data” field, and the contents of pfsense.key into the “Private key data” field. Finish by selecting “Save.”
    The information you copy from your ca.crt, pfsense.crt and pfsense.key files will no longer appear in these fields after you select Save. Rest assured, however, that they are stored in pfSense. In fact, you will find them stored as server1.ca, server1.cert and server1.key respectively in /var/etc/openvpn.
    Next we’ll configure the various OpenVPN server parameters. Navigate to VPN->OpenVPN->Server and click on the “+” icon to add a new OpenVPN server (See Figure 2).
     Screenshot of pfSense configuration wizard
    Figure 2
    Most of the parameters will be left at their default settings, however the following will need to be configured:
    Server Mode – We’re using the X.509 PKI authentication method for this example so we should select “Remote Access(SSL/TLS)” here.
    Local port – This is the logical port that the OpenVPN server will listen on for VPN connections. To help improve security, we’ll avoid using OpenVPN’s default port 1194 and use port 13725 instead.
    Description – Enter a description here for your reference. This field is optional but helpful.
    TLS Authentication – Enabling these two check boxes adds an additional HMAC (Hash-based Message Authentication Code) signature to all SSL/TLS handshake packets for integrity verification. Any UDP packet not bearing the correct HMAC signature can be dropped without further processing. The HMAC signature provides an additional level of security above and beyond that provided by SSL/TLS at the cost of some processing power and connection speed. Using this feature is beyond the scope of this post so for now uncheck “Enable authentication of TLS packets.” If you would like to learn more about using TLS authentication, consult the hardening OpenVPN security section of the OpenVPN documentation.
    Peer Certificate Authority – Ensure that the CA you imported under System->Cert Manager->CA (e.g., “OpenVPN Server CA #1″) is selected here.
    Server Certificate – Ensure that the certificate you imported under System->Cert Manager->Certificates (e.g., “OpenVPN Server Cert #1″) is selected here.
    Encryption algorithm – This is the cipher that OpenVPN will use to secure your VPN traffic. The default cipher, AES, using 128-bit Cipher Block Chaining – AES-128-CBC (128-bit), will work just fine for most cases.
    Tunnel Network – This is the subnet from which the OpenVPN server will assign IP addresses. The server will automatically assign the first host address from this subnet to itself, while the remaining host addresses will be used for remote VPN clients. Our example VPN network will use subnet 192.168.20.0/24 so enter that here.
    Local Network – This is the subnet that will be accessable from through the VPN; in other words, your home network’s subnet. Our example home network has the subnet 192.168.10.0/24 so enter that here.
    Compression – This parameter is optional but selecting it will result in compressing the traffic transversing your VPN connection, making more efficient use of your available bandwidth. The drawback to using it is that it may increase slightly the CPU utilization for both the pfSense box and the OpenVPN client.
    Address Pool – This check box must be selected so that the OpenVPN server will assign addresses from the tunnel network to your OpenVPN clients.
    In addition to the parameters above, there are several others you might be interested in depending upon your specific requirements. These are optional, but may help improve your OpenVPN experience:
    DNS Default Domain – This specifies a domain name to be assigned to your VPN clients. You should enter the same domain name you entered in the “Domain” field under System -> General Setup.
    DNS Servers – Selecting this check box will allow you to specify the DNS server(s) to be used by the OpenVPN clients while connected. If you’re using pfSense as your DNS forwarder, then enter the pfSense LAN IP address here, else enter the IP address(s) of the DNS servers you entered in the “DNS servers” fields under System -> General Setup.
    NetBIOS Options – If you need Microsoft’s NetBIOS protocol, then selecting this will ensure it is propogated over your VPN connection.
    NTP Servers – Selecting this check box will allow you to specify the NTP server(s) to be used by the OpenVPN clients while connected.
    When you’re finished making changes, select “Save” at the bottom of the page to complete the configuration.
    Next, we’ll need to create a new firewall rule under Firewall -> Rules that will allow our incoming VPN connection on the WAN interface to pass through to the OpenVPN server on the port it’s listening on. Select the “+” icon and define following parameters:
    Action: Pass
    Interface: WAN
    Protocol: UDP
    Destination: WAN address
    Destination port range: 13725
    Description: OpenVPN
    When you’re finished making changes, select “Save” at the bottom of the page.
      OpenVPN client configuration in Windows for X.509 PKI authentication
    To configure your Windows OpenVPN client for X.509 PKI authentication, copy the client certificate and key, as well as the CA certificate from c:\Program Files (x86)\OpenVPN\easy-rsa\keys\ to c:\Program Files (x86)\OpenVPN\config\. You’ll recall these files are bob.crt, bob.key, and ca.crt. Next, we need to create an client configuration file so our OpenVPN client knows how to connect to the server. Fortunately, OpenVPN includes a sample configuration file so we don’t have to create one from scratch. Copy the file c:\Program Files (x86)\OpenVPN\sample-config\client.ovpn to c:\Program Files (x86)\OpenVPN\config\. You can rename the file if desired, however, make sure to retain the *.ovpn extension. Open this file in your text editor and modify the remote line so that it specifies either the FQDN (“Fully Qualified Domain Name”) or WAN IP address of your pfSense box, followed by the port number the OpenVPN server is listening on, which in our case is port 13725. The remaining configuration parameters can retain their defaults:
    # The hostname/IP and port of the server.
    # You can have multiple remote entries
    # to load balance between the servers.
    remote <the-FQDN-or-WAN-IP-address-of-your-pfSense-box> 13725
    We need to modify the cert and key lines so they point to our certificate and key file names:
    # SSL/TLS parms.
    # See the server config file for more
    # description.  It's best to use
    # a separate .crt/.key file pair
    # for each client.  A single ca
    # file can be used for all clients.
    ca ca.crt
    cert bob.crt
    key bob.key
    We also need to tell the client which cipher to use. This should match the one configured in the OpenVPN server. Assuming you retained the default AES-128-CBC cipher there then uncomment the cipher line and modify it so that it looks like the following:
    # Select a cryptographic cipher.
    # If the cipher option is used on the server
    # then you must also specify it here.
    cipher AES-128-CBC
    Now we’re ready to make our first OpenVPN connection. First, if you’re using Window’s firewall, make sure it is configured to allow VPN traffic to pass to/from the TAP-Win32 adapter installed by OpenVPN. Now, open the Windows Start menu and select “OpenVPN,” then “OpenVPN GUI.” The OpenVPN GUI will launch and automatically minimize to the task tray. Right-click on the icon and select connect. If you elected to use a password to protect the client private key, then you be asked to enter that password before OpenVPN will proceed with the connection (See Figure 3). After the OpenVPN client connects with the server in pfSense, the GUI will once again minimize to the task tray. Now try to ping the IP address of a host on the home network’s subnet. If the ping succeeds, congratulations! You’re now securily connected through your pfSense box to your home network using OpenVPN and X509 PKI authentication.
    Screenshot of OpenVPN GUI launching VPN connection with password field
    Figure 3
    By the way, there are several other ways you can start your OpenVPN connection in Windows. You can simply right click on an OpenVPN configuration file and selecting “Start OpenVPN on this config file.” You can start it by using the command openvpn at a command prompt – you’ll need to be in the folder c:\Program Files (x86)\OpenVPN\config for this to work, else make the appropriate adjustments to your PATH environmental variable (The F4 key will terminate the connection). Finally, you can run OpenVPN as a service so that it will start automatically at system boot time. To do this, click Window’s “Start” button and issue the command services.msc in the search box to bring up the list of Windows services. Navigate to the OpenVPN service and right-click on it. Select “Properties” and change the “Startup type” to “Automatic.”
      OpenVPN client configuration in Linux for X.509 PKI authentication
    To configure your Linux OpenVPN client in Linux for X.509 PKI authentication, copy the client certificate and key files, as well as the CA certificate from /etc/openvpn/easy-rsa/keys/ to /etc/openvpn/. You’ll recall these files are bob.crt, bob.key, and ca.crt. Next, we need to create a client configuration file so our OpenVPN client knows how to connect to the server. Fortunately, OpenVPN for Linux includes a sample configuration file so we don’t have to create one from scratch. Copy the file /usr/share/doc/openvpn/examples/sample-config-files/client.conf to /etc/openvpn/. You can rename the file if desired, however, make sure to retain the *.conf extension. Now open this file in your text editor and make the same changes as descibed above for the OpenVPN client configuration file in Windows. Remember to save your changes. Now we’re ready to make our first VPN connection. Open a terminal and use the following commands, replacing client.conf with the name of your configuration file if you changed it:
    cd /etc/openvpn/
    sudo openvpn client.conf
    If you elected to use a password to protect the client private key, then you’ll be asked to enter that password before OpenVPN will proceed with the connection, which will end with a “Initialization Sequence Completed” message. Now, open another terminal, and try to ping the IP address of a host on the home network’s subnet. If the ping succeeds, congratulations! You’re now securily connected through your pfSense box to your home network using OpenVPN and X509 PKI authentication.
    To simplify troubleshooting, it’s best to initially start the OpenVPN client from the command line as described above. However, once you know it can reliably connect to the server, then you can start it as a daemon as follows:
    sudo /etc/init.d/openvpn start
    When executed, OpenVPN will scan for any configuration files (i.e. *.conf) in /etc/openvpn/, and will attempt to start a separate daemon for each one it finds.
    Configuring OpenVPN: Pre-shared Private Key Authentication
    Having previously gone through the steps necessary to configure the OpenVPN server and clients for VPN access into our home network using the X.509 PKI authentication method, it’s time now to discuss how to configure these same components for VPN access using pre-shared private key authentication. Once again, to help explain the steps involved, we’ll assume there is an existing home network that is currently using the IP subnet 192.168.10.0/24; we’ll use the subnet 192.168.20.0/24 for our VPN; and, we’ll designate UDP port 13725 as the port the OpenVPN server will listen on (See Figure 1).
      OpenVPN server configuration in pfSense for pre-shared private key authentication
    Log into your pfSense box’s “webConfigurator” interface and navigate to VPN->OpenVPN->Server then click on the “+” icon to add a new OpenVPN server (See Figure 2). Most of the options will be left at their default settings, however the following will need to be configured:
    Server Mode – We’re using the pre-shared private key authentication method in this example so we should select “Peer to Peer (Shared Key)” here.
    Local port – This is the logical port that the OpenVPN server will listen on for VPN connections. To help improve security, we’ll avoid using OpenVPN’s default port 1194 and use port 13725 instead.
    Description – Enter a description here for your reference. This field is optional but helpful.
    Shared Key – Uncheck the “Automatically generate a shared key” box and then carefully and securely copy the contents of the static-bob.key file from the machine you generated it and paste it into the provided field.
    Encryption algorithm – This is the cipher that OpenVPN will use to secure your VPN traffic. The default cipher, AES, using 128-bit Cipher Block Chaining – (AES-128-CBC (128-bit), will work just fine for most cases.
    Tunnel Network – This is the subnet from which the OpenVPN server will assign IP addresses. The server will automatically assign the first host address from this subnet to itself, while the remaining host addresses will be used for remote VPN clients. Our example VPN network will use subnet 192.168.20.0/24 so enter that here.
    Local Network – This is the subnet that will be accessable from through the VPN; in other words, your home network’s subnet. Our example home network has the subnet 192.168.10.0/24 so enter that here.
    Compression – This parameter is optional but selecting it will result in compressing the traffic transversing your VPN connection, making more efficient use of your available bandwidth. The drawback to using it is that it may increase slightly the CPU utilization for both the pfSense box and the OpenVPN client.
    When you’re finished making changes, select “Save” at the bottom of the page to complete the configuration.
    Next, we’ll need to create a new firewall rule under Firewall -> Rules that will allow our incoming VPN connection on the WAN interface to pass through to the OpenVPN server on the port it’s listening on. Select the “+” icon and define following parameters:
    Action: Pass
    Interface: WAN
    Protocol: UDP
    Destination: WAN address
    Destination port range: 13725
    Description: OpenVPN
    When you’re finished making changes, select “Save” at the bottom of the page.
      OpenVPN client configuration in Windows for pre-shared private key authentication
    To configure your Windows client for pre-shared private key authentication, copy the key file static-bob.key from c:\Program Files (x86)\OpenVPN\easy-rsa\keys\ to c:\Program Files (x86)\OpenVPN\config\. Now we need to create an client configuration file so our OpenVPN client knows how to connect to the server. Since OpenVPN for Windows doesn’t include a sample client configuration file for the pre-shared private key authentication method, we’ll use the following, which is based on the sample client configuration file included with the OpenVPN installation in Linux. Copy and paste this text into your text editor and modify the remote line so that it specifies either the FQDN (“Fully Qualified Domain Name”) or WAN IP address of the pfSense box, followed by the port number the OpenVPN server is listening on, which in our example case is port 13725. The secret line specifies the name of our static key file, which in our case is static-bob.key. Save the file as client.ovpn and copy it to c:\Program Files (x86)\OpenVPN\config\. You can rename the file if desired, however, make sure to retain the *.ovpn extension:
    1### README
    2#
    3# Date:
    4# Description: Client configuration for shared private key authentication
    5# Author:
    6# Process(s): openvpn
    7# Configuration:
    8#
    9### START OF CONFIGURATION
    10 
    11# Use a dynamic tun device.
    12# For Linux 2.2 or non-Linux OSes,
    13# you may want to use an explicit
    14# unit number such as "tun1".
    15# OpenVPN also supports virtual
    16# ethernet "tap" devices.
    17;dev tap
    18dev tun
    19 
    20# Our OpenVPN peer is the OpenVPN server in our pfSense box.
    21remote <the-FQDN-or-WAN-IP-address-of-your-pfSense-box> 13725
    22 
    23# 192.168.20.1 will be our OpenVPN server endpoint.
    24# 192.168.20.2 will be our local OpenVPN endpoint.
    25ifconfig 192.168.20.2 192.168.20.1
    26 
    27# The route to our local network
    28route 192.168.10.0 255.255.255.0
    29 
    30# Add a route to our home network subnet
    31route 192.168.10.0 255.255.255.0
    32 
    33# Our pre-shared private key.
    34secret static-bob.key
    35 
    36# If you used LZO compression on the OpenVPN server,
    37# uncomment out the following line.
    38comp-lzo
    39 
    40# Select a cryptographic cipher. The default is AES-128-CBC.
    41# If the cipher option is used on the server
    42# then you must also specify the same one here.
    43cipher AES-128-CBC
    44 
    45# Send a UDP ping to the OpenVPN server once
    46# every 15 seconds to keep
    47# stateful firewall connection
    48# alive.
    49ping 15
    50 
    51# Uncomment these for more reliable detection when a system.
    52# loses its connection.  For example, dial-ups or laptops that
    53# travel to other locations.
    54persist-tun
    55persist-key
    56 
    57# Verbosity level.
    58# 0 -- quiet except for fatal errors.
    59# 1 -- mostly quiet, but display non-fatal network errors.
    60# 3 -- medium output, good for normal operation.
    61# 9 -- verbose, good for troubleshooting
    62verb 3
    If you would like to specify a domain name to be assigned to your VPN client, add the following line to your client configuration file. You should enter the same domain name you entered in the “Domain” field under System -> General Setup.
    dhcp-option DOMAIN <em>your-domain-name>
    If you would like to specify the DNS server(s) to be used by your OpenVPN client while connected, add the following line to your client configuration file. If you’re using pfSense as your DNS forwarder, then specify the pfSense LAN IP address here, else specify the IP address(s) of the DNS servers you entered in the “DNS servers” fields under System -> General Setup.
    dhcp-option DNS <your-DNS-IP-address>
    Now we’re ready to make our OpenVPN connection. First, if you’re using Window’s firewall, make sure it is configured to allow VPN traffic to pass to/from the TAP-Win32 adapter installed by OpenVPN. Now, open the Windows Start menu and select “OpenVPN,” then “OpenVPN GUI.” The OpenVPN GUI will launch and automatically minimize to the task tray. Right-click on the icon and select connect. After the OpenVPN client connects with the server in pfSense, the GUI will once again minimize to the task tray. Now try to ping the IP address of a host on the home network’s subnet. If the ping succeeds, congratulations! You’re now securily connected through your pfSense box to your home network using OpenVPN and pre-shared private key authentication.
      OpenVPN client configuration in Linux for pre-shared private key authentication
    To configure your Linux OpenVPN client in Linux for pre-shared private key authentication, copy the key file static-bob.key from /etc/openvpn/easy-rsa/keys/ to /etc/openvpn/. Then, copy the sample configuration file discussed above in the Windows section to /etc/openvpn/ (Alternatively you can use the sample configuration file included with OpenVPN for Linux. See /usr/share/doc/openvpn/examples/sample-config-files/static-home.conf). You can rename the file if desired, however, make sure to retain the *.conf extension. Now, open the file in your text editor and make the appropriate changes to the remote and secret lines as discussed above for the Windows configuration file. Remember to save your work.
    Now we’re ready to make our VPN connection. Open a terminal and use the following commands, replacing client.conf with the name of your config file if you changed it:
    cd /etc/openvpn/
    sudo openvpn client.conf
    To simplify troubleshooting, it’s best to initially start the OpenVPN client from the command line as described above. However, once you know it can reliably connect to the server, then you can start it as a daemon as follows:
    sudo /etc/init.d/openvpn start
    Now, open another terminal, and try to ping the IP address of a host on the home network’s subnet. If the ping succeeds, congratulations! You’re now securily connected through your pfSense box to your home network using OpenVPN and pre-shared private key authentication.
    Conclusion
    This concludes the post on how to configure secure remote access to your home network using pfSense and OpenVPN. Two methods are typically used by OpenVPN to authenticate the server and remote clients to one another: X.509 PKI or pre-shared private keys. The X.509 PKI method offers scalability and arguably better security, but may be overkill for those that want single-user VPN access to their home network. Conversly, the pre-shared key method does not scale well beyond one or two users, but is easier to setup and likely just fine for a small network with a limited number of remote VPN clients. For a full list of all the configuration options and other information I encourage you to visit the OpenVPN community software web site.

    No comments:

    Post a Comment