Using a Comodo Free Email Cert In macOS Sierra

Comodo offer free email certificates, which is awesome as email is an inherently insecure method of communication. So, if you were toying with the idea of playing around with email encryption and signing, you have no more excuses now.

Getting the free cert to work on macOS, however, might be tricky if you don’t pay attention to a couple of things. Here are the pitfalls I have encountered in the process and how I was able to fix them.

Continue reading

How To Solve ‘error 3 at 0 depth lookup:unable to get certificate CRL’ When Revoking Certificates In OpenVPN

If you are trying to revoke an OpenVPN certificate by using the revoke-full command from within your easy-rsa directory, you might stumble upon the following error message:

error 3 at 0 depth lookup:unable to get certificate CRL

The full standard output from the revoke-full command would look like this:

Continue reading

Build a VPN Server Using a Raspberry Pi – The Paranoid Version

If you have landed on this post, you have probably already stumbled upon ReadWrite’s post Building A Raspberry Pi VPN Part One: How And Why To Build A Server (and the following Part Two). Both of them are based on the excellent SANS article SOHO Remote Access VPN. Easy as Pie, Raspberry Pi… which I recommend you read in its entirety, being a very informative read even if you don’t focus on the technical details of how to configure a VPN server.

However, I found that both of these sources were missing some details which, in my opinion, would have made them even better. While following these guide, I added some notes of my own for future reference, so I really had 3 goals in mind when I decided to write this post expanding on the previously mentioned resources:

  • Clarify the most confusing steps in the process of configuring an OpenVPN server
  • Add some instructions on how to include some basic OS-hardening (if you have to go through the hassle of setting up a VPN server, presumably for security reasons, I think you should do it right)
  • Increase the security of the OpenVPN server using bigger keys, for the most paranoid out there (it’s an interesting exercise even if you don’t really need the extra level of security).

I am going to skip the detailed instructions on how to prepare the SD card and how to boot into Raspbian for the first time. I am just going to recommend Win32DiskImager to do this if you are on Windows:

OS configuration and OpenVPN installation

  1. After booting into Raspbian, you can login with the default credentials:
    • Username: pi
    • Password: raspberry
  2. Refresh your repositories so you can download the latest version of the packages we are going to use:
    sudo apt-get update
  3. Run
    sudo apt-get upgrade

    to effectively upgrade your system packages

  4. Finally, run
    sudo rpi-update

    to update your Pi’s firmware (it’s important to leave this action for last in this update process so that the latest version of rpi-update will be downloaded)

  5. At the end of the process you should see a message prompting you to reboot. Go ahead and run a
    sudo reboot

    to proceed.

  6. Let’s change the hostname of the Pi from the default to something like “vpnserver”. To do this successfully, you have to update the hostname in the following two locations:
    • /etc/hostname
    • /etc/hosts
  7. Let’s create a new user for this Raspberry, as using the default user pi would leave brute force and dictionary attacks a higher chance of success. For this guide, I am going to use the name “vpn”:
  8. sudo adduser vpn
  9. Fill in the information:
  10. Add this user to the sudoers file (i.e. the users allowed to gain root privileges):
    sudo visudo
  11. Look for the line beginning with
    #includedir /etc/sudoers.d

    and add this line:

    vpn ALL=(ALL) ALL

    . Using ALL rather than the nopassword that the default user pi is using increases security by a factor of more than a billion billions.

  12. Reboot so we can login with the newly created user:
    sudo reboot
  13. Run
    sudo userdel -r pi

    to delete the default user pi

  14. Check that the command has been successful running
    cut -d: -f1 /etc/passwd
  15. Now it’s time to install OpenVPN:
    sudo apt-get install openvpn

Configuring the PKI

We will be using OpenVPN with certificate authentication, which is way more secure than plain password authentication. Every device will be issued a certificate that it will have to use to successfully connect to the OpenVPN server. To do so, however, we need to have a PKI in place to issue and validate certificates.

Server configuration

  1. Go root for a while now, since everything we will be doing now requires root privileges:
    sudo -s
  2. Create a folder for easy RSA to store all the certificate information:
    mkdir /etc/openvpn/easy-rsa
  3. Copy the included configuration example to the newly created folder so we have a template to start from:
    cp /usr/share/doc/openvpn/examples/easy-rsa/2.0/* /etc/openvpn/easy-rsa
  4. Move to the newly created folder:
    cd /etc/openvpn/easy-rsa
  5. Open the vars file
    nano vars

    and paste the following content:

    # easy-rsa parameter settings
    # NOTE: If you installed from an RPM,
    # don't edit this file in place in
    # /usr/share/openvpn/easy-rsa --
    # instead, you should copy the whole
    # easy-rsa directory to another location
    # (such as /etc/openvpn) so that your
    # edits will not be wiped out by a future
    # OpenVPN package upgrade.
    # This variable should point to
    # the top level of the easy-rsa
    # tree.
    export EASY_RSA="/etc/openvpn/easy-rsa"
    # This variable should point to
    # the requested executables
    export OPENSSL="openssl"
    export PKCS11TOOL="pkcs11-tool"
    export GREP="grep"
    # This variable should point to
    # the openssl.cnf file included
    # with easy-rsa.
    export KEY_CONFIG=`$EASY_RSA/whichopensslcnf $EASY_RSA`
    # Edit this variable to point to
    # your soon-to-be-created key
    # directory.
    # WARNING: clean-all will do
    # a rm -rf on this directory
    # so make sure you define
    # it correctly!
    export KEY_DIR="$EASY_RSA/keys"
    # Issue rm -rf warning
    echo NOTE: If you run ./clean-all, I will be doing a rm -rf on $KEY_DIR
    # PKCS11 fixes
    export PKCS11_MODULE_PATH="dummy"
    export PKCS11_PIN="dummy"
    # Increase this to 2048 if you
    # are paranoid.  This will slow
    # down TLS negotiation performance
    # as well as the one-time DH parms
    # generation process.
    export KEY_SIZE=2048
    # In how many days should the root CA key expire?
    export CA_EXPIRE=3650
    # In how many days should certificates expire?
    export KEY_EXPIRE=3650
    # These are the default values for fields
    # which will be placed in the certificate.
    # Don't leave any of these fields blank.
    export KEY_COUNTRY="CO"
    export KEY_PROVINCE="Province"
    export KEY_CITY="City"
    export KEY_ORG=changeme
    export KEY_EMAIL="me@myhost.mydomain"
    export KEY_EMAIL=mail@host.domain
    export KEY_CN=changeme
    export KEY_NAME=changeme
    export KEY_OU=changeme
    export PKCS11_MODULE_PATH=changeme
    export PKCS11_PIN=1234

    Feel free to customize this of course, but the most important settings here are the key size (the comments say to “Increase this to 2048 if you are paranoid”, so we have done so) and the CA lifetime, 3650 days in this case.

  6. You should still be in the easy-rsa folder, if not, cd to it
  7. Run
    source ./vars
  8. Run
  9. Run


  10. Fill in all the fields
  11. Build the server key pair (private key and public key):
    ./build-key-server vpnserver
    • The common name must match the server name, but by default it should prompt you to use the same name
    • Leave the challenge password blank
    • Answer yes when prompted to “sign cert?”
    • Answer yes when prompted to “commit?”

Client configuration

It’s now time to generate client certificates. This procedure will need to be followed for every end device that you plan to use with OpenVPN.

  1. Run
    ./build-key-pass UserName
    • pem passphrase: your passwords. This protects the private key with a password, to be entered every time you connect to the server
    • Leave the challenge password blank
    • Answer yes when prompted to “sign cert?”
    • Answer yes when prompted to “commit?”
  2. Run
    cd keys
    openssl rsa -in UserName.key -des3 -out UserName.3des.key
    • This step is necessary if you are going to use the Android or iOS versions of OpenVPN
    • Don’t get confused by 3DES: it’s much better than DES. It theoretically uses a 56*3 bit key but due to a meet-in-the-middle attack it is equivalent to a cypher suite using a 112-bit key (still much better than standard DES)
    • Enter the passphrase you chose before

Generate Diffie-Hellman parameters

It’s time to generate Diffie-Hellman parameters now for secure key exchange. Keep in mind that, using 2048 bit keys on a machine like a Raspberry Pi, this can take quite a long time (it took a bit less than two hours on my machine).

  1. Run
    cd /etc/openvpn/easy-rsa/


OpenVPN Server Configuration

It’s finally time to tweak the server configuration now.

  1. Run
    openvpn --genkey --secret keys/ta.key

    This will provide DoS protection: each client will have to use this value during the initial handshake, otherwise the connection will be dropped

  2. Run
    nano /etc/openvpn/server.conf

    and paste the following configuration file:

    topology subnet
    dev tun
    proto udp
    port 1194
    ca /etc/openvpn/easy-rsa/keys/ca.crt
    cert /etc/openvpn/easy-rsa/keys/vpnserver.crt # SWAP WITH YOUR CRT NAME
    key /etc/openvpn/easy-rsa/keys/vpnserver.key # SWAP WITH YOUR KEY NAME
    dh /etc/openvpn/easy-rsa/keys/dh2048.pem
    # server and remote endpoints
    # Add route to Client routing table for the OpenVPN Server
    push "route"
    # Add route to Client routing table for the OpenVPN Subnet
    push "route"
    # your local subnet
    # Set primary domain name server
    # Override the Client default gateway by using and
    # rather than This has the benefit of
    # overriding but not wiping out the original default gateway.
    push "redirect-gateway def1"
    keepalive 10 120
    tls-auth /etc/openvpn/easy-rsa/keys/ta.key 0
    cipher AES-128-CBC
    user nobody
    group nogroup
    status /var/log/openvpn-status.log 20
    log /var/log/openvpn.log
    verb 1
  3. Run
    nano /etc/sysctl.conf

    and paste the following content to enable IP forwarding:

    # /etc/sysctl.conf - Configuration file for setting system variables
    # See /etc/sysctl.d/ for additional system variables
    # See sysctl.conf (5) for information.
    #kernel.domainname = example.com
    # Uncomment the following to stop low-level messages on console
    #kernel.printk = 3 4 1 3
    # Functions previously found in netbase
    # Uncomment the next two lines to enable Spoof protection (reverse-path filter)
    # Turn on Source Address Verification in all interfaces to
    # prevent some spoofing attacks
    # Uncomment the next line to enable TCP/IP SYN cookies
    # See http://lwn.net/Articles/277146/
    # Note: This may impact IPv6 TCP sessions too
    # Uncomment the next line to enable packet forwarding for IPv4
    # Uncomment the next line to enable packet forwarding for IPv6
    #  Enabling this option disables Stateless Address Autoconfiguration
    #  based on Router Advertisements for this host
    # Additional settings - these settings can improve the network
    # security of the host and prevent against some network attacks
    # including spoofing attacks and man in the middle attacks through
    # redirection. Some network environments, however, require that these
    # settings are disabled so review and enable them as needed.
    # Do not accept ICMP redirects (prevent MITM attacks)
    #net.ipv4.conf.all.accept_redirects = 0
    #net.ipv6.conf.all.accept_redirects = 0
    # _or_
    # Accept ICMP redirects only for gateways listed in our default
    # gateway list (enabled by default)
    # net.ipv4.conf.all.secure_redirects = 1
    # Do not send ICMP redirects (we are not a router)
    #net.ipv4.conf.all.send_redirects = 0
    # Do not accept IP source route packets (we are not a router)
    #net.ipv4.conf.all.accept_source_route = 0
    #net.ipv6.conf.all.accept_source_route = 0
    # Log Martian Packets
    #net.ipv4.conf.all.log_martians = 1
  4. Apply the change running
    sysctl -p
  5. Enable NAT between the VPN subnet and your home subnet using iptables:
    nano /etc/openvpn_firewall_rules.sh

    and paste this:

    iptables -t nat -A POSTROUTING -s -o eth0 -j SNAT --to-source
  6. Run
    chmod 700 /etc/openvpn_firewall_rules.sh
  7. Run
    chown root /etc/openvpn_firewall_rules.sh
  8. Let’s enable this firewall route every time the network interface comes up:
    nano /etc/network/interfaces

    and check that your configuration file looks similar to this:

    # This file describes the network interfaces available on your system
    # and how to activate them. For more information, see interfaces(5).
    # The loopback network interface
    auto lo
    iface lo inet loopback
    # The primary network interface
    auto eth0
    iface eth0 inet static
    pre-up /etc/openvpn_firewall_rules.sh
  9. Run
  10. Run
    sudo -s
  11. Let’s create a default configuration that will be applied to every OpenVPN client:
    nano /etc/openvpn/easy-rsa/keys/Default.txt

    (the file must be called Default.txt unless you modify the MakeOVPN.sh script later) and paste the following:

    dev tun
    proto udp
    remote  1194
    resolv-retry infinite
    ns-cert-type server
    key-direction 1
    cipher AES-128-CBC
    verb 1
    mute 20
  12. Run
    nano /etc/openvpn/easy-rsa/keys/MakeOVPN.sh

    and paste this:

    # Default Variable Declarations
    #Ask for a Client name
    echo "Please enter an existing Client Name:"
    read NAME
    #1st Verify that client’s Public Key Exists
    if [ ! -f $NAME$CRT ]; then
    echo "[ERROR]: Client Public Key Certificate not found: $NAME$CRT"
    echo "Client’s cert found: $NAME$CR"
    #Then, verify that there is a private key for that client
    if [ ! -f $NAME$KEY ]; then
    echo "[ERROR]: Client 3des Private Key not found: $NAME$KEY"
    echo "Client’s Private Key found: $NAME$KEY"
    #Confirm the CA public key exists
    if [ ! -f $CA ]; then
    echo "[ERROR]: CA Public Key not found: $CA"
    echo "CA public Key found: $CA"
    #Confirm the tls-auth ta key file exists
    if [ ! -f $TA ]; then
    echo "[ERROR]: tls-auth Key not found: $TA"
    echo "tls-auth Private Key found: $TA"
    #Ready to make a new .opvn file - Start by populating with the
    default file
    #Now, append the CA Public Cert
    echo "" >> $NAME$FILEEXT
    cat $CA >> $NAME$FILEEXT
    echo "" >> $NAME$FILEEXT
    #Next append the client Public Cert
    echo "" >> $NAME$FILEEXT
    echo "" >> $NAME$FILEEXT
    #Then, append the client Private Key
    echo "" >> $NAME$FILEEXT
    echo "" >> $NAME$FILEEXT
    #Finally, append the TA Private Key
    echo "" >> $NAME$FILEEXT
    cat $TA >> $NAME$FILEEXT
    echo "" >> $NAME$FILEEXT
    echo "Done! $NAME$FILEEXT Successfully Created."
    #Script written by Eric Jodoin
    \ No newline at end of file

Generate OpenVPN configuration files

We finally arrived at the last step of the process: using the certificates we created in the previous steps, we can now generate the OpenVPN configuration files that end devices are going to use to connect to your VPN server.

  1. Run
    cd /etc/openvpn/easy-rsa/keys/
  2. Run
    chmod 700 MakeOVPN.sh
  3. Run

    to create the .ovpn configuration file

  4. Download the configuration file to the end device (you might need to temporarily change the permissions of the /etc/openvpn folder from 600 to 700 to do so)

© 2018 Daniel's TechBlog

Theme by Anders NorénUp ↑

%d bloggers like this: