Synology - calDAV Setup

Setting up calendars on Synology. I am using the WebDAV package. This package includes calDAV. I cannot use the Calendar package on my old Synology NAS. I think it is time to buy a new NAS.


Please follow the documents below. Feel free to create a new unique SSL certificate for use with calendar. This new SSL certificate will be used for WebDAV and CalDAV. Or you may use the same SSL certificate you use for other services.

  1. Securing Synology NAS
  2. Synology - Map Domain with DDNS
  3. Synology - Setup Let's Encrypt SSL Certificates

Not Using the Calendar Package

I am not using the calendar package from Synology. It isn't supported on my old NAS. But the basics of using calendars on Synology should be the same. I am using calDAV from the WebDAV package.

Basic Setup

My post on setting up WebDAV covers the basics of installing this package. Once that is done, open the WebDAV server application from the main menu. Next click on the 'Calendar' tab. Then 'click' Enable CalDAV and click 'Apply'. See the picture below.

Enable CalDAV
Enable CalDAV

Secure Setup

I will create two groups for calendar access. One will have Read/Write access and the other will only have Read Only access. I will create a shared folder for holding all my calendars that has limited access.

NOTE: The read only access will be used to allow users to access one or more calendars but not allow them to edit the calendar. This is useful if you want to publish a schedule. This is not necessary for most home users.

Shared Folder

First create a shared folder. I will name it 'caldav'. Next create the two new groups described in the next section. Then come back and verify the group permissions for the 'caldav' shared folder.

CalDAV Shared Folder Group Permissions
CalDAV Shared Folder Group Permissions

Create Two New Groups

Create the following two new groups.

  1. caldavRW
  2. caldavRO

The settings are shown below. For the RW group make 'caldav' folder writeable. For the RO group make the 'caldav' folder read only.

CalDAV RW Group Settings
CalDAV RW Group Settings

Create Two New Users

Now create two new users. One user will have read write access. The other user will only have read only access. Make sure you can log into DSM with each user. I am creating the following two users.

  1. cally (RO)
  2. kalel (RW)

The goal is to limit access for each ID to just the 'caldav' shared folder. See the permissions below.RW Calender User Permissions

RW Calender User Permissions

Create a Calendar

I will use Mozilla Thunderbird to create a calendar. But any calendar application should work as long as it supports CalDAV. When you create a new calendar a new folder will be created in the 'caldav' shared folder. I will create 2 calendars. One will be named 'calone' and the second will be named 'caltwo'. These directions assume you have used the default port of 5006. Feel free to change this port. If you use the calendar package from Synology the port will be different. My port is secured by SSL/TLS. Follow the steps below.

Create a New Calendar in WebDAV

First we need to create a new calendar in WebDAV. Launch the WebDAV application from the Synology main menu. Go to the calendar tab. Click 'View calendar list' and then click 'Add'.  Provide a calendar name and select 'caldav' as the destination. See the screen shot below.

Add a New Calendar in WebDAV
Add a New Calendar in WebDAV

When you create 'calone' and 'caltwo' you will have two new folders named 'calone' and 'caltwo' under 'caldav'. Each folder will have the hidden folder '.DAV'. I will publish a new calendar into each directory.

Thunderbird Steps

  • Install Mozilla Thunderbird and launch it
  • Go to "File // New // Calendar" - Choose the following options
    • Locate your calendar = "On the Network"
      • Click Next
    • Format = CalDAV
    • Location =
    • Check "Offline Support"
      • Click Next
    • Name = Choose a descriptive name for you new calendar
      • calone
      • caltwo
    • Color = Choose a color for you new calendar
    • Show Reminders = keep checked
    • Email = none - feel free to add an email address
      • Click Next
    • Now provide your user name and password (RW ID)
    • Click Finish

Repeat these steps for 'caltwo' and any other future calendars.

Publish a New Calendar

  • From Mozilla Thunderbird go to "Events and Tasks // Publish"
  • Choose your calendar and click 'OK'
  • Publishing URLs for 'calone' and 'caltwo'

CalDAV Clients

Now use your favorite CalDAV client and use the URL below to synchronize with your newly created calendar. Use the RW or RO user ID for access.


Synology OpenVPN Setup

Configuring a secure OpenVPN implementation on Synology NAS devices


Secure your Synology NAS before enabling internet access. Follow this document before proceeding.

You need to setup dynamic DNS in order to access your WAN IP from the public internet. Most people have DHCP from the ISP. As a result the WAN IP address may change from time to time. There are numerous free and paid dynamic DNS services available. Feel free to pick anything you desire. You can setup dynamic DNS on most home routers. You can also setup dynamic DNS on the Synology NAS as well.

You don't need your own domain to use OpenVPN. Nor do you need a Let's Encrypt certificate. It is best to create your own CA (Certificate Authority) and sign your own certificates. The setup of the root CA is described in detail below.

Setup port forwarding on your home router. The default port for OpenVPN is 1194/UDP. But you can choose any port and change the protocol as well. Every router has a different interface. Use for instructions if needed. Do not buy there little tool. Port forwarding is quite simple to setup. It is recommended to setup a DHCP reservation or use a static IP address for your Synology NAS device. Setting up either option varies from device to device and is beyond the scope of this document.

Official Documentation

The user should always read the official documentation first. This document is based on the official documents plus a few other websites. The official documents will help explain in detail all of the various settings.

For the root CA (certificate authority) I mainly used the directions from the Feisty Duck SSL cookbook. I also borrowed from a few different websites. The openssl.cnf file has tons of options. And there are probably better ways to configure it. I previously created my own CA on my DD-WRT router. This setup is a bit better. And I suspect if I do this in the future I will learn a bit more then. The OpenVPN setup has also improved over my DD-WRT setup. I used a few websites to help setup OpenVPN.

  1. Deprecated OpenVPN Commands - Some of my options will be deprecated in the near future. But for now Synology is running version 2.3.x.
  2. Hardening OpenVPN - I took some of these suggestions.
  3. Another hardening guide
  4. A third hardening guide

High Level Overview

This is a very long document. But the steps are not hard. I found a new WordPress plugin that will allow for tabs. That will make long documents like this a lot more usable.

I created a script to help setup the root-ca and make it easier. And to make it more consistent. The script follows the high level procedures below. More information about the script can be found at the bottom of this document.

Transfer SYNO-OVPN.tar.gz to your NAS. This file has my script and a few configuration files. And it includes a nice little README file.

  1. Install the Synology OpenVPN package
  2. Configure the Synology OpenVPN package
  3. Test the Synology OpenVPN package before making any manual changes.

Now use the script or follow the manual directions to build your own root CA and to secure OpenVPN. Extract the files in /tmp or in /root. It will make a sub-directory name 'SYNO-OVPN'.

Now edit the files and update the variables for your environment. Use the included README for instructions on what to edit. Then run './syno-ovpn.ash build) to setup the basic directory structure and copy over a few configuration files.

  1. Setup the directory structure for the Root CA (./syno-ovpn.ash BUILD)
    1. Setup /etc/ssl/root-ca and sub-directories
    2. Copy the key files
  2. Switch to /etc/ssl/root-ca. Double check the configuration files and finish editing them if required. The script renamed some of the files when it copied them to the new directory.
    1. /etc/ssl/root-ca/openssl.conf
    2. /usr/syno/etc/packages/VPNCenter/openvpn/openvpn.conf
    3. /etc/ssl/root-ca/ovpn/openvpn.client.ovpn
    4. /etc/ssl/root-ca/syno-ovpn.ash (Script mentioned above)
  3. Setup the Root CA (./syno-ovpn.ash root-ca)
  4. Setup the Diffie Hellman file (./syno-ovpn.ash DH)
  5. Add Users (./syno-ovpn.ash -f john -l doe add)
    1. This will create the CSR and private key for the user
    2. Sign the CSR and create the public key for the user
    3. Setup an OVPN file for the user
  6. The script will also make it easier to revoke client certificates
    (./syno-ovpn.ash -f john -l doe revoke)
  7. Overwrite the Synology openvpn.conf server configuration file with our more secure configuration.
  8. Manually add the new SSL/TLS certificates to the Synology GUI for the OpenVPN package
    1. server.key (server private key)
    2. server.crt (server public key)
    3. ca.crt (Root CA public key)

Install the OpenVPN Package

Synology has a VPN Server package. It has 3 VPN protocols.

  • PPTP = Point to Point Tunneling Protocol (Do not use. There are known security vulnerabilities.)
  • L2TP/IPSec - Layer 2 Tunneling Protocol with IPSec (Internet Protocol Security) - L2TP doesn't encrypt. Encryption is done by IPSec. There may be security issues with IPSec.
  • OpenVPN - Recommended - Very configurable and it is open source.

Go to the package center and install 'VPN Server'. Once it is installed go to the main menu and select VPN Server. There are very few native configuration options within this package. Click on the 'OpenVPN' tab and fill in the information as desired.

  • Check 'Enable OpenVPN Server'
  • Dynamic IP address = Pick any /24 private subnet you desire. In this example I am using
  • Maximum connection number = choose a number from the drop down box (5, 10, or 15)
  • Maximum number of connections with the same account - I changed this to '1' from the default value of '3'. By default the Synology OpenVPN uses ID and password. I plan to change this to certificate authentication for better security.
  • Port = 1194 (Default) - It is a good idea to change this to another port to reduce port scanning. Additional layers of security are always a good thing.
  • Protocol = UDP (Default) You can change this to TCP if you like. Some people use 443/TCP to help them connect through various firewalls. If possible use UDP.
  • Encryption = AES-256-CBC - Choose this or another encryption algorithm. NOTE: This cipher is being deprecated. Perhaps the next release of OpenVPN on Synology will have current ciphers.
  • Authentication = SHA512 - Do not use SHA1 anymore. SHA256 is probably more than enough. But I went for the highest HMAC.
  • Check "Enable compression on the VPN link"
  • [OPTIONAL] - Check "Allow clients to access server's LAN - Enable this if you want to SSH or RDP to other boxes on your home LAN.
  • [OPTIONAL] - Do not check - Enable IPv6 server mode. Most people are not using IPv6 at this time.
  • Click 'Apply'
OpenVPN Configuration Panel
OpenVPN Configuration Panel

Update the Synology Firewall

Based on the document 'Securing Synology NAS' mentioned above update your firewall to allow 1194/UDP. Or choose another port if desired.

Before changing anything else test out the basic configuration. Export your configuration from the OpenVPN GUI. Edit it with your dynamic DNS name. And install it on your phone or something else. Make sure everything works before proceeding.

Create Your Own CA

The default Synology OpenVPN setup uses ID and password for authentication. This is not recommended for several reasons. I am following the hardening guide from OpenVPN. At the time of this writing Synology is running OpenVPN v2.3.11 and OpenSSL v1.0.2n-fips. Two factor authentication is not an option with the Synology OpenVPN server at this time. It may be possible to compile the code yourself and update PAM.

NOTE: Once you manually update the configuration files you cannot hit 'apply' in the VPN Server configuration panel GUI. It will overwrite your settings. Make a backup of all your changes. It is possible that package updates may overwrite things as well.

Follow the steps below to configure your CA (Certificate Authority). The v1.0.2 MAN pages are here. And links to the main commands used are shown below with a brief explanation of each option.

GENRSA Man Page - genrsa - Generates an RSA private key.

CA Man Page - ca - This is a minimal CA application. It can be used to sign certificate requests (CSR) in a variety of forms and generate CRLs. It also maintains a text database of issued certificates and their status.

REQ Man Page - req - PKCS#10 certificate request and certificate generating utility. The req command primarily creates and processes certificate requests in PKCS#10 format. It can additionally create self signed certificates for use as a root CA.

X509 Man Page - x509 - A certificate display and signing utility. The x509 command is a multi purpose certificate utility. It can be used to display certificate information, convert certificates to various forms, sign certificate requests like a 'mini CA' or edit certificate trust settings.

Please note that in all of the commands below we must specify the updated openssl.conf file using the '-config' flag. We are not using the system default file.

1. Setup a New SSL Directory

Synology OpenSSL uses '/etc/ssl' as the default directory. (openssl version -d) I don't want to mess up any of the other items using SSL. So I will create a new openssl.conf file and directory structure for my CA. SSH to the Synology NAS and run the following commands as root or use sudo.

  • # Temporarily change the umask to ensure the newly created files and directories are secure
    • umask 0077
  • # Make a new directory for root-ca - /etc/ssl/root-ca
    • mkdir -m 0700 /etc/ssl/root-ca
  • # Change to that directory to lessen the amount of typeing
    • cd /etc/ssl/root-ca
  • # Make the sub-directories (certs - For PEM formatted certificates 'hash_of_name.pem' // db - For text based control files // private - For the private keys '*.key' // pub - For the public certificates '*.crt' // csr - For the certificate signing request '*.csr')
    • mkdir -m 0700 certs db private pub csr
  • # Optionally make a directory to hold the OpenVPN OVPN client configuration files for each user. Note, my script requires this directory.
    • mkdir -m 700 ovpn
  • # Each private key should be secured by a unique strong password. To help secure these files the directory is only available to 'root'.
    • chmod 0700 private
  • # Seed the '.rand' file. This file is used to help create entropy.
    • dd if=/dev/urandom of=/etc/ssl/root-ca/private/.rand bs=256 count=1
  • # For extra security we limit access to this file.
    • chmod 0600 /etc/ssl/root-ca/private/.rand
  • # Create the text based database file for openssl.
    • touch db/index
  • # Create a random unique string to start the count of each public key. Each public key gets the next number in the sequence.
    • openssl rand -hex 16 > db/serial
  • #The number with which to start a sequence of numbers to identify revoked certificates. Each one will get a unique number.
    • echo 1001 > db/crlnumber
  • # For security make sure everything is owned by root. On other systems it is best not to run this as root.
    • chown -R root:root /etc/ssl/root-ca

2. Create a New Openssl.conf (aka openssl.cnf)

Now we need to create a new openssl.conf file. The file should be owned by 'root:root' with permissions of 0600. Synology OpenSSL uses '/etc/ssl/openssl.cnf' as the configuration file. You can copy that file over, or use the file from the *.tar.gz file I provide. The script from the *.tar.gz file will copy over the initial file.

  • vi /etc/ssl/openvpn/openssl.conf

I am using the Feisty Duck site and PKI tutorials to help me configure the openssl.cnf file. I am not creating OCSP responders. Use the sample file below to create openssl.conf. Edit the lines in blue as desired.

# The [default] section contains global constants that
# can be referred to

# from the entire configuration file. It may also hold
# settings pertaining to # more than one openssl command.

# base_url = http://FQDN of your NAS
# Optional - update aia_url and crl_url
[ default ]

default_ca          = ca_default            # The default CA section
base_url            =
aia_url             = $base_url/pub/ca.crt
crl_url             = $base_url/ca.crl
name_opt            = utf8,esc_ctrl,multiline,lname,align
prompt              = yes

# Update countryName, stateOrProvince, localityName & organizationName
# Optional - update commonName
# CA Distinguished Name (DN) - called from req section

[ ca_dn ]
countryName          = "US"
stateOrProvinceName  = "IL"
localityName         = "Chicago"
organizationName     = "Lava VPN"

commonName           = "Root CA"

# The CA section defines the locations of CA assets, as
# well as the policies

# applying to the CA. Used by the 'openssl ca' command
[ ca_default ]
home                = /etc/ssl/root-ca     # Base directory
database            = $home/db/index       # dB index file
serial              = $home/db/serial      # Serial number file
crlnumber           = $home/db/crlnumber   # CRL number file
certificate         = $home/ca.crt         # CA public cert
private_key         = $home/private/ca.key # CA private key
RANDFILE            = $home/private/.rnd # Private random number file
new_certs_dir       = $home/certs       # Public certs directory
unique_subject      = no                # Require unique subject
copy_extensions     = none              # Copy extensions from the CSR
default_days        = 3650              # Certify for 10 years
default_crl_days    = 365               # How long until next CRL
crl_extensions      = crl_ext           # CRL extensions
default_md          = sha512            # Default signature algorithm
copy_extensions     = none              # Copy extensions from CSR

policy              = match_pol         # Default naming policy
x509_extensions     = client_ext        # Default signing extensions

# The next part of the configuration file is used by the
# openssl req command.
# It defines the CA's key pair, its DN, and the desired
# extensions for the CA 
[ req ]
default_bits        = 2048        # RSA key size
encrypt_key         = yes         # Protect private key
default_md          = sha512      # MD to use
utf8                = yes         # Input is UTF-8
string_mask         = utf8only    # Emit UTF-8 strings
prompt              = no          # Don't prompt for DN
distinguished_name  = ca_dn       # DN section
x509req_extensions  = ca_reqext   # Extensions for CA self-signed

# Extensions for CA self-signed Cert ca.crt
[ ca_reqext ]

keyUsage                  = critical,keyCertSign,cRLSign
basicConstraints          = critical,CA:true,pathlen:0
extendedKeyUsage          = clientAuth,serverAuth
subjectKeyIdentifier      = hash
authorityKeyIdentifier    = keyid:always

# Naming policies control which parts of a DN end
# up in the certificate and

# under what circumstances certification should be denied.
[ match_pol ]
countryName           = match     # Must match cn_dn
stateOrProvinceName   = match     # Must match cn_dn
localityName          = match     # Must match cn_dn
organizationName      = match     # Must match cn_dn
commonName            = supplied  # Must be present

# Certificate extensions define what types of
# certificates the CA is able to
[ root_ca_ext ]
keyUsage                 = critical,keyCertSign,cRLSign
basicConstraints         = critical,CA:true,pathlen:0
subjectKeyIdentifier     = hash
authorityKeyIdentifier   = keyid:always

# CRL extensions exist solely to point to the CA
# certificate that has issued
 the CRL.
[ crl_ext ]
authorityKeyIdentifier    = keyid:always

# Extensions used to create server
keyUsage                 = critical,digitalSignature,keyEncipherment
basicConstraints         = critical,CA:false
extendedKeyUsage         = clientAuth,serverAuth
authorityKeyIdentifier   = keyid:always
subjectKeyIdentifier     = hash

# Extensions used to create clients
keyUsage                 = critical,digitalSignature
basicConstraints         = critical,CA:false
extendedKeyUsage         = clientAuth
authorityKeyIdentifier   = keyid:always
subjectKeyIdentifier     = hash

3. Create the Diffie Hellman Parameters

I think you can use elliptic curve (EC) parameters instead of Diffie Hellman (DH) parameters. But I need to do some more research. I am using the 'dsaparam' flag to drastically reduce the amount of time it takes to create the file. I am using 2048 bits. Do not use 1024. And 4096 is overkill at this time.

  • cd /etc/ssl/openvpn
  • openssl dhparam -dsaparam -rand /dev/urandom -out dh2048.pem 2048

NOTE: This command will still take around 15 to 30 minutes to complete. Newer more powerful Synology NAS devices may require a bit less time.

4. Create the TLS Auth

Creating a TLS auth key helps to harden your VPN. It is a static pre-shared key (PSK) that must be generated in advance and shared among all peers.

  • cd /etc/ssl/openvpn
  • openvpn --genkey --secret private/ta.key

NOTE: This is not an OpenSSL command. It is an OpenVPN command.

On the OpenVPN server configuration file we must add the following line.

  • tls-auth /path/to/ta.key 0

On the clients we will be using inline files (concatenate all crt and key files into the OVPN file). The client configuration file needs the following line.

  • key-direction 1

5. Create the Root CA

The command below will generate a private key file (ca.key) and a public key file (ca.crt) for our new CA. When prompted, supply a secure password for the private key. Keep track of this password.

  • cd /etc/ssl/openvpn
  • openssl req \
    -config ./openssl.conf \
    -days 3650 \
    -x509 \
    -new \

    -keyout private/ca.key \
    -out pub/ca.crt

Check the private and public keys.

  • Private:  openssl rsa -in private/ca.key -check
  • Private:  openssl rsa -in private/ca.key -text -noout
  • Public:  openssl x509 -in pub/ca.crt -text -noout

Verify that the public key (ca.crt) has the correct distinguished name defined by openssl.conf. And verify that the x509v3 extensions list it as a CA.

We will also convert the CA crt to PEM format. This allows us to run 'openssl verify' commands against newly signed certificates.

  • openssl x509 \
    -in pub/ca.crt \
    -outform PEM \
    -out pub/ca.pem

6. Create the CRL (Revocation List)

Our default CRL days is 365. We need to create a new CRL every 365 days. Normally this is 30 days. But this is for a small personal OpenVPN instance. We want this as easy to manage as possible. Now create the CRL file before we create any other keys.

  • cd /etc/ssl/openvpn
  • openssl ca \
    -config ./openssl.conf \

    -gencrl \
    -extensions crl_ext \
    -out ca.crl

NOTE: You must recreate the file every time you revoke a client.

Read the contents with the following command.

  • openssl crl -in ca.crl -text -noout

Revoke a Certficate

The serial number of each CRT is stored in the database. (db/index) Grep for the name in the file and you can see the serial number. The serial number is shown in bold blue in the example below.

grep CN=john.doe db/index

V 280410224051Z 1BA302853C5C152075698774AC393A04 unknown /C=US/ST=IL/L=Chicago/O=Lava VPN/CN=john.doe

You must supply a reason for the revocation. Choose one of the following reasons.

  • unspecified
  • keyCompromise
  • CACompromise
  • affiliationChanged
  • superseded
  • cessationOfOperation
  • certificateHold
  • removeFromCRL

Use the command below to revoke a certificate. Update as appropriate. Make sure you create a new ca.crl file after each certification revocation.

  • openssl ca \
    -config ./openssl.conf \

    -revoke certs/1BA302853C5C152075698774AC393A04.pem \
    -crl_reason keyCompromise

7. Create the Server Key, CSR, & Crt

Now create the server private key (server.key) and CSR (server.csr). Adjust your '-subj' flags as required to match whatever you set in the 'openssl.cnf' file for the CA. When prompted enter a password for the private key (server.key). We need to remove the password for this key as Synology does not support authentication on the server key.

  • cd /etc/ssl/openvpn
  • openssl req \
    -config ./openssl.conf \
    -days 3650 \
    -new \

    -subj '/C=US/ST=IL/L=Chicago/O=Lava VPN/CN=server' \
    -extensions server_ext \
    -keyout private/server.key \
    -out csr/server.csr

Synology will not accept encrypted private keys. We must remove the password from the server private key. When prompted provide the password for the server private key.

  • openssl rsa -in private/server.key -out private/server.key

Now sign the CSR and generate the public key (server.crt). Remember you need to sign the CSR with the password for the CA private key (ca.key). Next we will verify that the public key has the correct information. Check to see the DN is correct and that the x509 extensions are correct. It should not be a CA and should point to the CA issuers public key (ca.crt).

  • cd /etc/ssl/openvpn
  • openssl ca \
    -config ./openssl.conf \
    -extensions server_ext \
    -days 3650 \

    -subj '/C=US/ST=IL/L=Chicago/O=Lava VPN/CN=server' \
    -in csr/server.csr \
    -out pub/server.crt
  • openssl x509 -in pub/server.crt -text -noout

8. Create the Client Key, CSR, & Crt

We will use the first and last name of the person for each client certificate. The first and last names will be separated by a '.' (period /aka dot). You can add a '-' (dash) or another '.' (period /aka dot) to either name to help with repeated names. For example you can use 'john.doe-jr' or 'john.doe.jr' as the name. Update the 'subj' flag with the correct DN. Make sure you use client extensions.

Just like the server setup we need to create a private key and a CSR. Then we need to sign the CSR and create the public key. Make sure you use the client extensions.

First create the CSR and private key. Make sure you create a new secure password for the private key and keep track of it.

  • cd /etc/ssl/openvpn
  • openssl req \
    -config ./openssl.cnf \
    -days 3650 \
    -new \

    -subj '/C=US/ST=IL/L=Chicago/O=Lava VPN/CN=john.doe' \
    -extensions client_ext \
    -keyout private/john.doe.key \
    -out csr/john.doe.csr

Now sign the CSR and create the public key. Remember you need to sign the CSR with the password for the CA private key (ca.key).

  • cd /etc/ssl/openvpn
  • openssl ca \
    -config ./openssl.cnf \
    -extensions client_ext \
    -days 3650 \

    -subj '/C=US/ST=IL/L=Chicago/O=Lava VPN/CN=john.doe' \
    -in csr/john.doe.csr \
    -out pub/john.doe.crt
  • openssl x509 -in pub/john.doe.crt -text -noout

Repeat these steps to add more clients.

Setup OpenVPN Server Configuration

OpenVPN provides a fully annotated sample openvpn server configuration file. They also provide a fully annotated sample client openvpn.ovpn file. To determine the default server configuration file run 'ps -aux | grep openvpn' on your NAS. The default location is shown below.

  • /usr/syno/etc/packages/VPNCenter/openvpn/openvpn.conf

The script mentioned in this document will copy the 'openvpn.conf' file copied below to "/etc/ssl/root-ca/ovpn/openvpn.conf.SERVER.SAMPLE". Edit this script as required. Then copy it over the default config shown above. Feel free to make additional changes. At a minimum you need to edit the push routes and the server VLAN. And you can also change the port if desired.

# OpenVPN Server Config
# Edit as appropriate

# Push routes to clients for local LAN subnet
# intranet - most home routers use
push "route"
# VPN network - choose whatever /24 you desire
push "route"

# Set Subnet mode
topology subnet

# VPN Server Subnet - OpenVPN uses x.x.x.1

# Do not allow split-tunneling
# Force ALL traffic through VPN
push "redirect-gateway def1"

# Listen on port (UDP or TCP) default 1194
port 1194

# Set Protocol - tcp or udp
proto udp

# Synology only supports TUN (L3)
# Set device tun/tap
dev tun0

# Keepalive n m = ping n ping-restart m
# ping every 10 seconds // restart after no ping in 60 sec
keepalive 10 60

# Renegotiate data channel key after N seconds (default=3600)
# 0 = disable
reneg-sec 0

# SSL/TLS certificates created by OpenSSL - root-ca
# ca = Root CA Self Signed Cert
# key = server running on Root CA private key
# cert = server running on Root CA public key
# dh = Diffie Hellman Parameters
# Syno default dir = /var/packages/VPNCenter/target/etc/openvpn/keys
ca /etc/ssl/root-ca/pub/ca.crt
key /etc/ssl/root-ca/private/server.key
cert /etc/ssl/root-ca/pub/server.crt
dh /etc/ssl/root-ca/dh2048.pem

# "HMAC FW" - helps block DoS attacks and UDP port flooding
# openvpn --genkey --secret ta.key
tls-auth /etc/ssl/root-ca/private/ta.key 0

# CRL Revocation List File Location
crl-verify /etc/ssl/root-ca/ca.crl

# Select a cryptographic cipher. (symmetric)
# Used by 'data channel'
# NOTE: OpenVPN 2.4 has newer ciphers GCM
# openvpn --show-ciphers
cipher AES-256-CBC

# Select Auth - auth alg
# openvpn --show-digests

# Authenticate packets with HMAC
auth SHA512

# For compression compatible with older clients use comp-lzo
# If you enable it here, you must also
# enable it in the client config file.
comp-lzo adaptive

# The maximum number of concurrently connected
# clients we want to allow.
max-clients 5

# The persist options will try to avoid
# accessing certain resources on restart
# that may no longer be accessible because
# of the privilege downgrade.

# Limit TLS v1.2
tls-version-min 1.2

# Limit TLS ciphers to those listed below
# Used by 'control channel'
# openvpn --show-tls
# EC and ECDSA tls ciphers only availble in 2.4 or higher
# Using list below as this is v2.3.x

# Limit scripting level
# 0 - no calling of external programs
# 1 (default) only call built-in executables - ifconfig, ip, netsh
# 2 allow calling of user defined scripts
# 3 allow passwords to be passed to scripts via environmental variables (unsafe)
script-security 2

# Ensure clients have EKU - extended key usage - set to client
# Clients must be set to use server
# remote-cert-eku "TLS Web Server Authentication"
remote-cert-eku "TLS Web Client Authentication"

# Output a short status file showing
# current connections, truncated
# and rewritten every N (30 sec)
status /tmp/ovpn_status_2_result 30

# Status version N - 1, 2 or 3
status-version 2

# Set the appropriate level of log
# file verbosity.
# 0 is silent, except for fatal errors
# 4 is reasonable for general usage
# 5 and 6 can help to debug connection problems
# 9 is extremely verbose
verb 3

Setup OpenVPN Client Configuration

Edit the included sample client configuration to match your server configuration. Then for each new client change the name to easily identify each OVPN file. And concatenate the certificates in the proper order. First put CA certificate (ca.crt). Second add the new client public certificate. Third add the new client private key. And fourth add the TLS authentication file (ta.key).

The client configuration file will be identical with 3 exceptions.

  1. For Windows clients comment out the 'user nobody' and 'group nobody' lines.
  2. Each client will have their own unique client public key. (john.doe.crt)
  3. Each client will have their own unique client private key. (john.doe.key)

Edit the sample file below as appropriate. Make sure you add the certificates.

# OpenVPN Client Config
# Needs to match server config
# Edit as appropriate

# Specify that we are a client and that we
# will be pulling certain config file directives
# from the server.

# Use the same setting as you are using on
# the server.
# On most systems, the VPN will not function
# unless you partially or fully disable
# the firewall for the TUN/TAP interface.
dev tun0

# Are we connecting to a TCP or
# UDP server? Use the same setting as
# on the server.
proto udp

# The hostname/IP and port of the server.
# You can have multiple remote entries
# to load balance between the servers.
# Should be dyn dns hostname
remote 1194

# Keep trying indefinitely to resolve the
# host name of the OpenVPN server. Very useful
# on machines which are not permanently connected
# to the internet such as laptops.
resolv-retry infinite

# Most clients don't need to bind to
# a specific local port number.

# Downgrade privileges after initialization (non-Windows only)
; user nobody
; group nobody

# Try to preserve some state across restarts.

# Verify server certificate by checking that the
# certicate has the correct key usage set.
# This is an important precaution to protect against
# a potential attack discussed here:
remote-cert-tls server

# If a tls-auth key is used on the server
# then every client must also have the key.
key-direction 1

# Allow remote peer to change IP (DHCP)
# Accept authenticated packets from any address
# not just address specified by 'remote' option

# Select a cryptographic cipher.
# If the cipher option is used on the server
# then you must also specify it here.
# Note that v2.4 client/server will automatically
# negotiate AES-256-GCM in TLS mode.
# See also the ncp-cipher option in the manpage
cipher AES-256-CBC

# Select HMAC Authentication
# server/client must match
auth SHA512

# Verify EKU - Extended Key Usage is set to server on remote box
remote-cert-eku "TLS Web Server Authentication"

# Set TLS to min of 1.2
tls-version-min 1.2

# Enable compression on the VPN link.
# Don't enable this unless it is also
# enabled in the server config file.
comp-lzo adaptive

# Set log file verbosity.
verb 0

# To simplify OVPN client setup concatenate
# all certificates here in proper order
# 1 <ca> </ca> 2 <cert> </cert>
# 3 <key> </key> 4 <tls-auth> </tls-auth>

Concatenate the Client OVPN

The script will create our client OVPN file. If you do this manually you need to concatenate all of the files into the client OVPN file.

  • Add the user to the root CA using the commands above.
  • Copy the sample OVPN file and create a client OVPN file. (john.doe.ovpn)
  • Add the ca.crt file, client crt file, client key file, and ta.key. Each file must be enclosed with the identifiers shown below.

cat ca.crt here
cat john.doe.crt here
cat john.doe.key here
cat ta.key here

Overwrite the Synology openvpn.conf File

Copy are new OpenVPN server configuration file  and overwrite the default Synology openvpn.conf file. Our new file is shown below.

  • /etc/ssl/root-ca/ovpn/openvpn.conf.SERVER

The default file is shown below.

  • /usr/syno/etc/packages/VPNCenter/openvpn/openvpn.conf

Add Our Server Keys to the GUI

By default Synology uses the self-signed synology certificate for everything. We need to add a new certificate to the DSM GUI and then configure OpenVPN to use that new certificate. It has to be a chained certificate and include our new server.key (private key), the server.crt (public key), and the new root CA public certificate (ca.crt).

I tar these three files up before I transfer them.

  • /etc/ssl/root-ca/pub/ca.crt (Root CA public certificate)
  • /etc/ssl/root-ca/pub/server.crt (OpenVPN server public certificate)
  • /etc/ssl/root-ca/private/server.key (OpenVPN server private certificate)

Extract the files somewhere on your computer. Then launch the DSM GUI. (https://your_nas:5001)

  • Next launch the 'Control Panel'.
  • Navigate to 'Security' and then open the 'Certificate Tab'.
  • Click 'Add'
    • Choose 'Add a new certificate' and click 'Next'
    • Choose 'Import certificate'. Optionally add a description. Click 'Next'.
    • Now import the server.key, server.crt, and ca.crt. See the picture below.
      Import Certificate Files Screen
      Import Certificate Files Screen

      Click OK to import the certificate. Then highlight your new certificate and click 'Configure'. Select 'server' (or what you used for a description) in the drop down box next to 'VPN Server'. And then click OK.

      Select 'server' Certificate
      Select 'server' Certificate


Restart OpenVPN

Restart OpenVPN so that it loads the new configuration. You may do this from the GUI or from the command line.

In the GUI open 'Package Center' and then scroll to 'VPN Server'. Open that and use the drop down box labeled 'Action' and select 'Stop'. Use the same box to start the VPN server again.

From a command line run the following command.

  • synoservice --restart pkgctl-VPNCenter
  • Or: /var/packages/VPNCenter/scripts/start-stop-status {stop start}

To check out your server configuration you may run the following.

  • cd /usr/syno/etc/packages/VPNCenter/openvpn
  • openvpn --config ./openvpn.conf

Using the Script

Setting everything up manually isn't that difficult. And it is very useful to help learn about SSL and OpenVPN. But adding or revoking users can be a pain if you have to remember the correct syntax. I created a script to help build the root CA. And it will add and revoke users as well. I mentioned the script above. It is included in 'SYNO-OVPN.tar.gz'. The README file shows you how to use the script. And it explains how to edit the included sample files.  Enjoy.

Synology - WebDAV Setup

Installing and configuring WebDAV on Synology NAS


Please read and follow the previous Synology setup posts before installing WebDAV.

  1. Securing Synology NAS
  2. Synology - Map Domain with DDNS
  3. Synology - Setup Let's Encrypt SSL Certificates

Install WebDAV

Go to the Package Center on your Synology NAS device. Install the 'WebDAV Server'.

Configure WebDAV

There are very few options to configure in WebDAV. But there are some security issues and permission issues to consider. Please feel free to change the permissions described below.

WebDAV Settings Tab

Go to the main menu and then open WebDAV Server. Enable HTTPS. Optionally change the default port from 5006 to whatever you desire as long as it isn't in use already. (1025 - 65535) You may choose to enable the WebDAV log as well. Finally you have the option of limiting the speed. Click 'Apply' once you are done.

Create a WebDAV Group and User

By default only the administrators group has access to WebDAV. However, I don't want to allow administrative access from the web. So I will create a new group and a new WebDAV user. This user should also have 2FA enabled for increased security.

Go to: Control Panel > Group

Click 'Create'.

  • Group name = webdav (Or whatever you prefer)
  • Group description = WebDAV Access Group

Skip the shared folder permissions as of now. We will be creating one or more shared folders for WebDAV.

Allow 'WebDAV Server' application permissions.

Go to: Control Panel > User

Click 'Create'.

  • Name = <choose_name> (I used 'webby' for now)
  • Description = WebDAV User Access
  • Email = optional
  • Password = Create a password that meets your password rules requirements.
  • Click 'Next'.

Add the user to the 'webdav' group. By default it is already part of the users group. Click 'Next'.

Skip granted shared folder access for now.

Allow the user to access the 'webDAV Server' application.

Create One or More Shared Folders

I don't like the idea of opening every folder in the root directory to WebDAV. I will create one folder for uploads with RW access. And add one or more folders with RO access. This may include some of the existing shared folders.

Go to:  Control Panel > Shared Folders

First we will create an upload folder with RW permissions. Click 'Create'.

  • Name = upload
  • Description = WebDAV Upload Folder
  • Click 'Next'

Optionally encrypt this folder. Click 'Next' and then 'Apply'. Now we can setup our basic folder permissions.

  • Local users:
    • admin - No access
    • Your new Admin user - will have RW by default. - No access
    • webby (or whatever WebDAV user you created) -
  • Local groups:
    • administrators - RW
    • webdav - RW
  • System internal user:
    • I need to experiment a bit more. Right now all system IDs have no access. But a few may need RO and possibly RW access.

There are some interesting advanced permissions. I need to experiment a bit more before adding any recommended setup steps for those permissions.

Pick one of your existing shared folders. Edit it. Change the group permissions for the webdav group to RO.

Verify DSM Access with New User

First verify that your new user has DSM access and set the password. Verify you can see your new 'upload' folder and whatever RO folder you chose. Upload a test file to your upload directory.

Add WebDAV SSL Certificate

Go to: Control Panel > Security > Certificate

Select your new SSL certificate. Then select 'Configure'. For the 'WebDAV Server' service change the certificate from the default certificate to your new SSL certificate. Click 'OK'.

Verify WebDAV Access

First we need to edit our hosts file. When we setup our SSL certificate we updated our hosts file and mapped '' to our internal private IP address (192.168.x.y). Now we need to disable this temporarily while we test out WebDAV. This is a good reason why you may want to get 2 Let's Encrypt SSL certificates with different subdomains.

  • notepad C:\Windows\System32\drivers\etc\hosts
  • put a hash tag in front of the 192.168.x.y address for your NAS
  • save the file
  • NOTE: Re-enable this mapping and test WebDAV access from your internal LAN as well. You may want to eliminate SMB access or other access methods and simply use WebDAV.

In Windows we can now map a network drive to our new WebDAV setup. Open File Explorer and then right click on 'This PC'. Select 'Map network drive'. Then fill out the new window as shown below.

  • Drive - choose any free drive letter you desire
  • Folder =
  • Check 'Connect using different credentials
  • Click finish and then enter your ID and password
    • webby (The ID we created above)
    • passw0rd - Enter your password
WebDAV - Map Network Drive
WebDAV - Map Network Drive

Again verify that you can upload a file.

You may want to run 'tcpdump' on your NAS to see if any packets are hitting it.

tcpdump -i eth0 -lnpt tcp and port 5006

Limit Administrators Group WebDAV Access

You can access WebDAV with the new administrator ID you previously created. It actually won't have access to the upload folder. But I don't want administrative access available from the web.

Go to: Control Panel > Group

Select the 'administrators' group and then click 'Edit'. Go to the 'Applications' tab. Scroll down to the WebDAV Server line. Change the permissions from 'Allow' to either 'Deny' or 'By IP'. I am setting up 'By IP' and I will whitelist my internal private subnet. Typically home routers use a /24 subnet from the 192.168/16 network. If your home network is you would enter the information as shown below. Adjust the subnet as required.

Whitelist Private Subnet
Whitelist Private Subnet

Limit WebDAV Access for the Admin User

We also need to limit WebDAV access by subnet for the newly created admin user. Go to the user panel in the control panel. Edit your administrator ID. And go to the Applications tab and repeat the steps above. Limit WebDAV access by IP to your local subnet.

Now verify your admin ID can access WebDAV locally but not from the internet.

2FA Not Available for WebDAV

Unfortunately 2FA is not available via WebDAV. At least not at this time. This is another reason to select strong passwords and to limit which folders are accessible over the web.

WebDAV Clients

There are numerous WebDAV clients available for IOS and Android. Choose your favorite and have remote access to your files.

This is actually a better place to store your Keepass database. And other files that you may need to access away from home but want to keep away from prying eyes.

Although access via a VPN is probably a bit more secure. But that is debatable.

Synology - Setup Let's Encrypt SSL Certificates

Setting up Let's Encrypt SSL certificates on Synology NAS devices


Before following this article please first secure your Synology NAS. And setup DDNS and a CNAME.

Let's Encrypt SSL Certificates

Let's Encrypt provides a free automated SSL certificate that can be used to secure your Synology NAS. You can have multiple SSL certificates. Perhaps one for local LAN DSM logins and another for WebDAV internet access. Or you could use the same SSL certificate.

I am not replacing or removing the default Synology self-signed SSL certificate. You can always switch back to that for various services.

Setup Web Station

Let's Encrypt will query your Synology NAS on port 80/TCP and 443/TCP. I can't find the nice technical document I read before. When I do I will add the link to this document. By default the Synology NAS device does not listen on 80/TCP or 443/TCP nor does it have a website.

Go to Package Center and install 'Web Station'. Once that finishes go to the main menu and launch 'Web Station'. Follow the steps below to configure the virtual host.

By default Web Station uses Nginx. I have both PHP 5.6 and PHP 7.0 installed on my NAS. I need to figure out if I can uninstall PHP 5.6. But that is for a future date. I am not sure if Web Station will automatically install PHP. If necessary install that package as well.

General Settings Tab

Select the following items from the drop down boxes.

  1. HTTP back-end server: = Nginx
  2. PHP: = Default Profile ( PHP 7.0 )
  3. Do NOT enable the personal website.

PHP Settings Tab

I think I deleted the PHP 5.6 profile from this tab. I didn't edit anything else.

Virtual Host

Before adding the virtual host you need to create a document root. Go to the Control Panel and then click on 'Shared Folder' and then 'Create' a new shared folder in the root directory. Or if you prefer bury the folder in whatever path you desire. The name should be 'www'. But it can be anything you desire.

  • Shared Folder Setup
    • Name = www
    • Description = Virtual Host Root Directory
    • Permissions Local Users = Your Admin ID = RW
    • Permissions Local Groups = administrators = RW // http = RO

Go back to the web station settings and finish creating the virtual host. Fill out the panel as shown below. See the screen shot after the explanation.

  • Select 'Name-Based'
    • Hostname =
    • Port = check 80/443
  • Document root = www (browse and select)
  • HTTPS settings:
    • Check HSTS
      • HSTS - Force connections to use HTTPS (443/TCP)
    • Check HTTP/2
      • HTTP/2 - Newest HTML standards
  • HTTP back-end server = Nginx
  • PHP = Default Profile ( PHP 7.0 )
  • Click OK
Create Virtual Host Panel
Create Virtual Host Panel

Create the .well-known/acme-challenge Directory

Let's Encrypt will query our virtual host to verify that we own the domain we wish to secure with the SSL certificate. To allow this we need to create two sub-directories under the 'www' shared folder.

I prefer the command line. SSH into your NAS. (as root) Run the following commands.

  • Switch to your www directory. - example: cd /volume1/www
  • mkdir -m 0711 -p .well-known/acme-challenge
  • chmod -R 0711 .well-known
  • chown -R http:http .well-known

Setup Port Forwarding on Your Router

Let's Encrypt will query your NAS device using your public IP address given to you by your ISP. Your NAS should not be on the internet or in a DMZ. I don't use UPnP either. Port forwarding is very simple to setup. And just about any consumer router should allow you to setup port forwarding.

One catch to make port forwarding work is that your NAS needs to use the same private IP address at all times. I do this by setting up DHCP reservations on my router. But you could configure your NAS device to use a static IP address.

PC World has a good article on setting up port forwarding. It varies from router to router. But the basics are the same. The site has a number of guides on how to setup port forwarding on various routers. Just don't buy there tool. You need three port forwarding rules.

  1. HTTP-80 // Protocol = TCP // Port from = 80 // IP Address = Private IP address of your NAS (192.168.x.y) // Port to 80
  2. HTTPS-443 // Protocol = TCP // Port from = 443 // IP Address = Private IP address of your NAS (192.168.x.y) // Port to 443
  3. WebDAV-5006 // Protocol = TCP // Port from = 5006 // IP Address = Private IP address of your NAS (192.168.x.y) // Port to 5006

The last rule assumes you will use the default secure WebDAV port. Feel free to change this to any port you desire as long as you change it in the WebDAV configuration as well.

Add additional rules if you enable additional packages on your NAS.

Verify Ports Are Open

I have read that some ISPs will block 80/TCP or 443/TCP. You may be able to get them to open these ports for you. Verify that your NAS is listening on 80/TCP and 443/TCP. You can use nmap or netstat. Synology does not have the 'ss' command as of yet. SSH to your NAS and run the following command.

netstat -latn |egrep "80|443"

Use Shields Up from to probe your NAS device. First run tcpdump on your NAS so you can see if any traffic hits your box. The IP address is for shields up. (dig @ +short)

tcpdump -i eth0 -lnpt tcp and port 80 or port 443 and host

Make sure you see a SYN [S] from GRC and a SYN-ACK [S.] going to GRC for each port you check. Don't worry about the reset flags [R.].

Install the Let's Encrypt SSL Certificate

Remember in a previous post we setup DDNS and a CNAME for our subdomain. Here is a review of the information we setup for our domain.

  1. The domain you purchased. Presumably for your personal website. =
  2. Comcast public IP address (73/8) = 73.x.y.z
  3. DDNS = with A record of 73.x.y.z
  4. Subdomain = (replace lab with anything you desire)
  5. Fully Qualified Domain Name (FQDN) = (You don't really need to do this. But I wanted to use my Synology FQDN as the URL. You can simply use the subdomain if you desire.)

Go to: Control Panel > Security > Certificate

Click 'Add' to create a new certificate. Leave the default '' self-signed certificate alone. It is our fallback certificate if we ever have issues. Follow the steps below.

  1. Select 'Add a new certificate' and click 'Next'
  2. Select 'Get a certificate from Let's Encrypt' and click 'Next'
  3. Fill out Let's Encrypt information as shown below.
    1. Domain name = (FQDN from above. Or you could simply use the subdomain ''. Whichever you prefer.)
    2. Email = Your email address (must be a valid email)
    3. Subject Alternative Name = OR; (The dynamic DNS name you created from a dynamic DNS provider. Since I used my FQDN for the domain name I also add the subdomain as a second SAM. Separate the two subject alternative names with a semi-colon. Again adding the second SAM is optional.)

See the screen shot below.

Lets Encrypt Certificate Information Panel
Lets Encrypt Certificate Information Panel

Once you have filled it out click 'Apply'. Assuming everything is correct you should have a new SSL certificate. If things don't work you can look at the logs on your NAS. SSH and tail '/var/log/messages'.

Configure the New Certificate

To use this new certificate for DSM logins (5001/TCP) you need to set it as the system default certificate. Highlight the newly created certificate and click 'Configure'. You will see a list of all your services. Your list may be different than the screen shot shown below. The certificate column has a bunch of drop down boxes that allow you to select any configured certificate. For the 'System default' service use the drop down box and select your newly created Let's Encrypt certificate. And then click 'OK'.

Configure Certificates Panel
Configure Certificates Panel

Update Your Hosts File

I am not allowing DSM access from the web. You can continue to use the IP address of your NAS ( if you desire. But you will get the warning about an improper SSL certificate. The FQDN '' will resolve to your public IP address.

To allow for easy access from your LAN update your hosts file. Add the private IP address of your NAS and the FQDN and the subdomain. See the example below.

  • notepad C:\Windows\System32\drivers\etc\hosts
  • 192.168.x.y
  • Save the file. Ensure there is no 'txt' extension

Now test out the connection from your browser.

Setup WebDAV

In my next post I will install and configure WebDAV.

Synology - Map Domain with DDNS

Mapping Synology to a subdomain with DDNS and CNAME

First Secure Your Synology NAS

Secure your Synology NAS before adding enabling internet access. Follow this post for more information.


You need to own your own domain. You need to understand the basics of DNS and have the ability to add a CNAME to DNS.

Setup Dynamic DNS (DDNS)

Your ISP provides you with a publicly routable IP address. You then connect your router to the ISP modem. Your devices inside your home have NAT'ed IP addresses and are all RFC 1918 addresses. These addresses are not routable on the internet. When you go to a website or use anything on the internet your router will translate your private IP to the public IP address provided by your ISP.

Most ISPs provide DHCP addresses. They change from time to time. To get a SSL certificate you need to be able to map your domain to an IP address. Dynamic DNS will automatically update the forward resolution of your domain name to IP address even if it changes. The TTL (time to live) needs to be short. Normally this is about 15 minutes or so. So any changes won't be immediately available. But for home use it is more than good enough.

You can use any number of DDNS providers. Synology also offers a DDNS service. I already added DDNS to my home router. So I am not going to walk through the setup in this article.


Once you setup DDNS you will have a resolvable domain name that maps to the IP address given to you by your ISP. For example Comcast (Xfinity) owns all of 73/8. So if your ISP is Comcast you will have a public IP like 73.x.y.z. (where x.y.z are valid numbers between 0-255) Check what it is by going to  And if you used as your DDNS provider you resolve your 73.x.y.z IP address to You can choose any available hostname and choose from a number of different domains. A 73.x.y.z

If you owned the domain '' you could then create a subdomain and add a CNAME to Lets say you create the subdomain So you have the following.

  1. The domain you purchased. Presumably for your personal website. =
  2. Comcast public IP address (73/8) = 73.x.y.z
  3. DDNS = with A record of 73.x.y.z
  4. Subdomain = (replace lab with anything you desire)
  5. Fully Qualified Domain Name (FQDN) = (You don't really need to do this. But I wanted to use my Synology FQDN as the URL. You can simply use the subdomain if you desire.)

You now need to setup a CNAME record for either the subdomain or the FQDN. The exact procedure will vary with your DNS provider. But you want to set it up like the following picture.

DDNS Setup
DDNS Setup

Here is our DNS zone information.

NAME                    TYPE   VALUE
------------------------------------------------        A      73.x.y.z   CNAME

The CNAME is ''. The domain '' is an alias to our DDNS domain. (

Since we own '' we can assign a SSL certificate to the subdomain of ''. In this example this is actually our Synology FQDN. Our home network domain would actually be ''. And we can use this internally.

Next Steps

Follow this post to setup Let's Encrypt SSL certificates.

JW Newsroom Notification Using IFTTT

How to use to receive RSS notifications from the JW Newsroom site.


RSS (Rich Site Summary or Real Simple Syndication) has been around for a long time. This article does not attempt to explain the ins and outs of RSS. Feel free to use to use another RSS reader if you so desire. This article will show the basics of using (If this then that).

IFTTT is a rather useful site to help automate or notify many different web based items. I am using IFTTT instead of other RSS readers because it provides a consistent way to be notified of new articles on JW newsroom on iOS and Android. I use both platforms and found that RSS readers on iOS do not provide very good notifications.

Sign In To IFTTT

You can use OAUTH and sign in with Google or Facebook. There are pros and cons to OAUTH. For more information on how it works check out this site. Be forewarned that like all authentication protocols there are some security risks. And recently a few security issues were discovered, but these should be patched by now.

I prefer to use a new password for each site. IFTTT supports long secure passwords and it also supports 2FA (Two Factor Authentication). I recommend using both. Your password should be at least 16 characters in length with lots of entropy. You can use the website or just the app on iOS or Android to register and setup your new IFTTT applet. Once you have your IFTTT account setup log into the site and then continue with these instructions to setup the RSS notification applet.

Below are the links for the IFTTT app for iOS and Android.

Creating the RSS Notification Applet

You can modify an existing applet. But this document will detail the steps to create a new applet. I am using notifications. You can also send a SMS alert if you prefer. I will leave that to you to figure out. Follow the steps below.

Create a New Applet

In the upper right of the web page you will see your username and a drop down arrow. Click on that and then click "New Applet".

IFTTT New Applet
IFTTT New Applet

Select Your Service

First click on the blue "+ this". It is surrounded by the red box in the picture below. The red box won't exist on the website.

Click Blue Plus This
Click Blue Plus This

Select the RSS Service

The RSS Feed service should be on the top row. Or you can use the search box and search for it. It is the orange box in the picture below. Just click on it to proceed to the next step.

RSS Feed
RSS Feed

Choose a Trigger

The RSS Feed service has two different triggers. I just want to be notified every time there is a new feed item on JW Newsroom. The other option will allow you to add keywords to only search for specific news items. In the picture below the correct trigger is surrounded by a red box that won't appear on the website.

Choose Trigger
Choose Trigger

Complete Trigger with Feed URL

Now you need to add the JW Newsroom XML Feed URL. To do this go to the JW newsroom site and right click on the 'Subscribe' button. Or long press on iOS or Android. Then select "Copy Link Address" or something similar depending on which browser or platform you are using. Paste it into the Feed URL and then click "Create trigger". See the picture below. The current link is copied below. It is possible this link will change. And if you use a different language you will have a different link.

Add Feed URL to Trigger
Add Feed URL to Trigger

Click On the Blue + That

Now that we have set our trigger. We need to create our action. Click on the blue "+ that". See the picture below. Again the red box won't exist on the website.

Click on Blue Plus That
Click on Blue Plus That

Choose Action Service

In the search box type in "notifications". This will reduce the services to one option. Click on the blue Notifications box to continue. See the picture below.

Choose Action Service
Choose Action Service

Choose Action

Now click on the blue "Send a notification from the IFTTT app". Please note that you need to install the IFTTT application on your electronic device to receive these notifications. And you must sign into the app before anything will work. At the time of this writing there was only one action to choose for the notification service. See the picture below.

Choose Action
Choose Action

Complete Action Fields

This step can be modified to choose your own desires. You can add or subtract ingredients by clicking on 'Add ingredient'. You can add plain text if you desire. The ingredients available for RSS feeds are listed below.

  • {{EntryTitle}} = The title of the entry in the RSS feed.
  • {{EntryUrl}} = The URL of the entry in the RSS feed.
  • {{EntryAuthor}} = The author of the content as seen on the RSS feed.
  • {{EntryContent}} = The content itself as is written in the RSS feed.
  • {{EntryImageURL}} = The thumbnail URL in the RSS feed.
  • {{EntryPublished}} = When the entry was published.
  • {{FeedTitle}} = The title of your RSS feed.
  • {{FeedURL}} = The URL of the source of the RSS feed.

I like to have 3 ingredients. I use "FeedTitle", "EntryTitle", and "EntryUrl". Edit it how you desire and then click "Create action". See the picture below.

Completed Action Fields
Completed Action Fields

Review and Finish

The default description is very long. I edit this to something short and easily identifiable. Feel free to use whatever you desire. Once you are done click "Finish". See the picture below.

Review and Finish
Review and Finish

Make sure you install the IFTTT app on your tablet or phone and sign into the application. Once that is done you will receive notifications for every new story from the JW newsroom site.


That is all there is to it. Enjoy!

Remove Carriage Returns (^M)

Brief tutorial on how to remove carriage returns in UNIX. Use CTRL-V+CTRL-M in SED or VI. Use octal \026 \015. Use tr or perl.


Whenever you transfer files from DOS (Windows) to UNIX boxes it is possible that carriage returns may be added to your text files.  This will sometimes prevent the file from working properly in UNIX.  I have actually had some files work with carriage returns (CR hex 0D).  I know the simple VI command to remove the carriage returns (^M) at the end of each line. And there are several other ways to remove carriage returns.

I ran into a problem on my home router running DD-WRT. It would not allow me to type CTRL-V+CTRL-M to create the carriage return (^M) in vi or anywhere else. I suspect is a busybox shell issue. So I had to find another way. This document shows the standard methods as well as a new method I used on my router. I am not including 'dos2unix' and 'unix2dos' as these may not by installed. I prefer to remember standard methods that should work on all boxes without installing additional software.

Who Uses What

A brief rundown on which OS uses which symbol for a line terminator.

  • LF = linefeed (move cursor down) - CTRL-J / ^J / hex 0A / Sometimes written as NL (newline)
  • CR = carriage return (return cursor to left margin) - CTRL-M / ^M / hex 0D
  • UNIX = LF only
  • DOS = CRLF (each line ends with CR then LF)
  • MAC = CR only

Typing ^M

To create the return character in vi or the command line you normally type "CTRL-V+CTRL-M". That is you press and hold the control key and then press 'v' and then 'm' (without the single quotes) and then release the control key. Another way is to use '\r'. (backslash r) And one more way is to use octal. Type '\026' for 'CTRL-V' and '\015' for 'CTRL-M'.

The Commands

Below are the various methods to edit the file. There are more methods than listed here. One of these is likely to work.


The percent sign (%) will perform the search and replace on all lines. And the 'g' at the end does the search and replace globally and not on just the first instance in the line.


Other ways to accomplish the same task.


This wiki article has some other useful tidbits about VI (VIM) and file formats.

Display the fileformat option (ff) for the current buffer, and the fileformats global option (ffs) which determines how VIM reads and writes files.

:set ff? ffs?
:verbose set ff? ffs? (Helps to see in your vimrc)

Convert from dos/unix to unix

:update             Save any changes
:e ++ff=dos         Edit file again using dos FF (fileformats                                  ignored)
:setlocal ff=unix   This buffer will use LF only
:w                  Write buffer using unix (LF-only) line endings

Convert from dos/unix to dos

:update             Save any changes
:e ++ff=dos         Edit file again using dos FF (fileformats                                  ignored)
:w                  Write buffer using unix (LF-only) line endings

tr (translate)

The '-d' flag deletes the tokens. Input the original file and output the new file. The '\r' (slash r) is another way to type the carriage return.

tr -d '\r' < file > newfile


Search and replace using sed is quite common. You can type ^M various ways. I am showing three methods. The '-e' is for scripting on the command line and running those commands directly. The greater than sign (>) redirects the output to a new file. Otherwise the results are just displayed to stdout (standard out). You can add a 'g' to the end for global replacement just like in vi. The '-r' is for using regex (regular expressions).

sed -e 's/\r//' file > newfile

sed -e 's/^M//' file > newfile

sed -r $'s/\026|\015//g' file > newfile


You can also use a one line perl command. The '-e' is used to enter one line of script to be run by perl. Multiple '-e' commands may be given. The '-p' causes perl to assume a certain type of loop command. Useful for one liner commands. The '-i(extension)' will edit the file in place. The extension is added to the filename. The original file is saved as 'filename.extension'. The edited file is saved as the original filename.

perl -pi.bak -e 's/\r//g' filename

OpenSSL Certificate Authority (CA) 101

Create your own Certificate Authority (CA). These directions are based upon the Feisty Duck documentation. This document shows you how to setup your own root authority and subordinate CA. And it includes OCSP.

Read the Docs

These directions are based upon the Feisty Duck directions.  It also helps to read the OpenSSL documentation.  Arch Linux has a decent WIKI article as well.  I built myself an OpenSSL CA a while back.  But the Feisty Duck directions are much better than the very basics.


I am using 'lab.pahoehoe.local' for my domain.  I originally tried to use ''.  But I have been too lazy to finish setting up my home ESXi host and internal VLANs.  Once I finish this task I can setup internal DNS and properly use ''.

Identify the Proper Directory

Different distributions will compile OpenSSL with different directories.  Use 'openssl version -a |grep DIR' to identify the directory for your box.

$ openssl version -d  (Raspbian / Debian)
OPENSSLDIR: "/usr/lib/ssl"
pi@pi2:~ $ ls -l /usr/lib/ssl
total 4
lrwxrwxrwx 1 root root 14 May 3 23:03 certs -> /etc/ssl/certs
drwxr-xr-x 2 root root 4096 May 27 11:11 misc
lrwxrwxrwx 1 root root 20 May 3 23:03 openssl.cnf -> /etc/ssl/openssl.cnf
lrwxrwxrwx 1 root root 16 May 3 23:03 private -> /etc/ssl/private

# openssl version -d  (CentOS 7 / RHEL 7)
OPENSSLDIR: "/etc/pki/tls"
[root@zl01lab01 ~]# ls -l /etc/pki/tls
total 12
lrwxrwxrwx. 1 root root 49 Jul 5 19:37 cert.pem -> /etc/pki/ca-trust/extracted/pem/tls-ca-bundle.pem
drwxr-xr-x. 2 root root 112 Jul 5 19:37 certs
drwxr-xr-x. 2 root root 69 Jul 5 19:37 misc
-rw-r--r--. 1 root root 10923 Mar 5 2015 openssl.cnf
drwxr-xr-x. 2 root root 6 Jun 29 2015 private

Create the ROOT CA

Pick a directory for the configuration files.  You will create new directories and a new configuration file for the root CA.  My root CA will be on my CentOS 7 box.

  • cd /etc/pki
  • mkdir root-ca
  • cd /etc/pki/root-ca
  • mkdir certs db private pub csr
  • chmod 700 private
  • touch db/index
  • openssl rand -hex 16 > db/serial
  • echo 1001 > db/crlnumber
  • vi /etc/pki/root-ca/root-ca.conf  (See 'root-ca.conf and sub-ca.conf' below)

Now we can create the root CA CSR, private key and public key.  Plus we will create the CRL (Certificate Revocation List) and the OCSP certificates.  You must export the RANDFILE variable or openssl will default to '~/.rnd'.  Not that it matters either way.

export RANDFILE=/etc/pki/root-ca/private/.rnd

Create the root CA CSR (./root-ca.csr) and private key (./private/root-ca.key).  You must enter a passphrase.  But we will delete that passphrase.  You can keep it if desired.

openssl req -new \
-config root-ca.conf \
-out root-ca.csr \
-keyout private/root-ca.key

Remove the passphrase.

openssl rsa -in private/root-ca.key -out private/root-ca.key

Now we can self sign our CSR and create the public key (./root-ca.crt).

openssl ca -selfsign \
-config root-ca.conf \
-in root-ca.csr \
-out root-ca.crt \
-extensions ca_ext

To generate a CRL use the '-gencrl' command as shown below.  The output will be './root-ca.crl'.

openssl ca -gencrl \
-config root-ca.conf \
-out root-ca.crl

OCSP Responder

The feisty duck directions provide a basic OCSP (Online Certificate Status Protocol).  If you have a lightweight web server you can configure that to respond to the OCSP queries.  Or you could move that to another server entirely.  OCSP is better than CRL (Certificate Revocation List).  But it still puts a burden on the CA and adds additional exposure to the CA.  If you sniff the packets when you log into an HTTPS site you will notice that your laptop also queries the OCSP responder.

OCSP stapling is a better solution.  The HTTPS site will periodically query the CA and then provide a timestamp in the TLS handshake to the client.  The client does not query the OCSP server directly.  Obviously you cannot include the OCSP responder URL in the server certificate.  I need to read more about OCSP stapling.  However, I have seen a number of VM appliances that are black boxes.  I am not sure if they support OCSP stapling.

Perform this on the root CA and the sub CA.

  • Create a key and CSR for the OCSP responder.  You may choose to remove the passphrase on the private key.  See the example above.

openssl req -new \
-newkey rsa:2048 \
-subj "/C=US/O=Lava Dreams/CN=OSCP Root Responder" \
-keyout private/root-ocsp.key \
-out csr/root-ocsp.csr

  • Second use the root CA to issue a certificate.  The days are shortened since this certifcate cannot be revoked.

openssl ca \
-config root-ca.conf \
-in csr/root-ocsp.csr \
-out pub/root-ocsp.crt \
-extensions ocsp_ext \
-days 30

  • Start the OCSP Responder - Ideally this would be done in an HTTPD server on a standard port.

openssl ocsp -port 9080 -index db/index \
-rsigner pub/root-ocsp.crt \
-rkey private/root-ocsp.key \
-CA root-ca.crt -text &

Create the SUB CA

The steps are very similar.  I am using my Raspberry PI for my subordinate CA (aka intermediate CA).  Edit the configuration file as appropriate.

  • cd /etc/ssl
  • mkdir sub-ca
  • cd /etc/ssl/sub-ca
  • mkdir certs db private pub csr
  • chmod 700 private
  • touch db/index
  • openssl rand -hex 16 > db/serial
  • echo 1001 > db/crlnumber
  • vi /etc/ssl/sub-ca/sub-ca.conf  (See 'root-ca.conf and sub-ca.conf' below)

Now create the CSR (./sub-ca.csr) and the private key (./private/sub-ca.key).  This is done on the SUB CA.

openssl req -new \
-config sub-ca.conf \
-out sub-ca.csr \
-keyout private/sub-ca.key

Remove the passphrase.

openssl rsa -in private/sub-ca.key -out private/sub-ca.key

Transfer the CSR (sub-ca.csr) to the ROOT CA.  Then using the ROOT CA create a certificate for the SUB CA.

openssl ca \
-config root-ca.conf \
-in sub-ca.csr \
-out certs/sub-ca.crt \
-extensions sub_ca_ext

Transfer the 'sub-ca.crt' to the SUB CA.  Place it in '/etc/ssl/sub-ca/sub-ca.crt'.

Create a Certificate Chain

Some applications will not accept our CRT from our intermediate (SUB-CA).  We need to provide the application with the certificate chain.  The root-ca.crt and the sub-ca.crt files need to be converted to the PEM format and concatenated together.  The order is important on some older versions of java.  So use the following order.

  1. private key (if applicable / not recommended)
  2. client certificate (server.crt - convert to PEM)
  3. intermediate certificate (sub-ca.pem)
  4. root certificate (root-ca.pem)

From the root CA perform the following steps.

  • openssl x509 -in root-ca.crt -outform pem -out root-ca.pem
  • openssl x509 -in sub-ca.crt -outform pem -out sub-ca.pem
  • cat sub-ca.pem root-ca.pem > server-chain.pem  (copy the output to the SUB CA)

OCSP Responder

Perform the following steps to create the SUB CA OCSP responder.

  • Create a key and CSR for the OCSP responder.  You may choose to remove the passphrase on the private key.  See the example above.

openssl req -new \
-newkey rsa:2048 \
-subj "/C=US/O=Lava Dreams/CN=OSCP SUB-CA Responder" \
-keyout private/sub-ocsp.key \
-out csr/sub-ocsp.csr

  • Second use the root CA to issue a certificate.  The days are shortened since this certifcate cannot be revoked.

openssl ca \
-config sub-ca.conf \
-in csr/sub-ocsp.csr \
-out pub/sub-ocsp.crt \
-extensions ocsp_ext \
-days 30

  • Start the OCSP Responder - Ideally this would be done in an HTTPD server on a standard port.

openssl ocsp -port 9081 -index db/index \
-rsigner pub/sub-ocsp.crt \
-rkey private/sub-ocsp.key \
-CA sub-ca.crt -text &

SUB CA Operations

Now we can sign CSR and issue new server or client certificates.  Most of the time we will issue server certificates.  Use unique names so you can identify each file.  Typically this is the short hostname.

Server Certificates

openssl ca \
-config sub-ca.conf \
-in csr/${SERVER}.csr \
-out pub/${SERVER}.crt \
-extensions server_ext

This will create a 'SERIAL_NUM.pem' file in certs.  The serial number is the same number listed in db/serial.

Client Certificates

openssl ca \
-config sub-ca.conf \
-in csr/${CLIENT}.csr \
-out pub/${CLIENT}.crt \
-extensions client_ext

Import 'root-ca.crt' into Windows

The local trust store must be updated to include our new CA.  You can do this in Windows by following the steps below.  Transfer 'root-ca.crt' to your local box.

Chrome & MS Edge & MS Internet Explorer Browsers

  • Start // Run // inetcpl.cpl
  • Click on the 'Content' tab
  • Click on 'Certificates'
  • Click on the 'Trusted Root Certification Authorities' tab
  • Click 'Import...'
  • Click 'Next'
  • Browse to your 'root-ca.crt' file, click 'Open' and then 'Next'
  • Ensure that it is being placed in the 'Trusted Root Certification Authorities' Certificate store and click 'Next'
  • Review and click 'Finish'
  • Click 'Yes' on the Security Warning
  • Click 'OK' and click 'Close' on the Certificates Window
  • Click 'OK' on the Internet Properties window

Firefox Browser

  • Launch Firefox
  • Open a new tab and type in 'about:preferences'
  • Click Advanced
  • Click Certificates
  • Click 'View Certificates'
  • On the 'Authorities' tab click 'Import...'
  • Navigate to 'root-ca.crt' and click 'Open'
  • Click on 'Trust this CA to identify websites' and click 'OK'
  • Click 'OK'

Convert Files and View Files

You may need to convert a CRT file to a PEM file.  Or do some other sort of conversion.  Different applications expect different types of file formats.  You may also need to verify the contents or extract the contents of various files.


openssl x509 -in XYZ.crt -outform PEM -out XYZ.pem

openssl x509 -in XYZ.pem -outform der -out XYZ.crt


openssl x509 -in XYZ.crt -inform DER -outform PEM -out XYZ.pem

Read the CSR or CRT or PEM

openssl req -in X.csr -text -noout

openssl x509 -in cert.crt -text -noout

openssl x509 -in X.pem -text -noout

Check a Private Key

openssl rsa -in X.key -check

Generate a New Private Key and CSR

openssl req -new -nodes -days 3650 -newkey rsa:4096 \
-keyout PRIVATE.key -out X.csr \
-subj "/C=US/ST=IL/L=Chicago/O=Lava Dreams/CN=hostname.lab.pahoehoe.local"

root-ca.conf and sub-ca.conf

You need to edit this file to suit your environment.  The blue lines must be edited.  There are other possible changes that you may make.  But you must read the official documentation to understand what you may or may not want to change.  This sample configuration file has both the root and subordinate CA information.

# ROOT-CA # name              = root-ca
# SUB-CA # name               = sub-ca
domain_suffix                 = lab.pahoehoe.local
aia_url                       = http://$name.$domain_suffix/$name.crt
crl_url                       = http://$name.$domain_suffix/$name.crl
# ROOT-CA # ocsp_url          = http://ocsp.$name.$domain_suffix:9080
# SUB-CA # ocsp_url           = http://ocsp.$name.$domain_suffix:9081
default_ca                    = ca_default
name_opt                      = utf8,esc_ctrl,multiline,lname,align

countryName                   = "US"
organizationName              = "Lava Dreams"
# ROOT-CA # commonName        = "Root CA"
# SUB-CA # commonName         = "Sub CA"

home                          = .
database                      = $home/db/index
serial                        = $home/db/serial
crlnumber                     = $home/db/crlnumber
certificate                   = $home/$name.crt
private_key                   = $home/private/$name.key
RANDFILE                      = $home/private/.rnd
new_certs_dir                 = $home/certs
unique_subject                = no
# ROOT-CA # copy_extensions   = none
# ROOT-CA # default_days      = 3650
# ROOT-CA # default_crl_days  = 365
# SUB-CA # copy_extensions    = copy
# SUB-CA # default_days       = 365
# SUB-CA # default_crl_days   = 30
default_md                    = sha256
policy                        = policy_c_o_match

countryName                   = match
stateOrProvinceName           = optional
organizationName              = match
organizationalUnitName        = optional
commonName                    = supplied
emailAddress                  = optional

default_bits                  = 4096
encrypt_key                   = yes
default_md                    = sha256
utf8                          = yes
string_mask                   = utf8only
prompt                        = no
distinguished_name            = ca_dn
req_extensions                = ca_ext

basicConstraints              = critical,CA:true
keyUsage                      = critical,keyCertSign,cRLSign
subjectKeyIdentifier          = hash

authorityInfoAccess           = @issuer_info
authorityKeyIdentifier        = keyid:always
basicConstraints              = critical,CA:true,pathlen:0
crlDistributionPoints         = @crl_info
extendedKeyUsage              = clientAuth,serverAuth
keyUsage                      = critical,keyCertSign,cRLSign
nameConstraints               = @name_constraints
subjectKeyIdentifier          = hash

URI.0                         = $crl_url

caIssuers;URI.0               = $aia_url
OCSP;URI.0                    = $ocsp_url


authorityKeyIdentifier        = keyid:always
basicConstraints              = critical,CA:false
extendedKeyUsage              = OCSPSigning
keyUsage                      = critical,digitalSignature
subjectKeyIdentifier          = hash

# SUB-CA ONLY server_ext & client_ext

# [server_ext]
# authorityInfoAccess         = @issuer_info
# authorityKeyIdentifier      = keyid:always
# basicConstraints            = critical,CA:false
# crlDistributionPoints       = @crl_info
# extendedKeyUsage            = clientAuth,serverAuth
# keyUsage                  = critical,digitalSignature,keyEncipherment
# subjectKeyIdentifier        = hash

# [client_ext]
# authorityInfoAccess         = @issuer_info
# authorityKeyIdentifier      = keyid:always
# basicConstraints            = critical,CA:false
# crlDistributionPoints       = @crl_info
# extendedKeyUsage            = clientAuth
# keyUsage                    = critical,digitalSignature
# subjectKeyIdentifier        = hash

DN, OU, CN and Others

Distinguished Names

Distinguished Names (DN) are used in PKI (Public Key Infrastructure) and LDAP (Lightweight Directory Access Protocol).  The DN is the combination of one or more RDNs (Relative Distinguished Name).  This is specified in the X.509 standard.  This is RFC 5280.

Below is a list of some of the more common RDN names.

RDN Name Abbreviation Example
Country C US
Organizaion O IBM
Organizational Unit OU (Multiple Allowed) Billing
State or Province Name ST IL
Common Name CN
Serial Number SN 123456
Locality L Chicago
Domain Component DC (Multiple Allowed) www 
User Identifier UID / USERID John Doe
Title T IT Architect
Email Address MAIL
Postal Code PC 60020

Typical WWW Certificate

If you go to Digicert, GlobalSign, or InstantSSL they will ask for the same information.  Not all of the information may be required.  Here are the common fields.

  • Country (C) = US
  • State or Province (ST) = IL
  • Locality or City (L) = Chicago
  • Organization (O) = Company Name
  • Organization Unit or Department (OU) = Descriptive Department Name
  • Common Name (CN) =, or *, or Public IP ( - This is how the web will reach your server.

You also need to provide the key type and the key size.  This is typically RSA and the minimum size these days is 2048.  Elliptic curve keys will be smaller (256).

Please note that a standard certificate will only secure ''.  It will not secure ''.  Or some other sub-domain.  You need to get a SANs (Subject Alternative Name) or a wildcard certificate.  Extended validation (EV) certificates are the same as a regular certificate except the CA will more rigorously verify that you are who you say you are.


Here are some examples from Google and Yahoo and the CA itself.

DN: C=US, O=Symantec Corporation, OU=Symantec Trust Network,\ CN=Symantec Class 3 Secure Server CA - G4

DN: C=US, ST=Washington, L=Seattle,, Inc.,\

DN: C=US, O=Equifax, OU=Equifax Secure Certificate Authority

DN: C=US, ST=California, L=Mountain View, O=Google Inc,\

DD-WRT OpenVPN 101


This document is a bit old. It still works. But I created a new setup on my Synology NAS. And it is a better setup. I now better understand openssl and how to configure it. There are a few things I would probably change in this document. Plus as nice as DD-WRT may be, it is open source and free. Those nice folks do not have the same resources as Synology. My DD-WRT OpenSSL package is a bit out of date and so is my OpenVPN package. Synology isn't the latest and greatest either. But it is more current. And it is more likely to be updated before DD-WRT.

Please use my Synology OpenVPN setup guide.

Read the Docs

The official DD-WRT documentation (and this doc) is very good.  And the official OpenVPN documentation covers a lot more detail.  Also refer to the Wikipedia article on X.509.  This document just covers the steps I needed to perform and does not add a lot of explanation.

Backup DD-WRT

Backup your DD-WRT configuration before you start changing anything.

Routing (tun) vs Bridging (tap)

Routing or tunneling encapsulates the data over OSI L3.  I am using this method.  One reason is that the iPhone does not support bridging.  With routing you need to create a new private subnet for the VPN server.

Bridging encapsulates the data over OSI L2.  You are extending your local LAN subnet across the VPN.  The default DD-WRT subnet is  You create a TAP interface on the server and the client.  As stated above this is not supported on Apple IOS devices.  And from what I have read it can be rather difficult to setup on Windows as well.

File Formats

This is provided as a reminder to myself.  With OpenSSL you can convert from almost any format to another.  This information is from Wikipedia,,,  and a few other sources.

  • *.pem - (Privacy-enhanced Electronic Mail) Base64 encoded DER certificate, enclosed between "----BEGIN CERTIFICATE-----" and "-----END CERTIFICATE-----".  Certificate container format that may include just the public certificate, or the entire certificate chain including the public key, private key, and root certificates.  
    • Base64 (ASCII) Encoding - Group of similar binary-to-text encoding schemes that represent binary data in an ASCII string format by translating it into a radix-64 representation.
    • DER Encoding (Binary) - DER is a restricted variant of BER for producing unequivocal transfer syntax for data structures described by ASN.1.
      • X.690 is an ITU-T standard specifying several ASN.1 encoding formats:
      • Basic Encoding Rules (BER)
      • Canonical Encoding Rules (CER)
      • Distinguished Encoding Rules (DER)
  • *.cer, *.crt - X.509 certificate (Base64 (ASCII) or DER (binary) encoded) - PEM formatted file with a different extension.  Recognized by Windows explorer as a certificate.
    • *.der - (DEPRECATED) - Binary DER encoded certificates.  These may also use the "*.cer" or "*.crt" extensions.
  • *.key - This is the PEM formatted file containing just the private key.
  • *.p7b *p7c, *.spc - PKCS#7 SignedData structure without data, just certificate(s) or CRL(s).  (Certificate Revocation List)
  • *.crl - Certificate Revocation List
  • *.csr - Certificate Signing Request - Submit this to the CA.  Contains some or all of the key details (subject, organization, state, OU, CN, etc) and the public key.
  • *.stl, *.ctl - Certificate Trust List (MS IIS)
  • *.sst - Microsoft Serialized Certificate Store
  • *.p12 - PKCS#12 - May contain certificate(s) public and private keys.  This is password protected.  
  • *.pfx - PFX, predecessor of PKCS#12.  Usually contains data in PKCS#12 formate with PFX files generated in IIS.)

The Environment

I am using a non-standard port.  My Aunt has a Xfinity wireless router.  The firewall on that isn't very good.  I have setup maximum security on it but it doesn't allow for exceptions or specific rules.  But it does allow 500/UDP GRE (Generic Routing Encapsulation) VPNs.  So I will use that port for my OpenVPN configuration.  My main laptop runs Windows.  I will be using the Windows setup steps.  I will be creating client files for my iPhone, Android tablet, Nexus tablet, and my Windows laptop.  At the time of this writing I installed version 2.3.11 (64 bit) for Windows Vista and later.  These directions assume you have already setup Dynamic DNS for your router's public IP address or you have a static IP address.

Easy-RSA Certification Creation

From an Administrator command prompt switch to the easy-rsa directory.

  • C:\Program Files\OpenVPN\easy-rsa

Perform the following steps.  I have VIM and GOW installed on my Windows box.

  • init-config <ENTER>  (This will copy the vars.bat.sample to vars.bat.)
  • vim vars.bat  (Edit the following lines as appropriate.)

set KEY_CITY=Chicago
set KEY_NAME=Zaphods Widgits
set KEY_OU=Zaphods
set PKCS11_MODULE_PATH=changeme (Ignore)
set PKCS11_PIN=1234  (Ignore)

  • vars <ENTER>  (This will source the environmental variables.)
  • clean-all <ENTER>  (Deletes anything in .\keys\* and recreates the index.txt and serial files in .\keys.)
  • build-ca <ENTER>  (Builds the Certificate Authority (CA) certificate (.\keys\ca.crt) and key (.\keys\ca.key).  This allows us to sign our certificates.)

WARNING: can't open config file: /etc/ssl/openssl.cnf
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) [IL]:
Locality Name (eg, city) [Chicago]:
Organization Name (eg, company) [OpenVPN]:
Organizational Unit Name (eg, section) [Zaphods]:
Common Name (eg, your name or your server's hostname) [OpenVPN-CA]:
Name [Zaphods Widgits]:
Email Address []:

  • vars <ENTER> (re-source variables)
  • build-key-server server <ENTER>  (You can use any name, but using 'server' is easier.  This creates the server crt and key and csr.  You MUST USE 'server' as the CN in the example below.  Edited to highlight the important bits.)

Country Name (2 letter code) [US]:
State or Province Name (full name) [IL]:
Locality Name (eg, city) [Chicago]:
Organization Name (eg, company) [OpenVPN]:
Organizational Unit Name (eg, section) [Zaphods]:
Common Name (eg, your name or your server's hostname) [OpenVPN-CA]:server
Name [Zaphods Widgits]:
Email Address []:

Please enter the following 'extra' attributes
to be sent with your certificate request
A challenge password []:******* (Optional - used by revocation)
An optional company name []:
WARNING: can't open config file: /etc/ssl/openssl.cnf
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:'IL'
localityName :PRINTABLE:'Chicago'
organizationName :PRINTABLE:'OpenVPN'
commonName :PRINTABLE:'server'
name :PRINTABLE:'Zaphods Widgits'
emailAddress :IA5STRING:''
Certificate is to be certified until Jul 8 21:06:12 2026 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\OpenVPN\easy-rsa>

Create the Client Keys

You can use the same client key and crt files on every client.  But it is more secure to use unique keys.  This allows for client revocation.  You should use unique identifiable names for each client.  You MUST use the client name for the CN name during the file creation process.  You can come back to this section and create more client keys at any time.  This will create three files in the keys directory.  (*.crt, *.key, *.csr)

  • vars <ENTER>
  • build-key iphone <ENTER>  (Replace iphone with a unique name for each client.  Use the same name in commands below for the CN.)

Country Name (2 letter code) [US]:
State or Province Name (full name) [IL]:
Locality Name (eg, city) [Chicago]:
Organization Name (eg, company) [OpenVPN]:
Organizational Unit Name (eg, section) [Zaphods]:
Common Name (eg, your name or your server's hostname) [OpenVPN-CA]:iphone
Name [Zaphods Widgits]:
Email Address []:

Please enter the following 'extra' attributes
to be sent with your certificate request
A challenge password []:******* (Optional)
An optional company name []:
WARNING: can't open config file: /etc/ssl/openssl.cnf
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:'IL'
localityName :PRINTABLE:'Chicago'
organizationName :PRINTABLE:'OpenVPN'
commonName :PRINTABLE:'iphone'
name :PRINTABLE:'Zaphods Widgits'
emailAddress :IA5STRING:''
Certificate is to be certified until Jul 8 22:36:47 2026 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\OpenVPN\easy-rsa>

Repeat as necessary for each client.

Create the Diffie Hellman Parameters

If this was a Linux server I would use a 2048 bit key.  This step will create the 'dh1024.pem' file.  To change this to 2048 bits edit 'vars.bat' and change the 'KEY_SIZE' variable from 1024 to 2048.  This will also change the output file from 'dh1024.pem' to 'dh2048.pem'.

  • vars <ENTER>
  • build-dh <ENTER>

Create the TLS Authentication File

This isn't part of the easy-rsa setup.  But while we are creating all of our files on our Windows box we may as well create this file as well.  I am copying this to the keys directory just to keep all of the files together.

  • cd ..\bin
  • openvpn.exe --genkey --secret ta.key
    • --genkey:  Generate a random key to be used as a shared secret, for use with the --secret option.
    • --secret file:  Write the key to a file.
  • move ta.key ..\easy-rsa\keys\ta.key
    • server config = tls-auth ta.key 0
    • client config = tls-auth ta.key 1
    • iphone = key-directive 1 (comment out tls-auth)

List of Files

All of these files are in the keys directory.  This is just the relevant files.  The "*.csr" files are not required anymore.

Filename Needed By Purpose Secret
ca.crt server & all clients Root CA Certificate No
ca.key Key Signing Machine Only Root CA Key Yes
dh{n}.pem server only DH Parameters No
server.crt server only Server Certificate No
server.key server only Server Key Yes
iphone.crt client 1 only (iphone) Client 1 Certificate No
iphone.key client 1 only (iphone) Client 1 Key Yes
ta.key server & all clients OpenVPN TLS Auth Yes

Setup the DD-WRT Gateway

Log into the DD-WRT web GUI.  Go to 'Services // VPN' and enable the 'OpenVPN Server/Daemon'.  I am using the WAN UP start type and configuring this as a daemon.  Copy the files we created via easy-rsa to the server.  Simply copy and paste the Base64 encoded sections of each file.  See the example below.  Most of the file has been replaced by '........'.

-----BEGIN CERTIFICATE-----  (Start Copy & Paste Here)
-----END CERTIFICATE-----  (End Copy & Paste Here)

Box Name File to Insert
CA Cert ca.crt
Public Server Cert server.crt
Private Server Key server.key
DH PEM dh1024.pem
Additional Config See Server Config Below
TLS Auth Key ta.key
Certificate Revoke List crl.pem (If exists to revoke client X)

At this time the 'clr.pem' file does not exist.  If we revoke a client in the future we can add the 'crl.pem' file.

  • vars <ENTER>
  • revoke-full clientX <ENTER>  (Where clientX is the name of one of the clients.)

Server Config

OpenVPN includes a fully annotated sample configuration file.  I am configuring the server using the 'additional config' box.  This replicates how an OpenVPN server would be setup on a Linux box.  The results are the same using the web GUI or the command line.  See the config by running 'nvram get openvpn_config' from the DD-WRT command line.

Many sites recommend using 'push "dhcp-options DNS x.x.x.x"'.  I am not using that setting.  If I use that option I cannot get DNS working.  I suspect I have some strange setting in my DHCP setup.

I am using the 'push "redirect-gateway def1"' on the server.  This forces all traffic over the VPN.  You can use this option on the client side by removing the 'push' part.  Feel free to test this option using 'tcpdump -nl -i tun0' on your DD-WRT router.  Or by simply heading to '' or ''.

  • C:\Program Files\OpenVPN\sample-config\server.ovpn

There are two networks that connect over the internet (WAN).

  • Local LAN = (DD-WRT Default - Update with your subnet)
  • OpenVPN Private Routing = (Use whatever you like)

# Push route to clients for local LAN subnet
push "route"
# Set subnet mode (net30, p2p, subnet)
topology subnet

# VPN Server Subnet - OpenVPN uses x.x.x.1
# Clients use the remaining IPs

# Listen on non-standard port (default 1194)
port 500
# Set protocol tcp or udp
proto udp
# Set device (tunX|tapX|null) server/client identical
# tun - L3 // tap - L2
dev tun0
# keepalive n m = ping n ping-restart x
# ping every 10 sec // restart after no ping in 120 sec
keepalive 10 120
# path to certs and keys - hard coded dd-wrt paths
dh /tmp/openvpn/dh.pem
ca /tmp/openvpn/ca.crt
cert /tmp/openvpn/cert.pem
key /tmp/openvpn/key.pem
# Additional layer HMAC auth on top of TLS control

# channel to protect against DoS attacks
# server must be  0 // client 1
tls-auth /tmp/openvpn/ta.key 0
# Compression mode (yes|no|adaptive (default) )
comp-lzo adaptive
# Allow multiple clients with same CN to connect concurrently
# duplicate-cn
# Route all traffic over VPN - NOT split tunnel
# 1. create static route for remote address which forwards
#    to pre-existing default gateway
# 2. delete the default gateway route
# 3. Set new def gateway to be the VPN endpoint address
# local - both openvpn servers connected via common subnet (wireless)
#         causes step 1 to be omitted
# def1 - override def gateway (, does not wipe
#        out original def gateway
push "redirect-gateway def1"

# Encrypt data channel packets
# cipher alg - server/client must match
# defaults to BF-CBC 128 bit
# openvpn --show-ciphers (to list ciphers)
cipher AES-256-CBC
# Authenticate packets with HMAC (message digest algorithm)
# auth alg - server/client must match
# defaults to sha1
# openvpn --show-digests (to list digests)
auth sha1

# Logging verbosity (services/services/syslogd)
# 0 silent except fatal
# 4 reasonable for general usage
# 5, 6 - debug
# 9 - extremely verbose
verb 0

# Only use crl-verify if you have revoke list
# crl-verify /tmp/openvpn/ca.crl

# Management parameter - DD-WRT can 
# access server's management port
management localhost 5001

Copy and paste the above into the 'additional config' box.  Edit as desired.  Now save and apply the settings.

DD-WRT Firewall Settings

Now we must allow the VPN traffic through the DD-WRT firewall.  Go to "Administrative // Commands".  Edit the rules below as required for your environment.  To help identify the correct interface run 'netstat -rn' from the DD-WRT command line or from the web GUI.  An edited example is shown below.  The public interface uses vlan2.  DD-WRT creates br0 for the internal networks.  And OpenVPN created tun0.

# netstat -rn (Removed Flags MSS Window and irtt)
Kernel IP routing table
Destination     Gateway       Genmask       Iface       vlan2  (Public Gateway) tun0  (OpenVPN) vlan2     lo   br0 br0 (DD-WRT Internal Bridged Networks)

Edit the lines below before adding them to the web GUI.  Cut and paste them into the 'Commands' box.  Then click 'Save Firewall'.  You will lose connectivity as the firewall rules are processed.  Edit the bold blue items as required.

  • udp - Change to tcp if required
  • 500 - Default port is 1194.  Edit as required
  • - This is the VPN server subnet previously created.  Edit as appropriate.
  • br0 - Default DD-WRT internal bridge
  • tun0 - The newly created OpenVPN tunnel interface
  • vlan2 - The public interface for the DD-WRT router (netstat -rn)
  • # Accept incoming connections on port 500/UDP
    iptables -I INPUT 1 -p udp --dport 500 -j ACCEPT
    # Forward packets from VPN subnet

    iptables -I FORWARD 1 --source -j ACCEPT
    # Forward packets inbound bridge outbound via tunnel

    iptables -I FORWARD -i br0 -o tun0 -j ACCEPT
    # Forward packets inbound tunnel outbound via bridge

    iptables -I FORWARD -i tun0 -o br0 -j ACCEPT
    # SNAT outbound packets as VLAN2 IP (public ip)

    iptables -t nat -A POSTROUTING -s -o vlan2 -j MASQUERADE

To see the rules run 'iptables -nvL' and 'iptables -t nat -nvL'.

Client Config

You can edit the sample configuration file.  It is nicely annotated.

  • C:\Program Files\OpenVPN\sample-config\client.ovpn

# Specify that we are a client and that we
# will be pulling certain config file directives
# from the server.

# Specify virtual network device tunX|tapX|null
# X may be omitted for dynamic device
# Both ends must match settings
# tun - encapsulate IPv4-6 OSI L3
# tap - encapsulate IPv4-6 Ethernet 802.3 OSI L2
dev tun0

# Are we connecting to a TCP or
# UDP server? Use the same setting as
# on the server.
proto udp

# The hostname/IP and port of the server.
# You can have multiple remote entries
# to load balance between the servers.
remote 500

# Keep trying indefinitely to resolve the
# host name of the OpenVPN server. Very useful
# on machines which are not permanently connected
# to the internet such as laptops.
resolv-retry infinite

# Most clients don't need to bind to
# a specific local port number.

# Downgrade privileges after initialization (non-Windows only)
user nobody
group nobody

# Try to preserve some state across restarts.

# Offers policy-level control over usage of external
# programs and scripts
# 0 -- strictly no calling of external programs
# 1 -- DEFAULT - Only call built-in exec - ifconfig, ip, route
# 2 -- All calling of built-in exec and user-defined scripts
# 3 -- Allow passwords to be passed to scripts via env variables
# script-security <level>

# SSL/TLS parms.
# See the server config file for more
# description.
# Using inline files - comment out here

# ca ca.crt
# cert client.crt
# key client.key
# tls-auth ta.key 1

# Verify server certificate by checking that the
# certicate has the correct key usage set.
# This is an important precaution to protect against
# a potential attack discussed here:
# To use this feature, you will need to generate
# your server certificates with the keyUsage set to
# digitalSignature, keyEncipherment
# and the extendedKeyUsage to
# serverAuth
# EasyRSA can do this for you.
remote-cert-tls server

# If a tls-auth key is used on the server
# then every client must also have the key.
# tls-auth ta.key 1
# For inline files use key-direction not tls-auth
key-direction 1

# Allow remote peer to change IP (DHCP)
# Accept authenticated packets from any address
# not just address specified by 'remote' option

# Select a cryptographic cipher.
# If the cipher option is used on the server
# then you must also specify it here.
cipher AES-256-CBC

# Select HMAC Authentication
# server/client must match - default sha1
auth sha1

# Enable compression on the VPN link.
# Don't enable this unless it is also
# enabled in the server config file.
comp-lzo adaptive

# Set log file verbosity.
verb 0

# Redirect all traffic over vpn
# Optional - I am setting on server side via push

# redirect-gateway def1

Read the next section to add all of the TLS files to the OVPN configuration file.  This makes management of the files much easier.

Concatenate Key Files into OVPN

Instead of providing the clients with the "*.ovpn" file and the key files you can combine everything into the OVPN file.  At the bottom of the OVPN file add the following.

Here is a list of the files you will need to add.

File Description File to Insert Enclosed By
Root CA Certificate ca.crt (The same file on all clients) <ca> </ca>
Client Certificate iphone.crt (Replace iphone as required) Unique per client <crt> </crt>
Client Private Key iphone.key (Replace iphone as required) Unique per client <key> </key>
TLS Auth Key ta.key (The same file on all clients) <tls-auth> </tls-auth>

# Root Certificate Authority ca.crt
# client cert iphone.crt

# client private key iphone.key
# tls auth ta.key
-----BEGIN OpenVPN Static key V1-----
-----END OpenVPN Static key V1-----

Verify Your Connection

Before you use this in the wild you need to verify that your VPN tunnel is operating correctly.  Here are a few commands to verify that all traffic is routing over the VPN.

From the DD-WRT command line run a few tcpdump commands.

  • tcpdump -nl -i tun0
  • tcpdump -nl -i tun0 port 53
  • To verify
    • tcpdump -nl -i tun0 host && host
  • To verify
    • tcpdump -nl -i tun0 host && host

Obviously use your browser and go to '' and '' before and after you establish your VPN tunnel.  Make sure your IP is now your ISP public IP address.

A Note on Windows

You must run the OpenVPN client as an Administrator.  And you must comment out the 'user nobody' and 'group nobody' lines in the client OVPN file.