OpenVPN Assign static IP to client

After configuring the overall OpenVPN client and server infrastructure, my clients can connect to a VPN. The client can access server resources and vice versa. While the server gets normally always the same IP assigned, the client IP address is assigned dynamically from a pool of IP addresses. Meaning: there is no guarantee that the client always gets the same IP address. Normally, this is not a problem, as the client connects to consume server resources. Such like a web site, or git repository. In my case, the architecture is that the OpenVPN server acts as a proxy to internal services. The web site, git repository, etc are running on the client. Therefore, the server must be able to connect to the client using a fix address.

To make this work, each time a client connects, the same IP must be assigned to. OpenVPN allows to assign a static IP to a client.

Configuration

  1. In /etc/openvpn create folder ccd. Ccd stands for client config directory, meaning: it contains the configuration for a client.
  2. Edit file server.conf and add line “client-config-dir ccd
# EXAMPLE: Suppose the client
# having the certificate common name "Thelonious"
# also has a small subnet behind his connecting
# machine, such as 192.168.40.128/255.255.255.248.
# First, uncomment out these lines:
client-config-dir ccd

3. Create a configuration file for each client and put into directory ccd. As file name, use the same name for the client as used in the CN field of the client certificate.

ifconfig-push IP MASK

Example:

ifconfig-push 10.8.0.2 255.255.255.255

CLI steps

sudo mkdir /etc/openvpn/ccd
sudo touch /etc/openvpn/ccd/client1
sudo vim /etc/openvpn/server.conf
Uncomment the line containing client config parameter
client-config-dir ccd

sudo vim /etc/openvpn/ccd/client1
Insert:
ifconfig-push 10.8.0.2 255.255.255.255
Restart OpenVPN service on server
sudo /etc/init.d/openvpn restart

Client with automatic assignment of IP: 10.8.0.6

After restart of OpenVPN server: IP is now 10.8.0.2

Server log

 

Additional information can be found in OpenVPN documentation.

client-config-dir

“This file can specify a fixed IP address for a given client using –ifconfig-push, as well as fixed subnets owned by the client using –iroute.https://openvpn.net/index.php/open-source/documentation/manuals/65-openvpn-20x-manpage.html

ifconfig-push

„Push virtual IP endpoints for client tunnel, overriding the –ifconfig-pool dynamic allocation.” https://openvpn.net/index.php/open-source/documentation/manuals/65-openvpn-20x-manpage.html

Setup OpenVPN server on Amazon EC2

Recently I got some new hardware that I will use to run some useful software. To use the software from anywhere, I’ll need to have remote access. As I cannot do DMZ or port forwarding with my new internet provider, I decided to connect my home server using VPN to a access machine running on AWS.

The AWS EC2 Linux computer will serve as my entry point. Services running on the RP at home connected via VPN can be accessed from EC2. Other computers at my home cannot be accessed, as the IP is different and no route is configured.

This setup comes with several architectural questions to solve:

  • How to ensure the communication is secure?
  • How to guarantee the tunnel is up?
  • How to enable access from EC2 to the services running on the client?
  • The client must be assigned the same IP for the services be accessible from EC2
  • How to give access to the services from the internet?

The three top question will be answered in my next blogs about how to set up OpenVPN server and client. The first question is the easiest to answer: by using a VPN solution. I am going to use OpenVPN and this blog is about how to setup OpenVPN. I’ll cover the installation on the EC2 instance and on the Raspberry Pi, as well as the initial setup with the certificates, server and client configuration and how to connect. Starting the client and server as service keeps them running and in case the connection fails, an automatic reconnect is attempted. The EC2 instance can access the services running on the client automatically. The last two questions will be answered sometimes later.

OpenVPN Server

Install OpenVPN on EC2

The OpenVPN software is available in yum on EC2 Linux AMI. You may need to enable the REPL repository. I assume you did this already. The packages to install a openvpn and easy-rsa.

sudo yum update
sudo yum install openvpn easy-rsa

This will also install a public key to install a package and ask for your permission to do so.

The easy-rsa package is needed to set up a certificate authority. In case you do have a CA available, you can use your CA to generate the certificates used by OpenVPN. For those that do not have a CA available, take the easy-rsa functionality.

Generate CA

The command above installs easy-rsa 3.x. With 3.x, the way how to use easy-rsa and to set up a CA and issue the certificates changed. You can see in detail how to use easy-rsa 3.x at the documentation available at the GitHub project site.

OpenVPN uses certificates, and easy-rsa issues those certificates. Basically, you have two components of easy-rsa to deal with:

  • CA software
  • Certificates

Configuration of OpenVPN is put and read from /etc/openvpn. Easy-rsa software should be in a separate folder, like /home/ec2-user/easy-rsa, but to keep all in one place I’ll put easy-rsa inside the /etc/openvpn directory.

Note: for real productive usage, don’t do this. Separate easy-rsa executables and config files.

Copy easy-rsa

Copy easy-rsa to your selection location. For this, first find out where easy-rsa is installed.

repoquery -l easy-rsa

Location is /usr/share/easy-rsa/3.0.3. I’ll copy these files to /etc/openvpn/easy-rsa.

sudo mkdir /etc/openvpn/easy-rsa
sudo cp -Rv /usr/share/easy-rsa/3.0.3/* .

Start easy-rsa

Follow the steps outlined at the easy-rsa git site. For the following steps, go into the directory where easy-rsa is installed.

cd /etc/openvpn/easy-rsa

Init PKI

sudo ./easyrsa init-pki

Build CA

This will create the CA certificate to sign certificate requests. In other words: whoever gets access to the private key of the CA created in this step, can create new valid OpenVPN clients for your setup. Take care of the CA certificate and key.

sudo ./easyrsa build-ca

You’ll need to enter:

  • PEM pass phrase
  • Common Name

The passphrase is used to unlock the private key and is an additional level of security. Even when someone gets a copy of the private key of your CA, without the pass phrase the key is not usable. The common name is used to identify the CA. I used the FQDN of my web server. After execution these two commands, the CA is initialized and can be used to issue certificates.

Diffie-Hellman

Generate Diffie-Hellman parameters.

sudo ./easyrsa gen-dh

Generate OpenVPN server certificate

The OpenVPN server needs a certificate issued by the CA to identify itself against the clients. This is a nice “feature” when using PKI. Server and client can validate the other side. Both need just to trust the CA certificate for this. The difference between the two certificates (client and server) is the included type. This is done by including an additional value in the certificate specifying the type of certificate:

  • TLS Web Server Authentication for the server and
  • TLS Web Client Authentication for the client

Which kind of certificate is going to be issued is specified by the easy-rsa command when creating the certificate request.

Generate certificate request

Create a certificate request containing the identity information of the server and let this request be signed by the CA. By specifying the server parameter, the request is for a server and the CA will include the value TLS Web Server Authentication in the extension.

sudo ./easyrsa gen-req server

Inform:

  • Pass phrase
  • Common Name

As with the CA certificate, inform a pass phrase that adds additional security to the private key and a common name to uniquely identify the server. I used server as CN. Of course, it could also have been openvpn.mydomain.com or something else.

Sign request

Send the request to the CA and sign it to issue a valid certificate. With that, the CA information is added to the CA, making it official and clients that connect to OpenVPN server will know if they can trust the server. Only when trust is verified, a connection will be established between the server and client.

sudo ./easyrsa sign-req server server

You’ll need to confirm the request by typing yes and the pass phrase.

TLS-AUTH

The following certificate is needed to harden the overall security of OpenVPN. As OpenVPN is using TLS, it makes sense to add HMAC to validate integrity of the packages received. For this to work, a shared secret key is needed. This key will be written to a file named ta.key.

Generate ta.key

cd /etc/openvpn
sudo openvpn --genkey --secret ta.key
sudo mv /etc/openvpn/ta.key /etc/openvpn/easy-rsa/private

OpenVPN server configuration

Take a sample configuration file as a template. Can be found in the doc folder of openvpn. The sample configuration file for the server is server.conf, and for the client, client.conf.

ls -1 /usr/share/doc/openvpn-2.4.4/sample/sample-config-files/

Copy server.conf to /etc/openvpn and edit the file.

sudo cp /usr/share/doc/openvpn-2.4.4/sample/sample-config-files/server.conf /etc/openvpn/
sudo vim /etc/openvpn/server.conf

Adjust the path to the ca, cert, key and dh files

These parameters inform OpenVPN where the certificates and Keys are stored. The CA cert ca.crt is used to validate the client certificates. They must be issued by this CA. The server.crt and server.key are used by the OpenVPN server to encrypt traffic and authenticate itselfs against clients. Diffie hellman dh.pem is used to provide Perfect Forward Secrecy.

Start OpenVPN server

To start the OpenVPN server and to test the current setup, run the following command:

sudo openvpn /etc/openvpn/server.conf

During startup, you need to provide the passphrase of the server certificate.

If all works, OpenVPN starts without erros: Initialization Sequence Completed. After this, the server is waiting for clients to connect.

 

 

Note:

If someone is reading my blogs for the last years you may remember that I have once written about setting up OpenVPN for accessing SUP on AWS. That blog was all about Windows and is outdated. I wrote it in 2012. But, as I published it once at SAP Community Network, it is not available anymore. SAP lost it during their last migration.

OpenSSL CA to sign CSR with SHA256 – Sign CSR issued with SHA-256

The overall process is:

  1. Create CA
    1. Private CA key
      1. Create private key
      2. Check private key
    2. Public CA certificate
      1. Create public certificate
      2. Check public certificate
  2. Sign CSR
    1. SHA-1
      1. Create CSR using SHA-1
      2. Check CSR
      3. Sign CSR enforcing SHA-256
      4. Check signed certificate
    2. SHA-256
      1. Create CSR using SHA-256
      2. Check CSR
      3. Sign CSR
      4. Check signed certificate

Sign CSR request – SHA-256

When a CSR is created a signature algorithm can be specified. Currently, this should be SHA-256. Installing a TLS certificate that is using SHA-256 ensures that browsers like Chrome, Firefox, etc won`t show a security warning to the user. Signing the CSR using the CA is straight forward.

Create CSR using SHA-256

openssl req -out sha256.csr -new -newkey rsa:2048 -nodes -keyout sha256.key –sha256

The command creates two files: sha256.key containing the private key and sha256.csr containing the certificate request.

Check CSR

openssl req -verify -in sha256.csr -text -noout

The signature algorithm of the CSR is SHA-256

Sign CSR

Singing the CSR using the CA

openssl x509 -req -days 360 -in sha256.csr -CA ca.cert.pem -CAkey ca.key.pem -CAcreateserial -out sha256.crt

This will sign the CSR using SHA-256 as provided by CSR.

Check signed certificate

openssl x509 -text -noout -in sha256.crt

The certificate is signed using SHA-256.

 

 

 


Possible problem: the certificate may be signed using SHA-1.

Why is the certificate signed with SHA1? Without providing –sha256 parameter, openssl is using the default value. Depending on the version of openssl you are using, the default may be using SHA-1. This is the case when you use the default openssl binary available on MacOs.

openssl version –a

This version is old. Better to install a newer one using brew.

After updating, the default algorithm is SHA-256 and not SHA-1 anymore. In case you cannot update the default openssl binary, install a newer version to a different location and use that one.

OpenSSL CA to sign CSR with SHA256 – Sign CSR issued with SHA-1

The overall process is:

  1. Create CA
    1. Private CA key
      1. Create private key
      2. Check private key
    2. Public CA certificate
      1. Create public certificate
      2. Check public certificate
  2. Sign CSR
    1. SHA-1
      1. Create CSR using SHA-1
      2. Check CSR
      3. Sign CSR enforcing SHA-256
      4. Check signed certificate
    2. SHA-256
      1. Create CSR using SHA-256
      2. Check CSR
      3. Sign CSR
      4. Check signed certificate

Sign CSR request – SHA-1

When a CSR is created, a signature algorithm is used. Normally, this is SHA-1. Installing a TLS certificate that is using SHA-1 will give some problems, as SHA-1 is not considered secure enough by Google, Mozilla, and other vendors. Therefore, the final certificate needs to be signed using SHA-256. In case the CSR is only available with SHA-1, the CA can be used to sign CSR requests and enforce a different algorithm.

Create CSR using SHA-1

openssl req -out sha1.csr -new -newkey rsa:2048 -nodes -keyout sha1.key

The command creates two files: sha1.key containing the private key and sha1.csr containing the certificate request.

Check CSR

openssl req -verify -in sha1.csr -text -noout

The signature algorithm of the CSR is SHA-1

Sign CSR enforcing SHA-256

Singing the CSR using the CA

openssl x509 -req -days 360 -in sha1.csr -CA ca.cert.pem -CAkey ca.key.pem -CAcreateserial -out sha1.crt -sha256

This will sign the CSR using SHA-256.

Check signed certificate

openssl x509 -text -noout -in sha1.crt

The certificate`s signature algorithm is using SHA-256. The original CSR`s signature algorithm was SHA-1, but the resulting algorithm is now SHA-256. Even when you cannot change to SHA-256 during CSR creation, or the CSR is only available in SHA-1, it is still possible to change the SHA-256 during the signing process of the CA.

OpenSSL CA to sign CSR with SHA256 – Create CA

The overall process is:

  1. Create CA
    1. Private CA key
      1. Create private key
      2. Check private key
    2. Public CA certificate
      1. Create public certificate
      2. Check public certificate
  2. Sign CSR
    1. SHA-1
      1. Create CSR using SHA-1
      2. Check CSR
      3. Sign CSR enforcing SHA-256
      4. Check signed certificate
    2. SHA-256
      1. Create CSR using SHA-256
      2. Check CSR
      3. Sign CSR
      4. Check signed certificate

Create a CA

To have a private CA with openssl, at least two steps are need: you need to create a private key and a public certificate. The public certificate will be used to sign CSRs.

Private CA key

Create private key

openssl genrsa -aes256 -out ca.key.pem 4096

The command will generate a private key using random data and ask you to provide a pass phrase. While possible to enter an empty pass phrase, it is highly recommended to provide one. In my test case, I simply use “test”. Remember: it is not a password, but a phrase. If you want, go crazy and use a full sentence.

Check private key

This creates a pass phrase protected private key. The key is password protected. This can easily be seen by opening the key and checking for the —–BEGIN RSA PRIVATE KEY—– section.

To validate that everything is OK with the private key, openssl can be used

openssl rsa –in ca.key.pem -check

The output prints RSA key ok.

Public CA certificate

Create public certificate

openssl req -key ca.key.pem -new -x509 -days 5000 -sha256 -extensions v3_ca -out ca.cert.pem

You`ll need to inform the pass phrase of the private key as well as some additional administrational data like the location of the server.

This created a new certificate for the CA using the private key.

Check public certificate

openssl x509 -in ca.cert.pem -text -noout

The Signature Algoritm is using SHA-256.

Using the above two commands, a private key and public certificate with usage type for CA was created. This certificate can now be used to sign CSR requests.

Certificate pinning

Certificate pinning aims to close a trust problem that comes with PKI architecture: you trust the certificate authority (CA) and assume that the server is valid, because you trust the CA. Certificate pinning aims to ensure that you also can also trust the server. How is pinning going to achieve this? You know the certificates you are going to receive by the server, and validate those certificates with your local information. Sounds complicated, but it means that your client has all the certificates expected to receive from the server (CA certificate, intermediate certificate and server certificate) and when the server sends those certificates, they are all compared to the client’s locally stored ones. If one of those certificates do not match, client will not connect to server.

OWASP has some more useful information on this topic online available

Sometimes you are already using certificate pinning without knowing it. When you import the CA certificate of your enterprise CA into a keystore, you are already partly using certificate pinning. If you also import the certificate of the server to validate the complete chain, you are doing certificate pinning. iOS documentation contains little information on this topic, but with Google help you can find some projects that try to solve this on GitHub [1] [2] [3] [4]. Android developer guide contains a small section on pinning. Looking at the source code, you can see that a keystore containing only the expected certificates is created.

CertificateFactory cf = CertificateFactory.getInstance("X.509");
InputStream caInput = new BufferedInputStream(new FileInputStream("load-der.crt"));
Certificate ca = cf.generateCertificate(caInput);// Create a KeyStore containing our trusted CAsString keyStoreType = KeyStore.getDefaultType();
KeyStore keyStore = KeyStore.getInstance(keyStoreType);
keyStore.load(null, null);
keyStore.setCertificateEntry("ca", ca);

As you can see, certificate pinning is simple to do. A problem is that you need to be able to control the used keystore. This means that you cannot do real certificate pinning in a web only scenario. If your app is 100% HTML5 or a hybrid app, you won’t be able to use your own keystore. This is also true for Cordova apps, as here you are using the web browser to access the TLS secured service, and not a native client. The browser will trust those CAs that are configured for the browser. HTTP Public Key Pinning (HPKP) promises to gain back some of the trust of a native pinning implementation

HTTP Public Key Pinning

With HPKP, a server publishes a set of hashes of his certificates, and a client expects to receive certificates from the server that matches those hashes. In case a CA is compromised, or an attacker can create a false certificate, the fingerprint (hashes) of these certificates is expected to differ, and the client will then not open a connection to the server. Of course, in case the attacker can take of the web server (directly or indirectly), HPKP won’t help. The hashes for HPKP are communicated in a HTTP header: Public-Key-Pins.

There is a RFC for HPKP (RFC 7469), but don’t expect too much. IE/Edge don’t support it; Chromium browser don’t use HPKP for private root CAs. A weak point is the first request: Ensure that HPKP is only send by a secured connection (TLS). And to make HPKP make sense, on the first request, you must hope that the web server wasn’t compromised at that time. If so, you’ll already get an invalid hash. When the server certificate is updated, the hash must be recreated and included in the header. An article by Mozilla describes how to create the hash and how to set the header. Online tools to validate the generated hash are also available [1] [2]. Some tips on correct usage of HPKP can be found here.

Online Certificate Status Protocol

Online Certificate Status Protocol, or short: OCSP, let you obtain the revocation status of a certificate. It has some benefits over certification revocation lists, mainly that you can let the OCSP server do the heavy work of validating a certificate and the client gets some additional security when accepting the answer. To use OCSP in your landscape, you will have to install and configure an OCSP responder. I did this for my sandbox SMP3 system. Here are the links that contain the information on how to set up your own OCSP responder on your Microsoft CA server.

My walkthrough

Hope you find the links useful.

Additional OCSP information

Here are some more links that I consulted when setting up my OCSP responder. All are from Microsoft and treat information regarding OCSP on a Microsoft server and CA.

About

Implementing OCSP responder part 1 – introducing OCSP

OCSP installation and configuration

Designing and implementing a PKI part 2

Designing and implementing a PKI part 3

Designing and implementing a PKI part 4

Designing and implementing a PKI part 5

Windows Server

Online Responder Installation, Configuration, and Troubleshooting Guide

AD CS: Online Certificate Status Protocol Support

Configure a CA to Support OCSP Responders

OCSP part 4 – Configure CA to support OCSP Responders

After having the OCSP service installed and configured, the CA must be made aware of the service. Only after this, new emitted certificates by the CA will include the OCSP information. This means that you can run a OCSP service without having it included in the client certificates. In that case, clients can be configured to use a static OCSP address to validate the status of the certificate, while other clients won`t be able to do this.

To configure a CA to support an Online Responder or OCSP responder services

  • Open the Certification Authority snap-in.


  • Open the properties of the CA.

  • Open the extensions tab. By default, the CRL distribution point (CDP) list is shown.

  • Change from CDP to Authority Information Access (AIA)

  • Click on Add to add a new location.

  • Specify the locations from which users can obtain certificate revocation data. This is the URL under which the OCSP service is installed.Make sure that the clients can resolve the DNS name and communicate with the service.

    Example: http://<ServerDNSName>/ocsp

  • Select “Include in the online certificate status protocol (OCSP) extension”. This makes the OCSP URL available in the certificate.

    You will have to restart the CA service to make the new configuration effective.

  • Next, you will have to include the OCSP certificate in the list of available certificates of the CA.


  • Open the CA snap-in, select Certificate Templates, right click and choose “New Certificate Template to Issue”


  • Select the OCSP Response Signing certificate.

  • To check that it worked, select the certificate and open its properties.

OCSP part 3 – Add read permission to NetWork Service

For the CA to be able to use OCSP, read permission to the private key must be given.

Add Read permissions to Network Service on the private key

Open the Certificate Templates snap-in.

Select the OCSP Response Signing template.

Right-click it and click on properties.

Go to tab security. Click on add.

In the dialog, select from the list of object types computer.

Search for the CA/OCSP computer. Click OK.

Select the newly created entry with the computer name of the OCSP responder and select ALLOW for Read and Enroll permissions.

Finish the task by clicking on OK.

Verify certificate chain with OpenSSL

A good TLS setup includes providing a complete certificate chain to your clients. This means that your web server is sending out all certificates needed to validate its certificate, except the root certificate. This is best practice and helps you achieving a good rating from SSL Labs. In a normal situation, your server certificate is signed by an intermediate CA. With this, your complete certificate chain is composed of the Root CA, intermediate CA and server certificate.

You do get signed your certificate by an intermediate CA and not the Root CA, because the Root CA is normally an offline CA. As the name suggests, the server is offline, and is not capable of signing certificates. Its certificate is included into the build-in root CA list of clients (browsers).The intermediate CA is online, and it`s task is to sign certificates. Compared to the root CA, its own certificate is not included in the built-in list of certificates of clients. Of course, the web server certificate is also not part of this list. For a client to verify the certificate chain, all involved certificates must be verified. Server certificate by intermediate CA, which is verified by Root CA. Client already has the root CA certificate, and at least gets the server certificate. Missing certificate therefore is the one of the intermediate CA.

When a client connects to your server, it gets back at least the server certificate. To validate this certificate, the client must have the intermediate CA. For this, he will have to download it from the CA server. The root CA is pre-installed and can be used to validate the intermediate CA. Well, it should download. But not all server certificates include the necessary information, or the client cannot download the missing certificate (hello firewall!). In that case, it is not possible to validate the server`s certificate. Therefore the server should include the intermediate CA in the response.

Now the client has all the certificates at hand to validate the server. In case more than one intermediate CAs are involved, all the certificates must be included. The chain is N-1, where N = numbers of CAs.

Verify certificate chain with OpenSSL

Enough theory, let`s apply this IRL. Use OpenSSL to connect to a HTTPS server (using my very own one here in the example).

openssl.exe s_client -connect www.itsfullofstars.de:443

Output

Loading 'screen' into random state - done
CONNECTED(000001EC)
depth=1 C = IL, O = StartCom Ltd., OU = StartCom Certification Authority, CN = StartCom Class 1 DV Server CA
verify error:num=20:unable to get local issuer certificate
---
Certificate chain
0 s:/CN=www.itsfullofstars.de
i:/C=IL/O=StartCom Ltd./OU=StartCom Certification Authority/CN=StartCom Class1 DV Server CA
1 s:/C=IL/O=StartCom Ltd./OU=StartCom Certification Authority/CN=StartCom Class1 DV Server CA
i:/C=IL/O=StartCom Ltd./OU=Secure Digital Certificate Signing/CN=StartCom Certification Authority
---
Server certificate
-----BEGIN CERTIFICATE-----
MIIGJjCCBQ6gAwIBAgIQEH6ZTKIfC5k6iN7ERWeE9zANBgkqhkiG9w0BAQsFADB4sH+ryHeVQVMe4WxKH2nUKbTtE0ppeCQqXL1ExXXDCD1jANVy0pjlVNHbJJJq9voViyYWxhBveiaEJ02N/gOfgkawwIhYiE3Ur6DLlJh0ynXVuXSsRrV5zCI0
-----END CERTIFICATE-----
subject=/CN=www.itsfullofstars.de
issuer=/C=IL/O=StartCom Ltd./OU=StartCom Certification Authority/CN=StartCom Class 1 DV Server CA
---
No client certificate CA names sent
Peer signing digest: SHA512
Server Temp Key: ECDH, P-256, 256 bits
---
SSL handshake has read 4041 bytes and written 443 bytes
---
New, TLSv1/SSLv3, Cipher is ECDHE-RSA-AES256-GCM-SHA384
Server public key is 4096 bit
Secure Renegotiation IS supported
Compression: NONE
Expansion: NONE
No ALPN negotiated
SSL-Session:
Protocol : TLSv1.2
Cipher : ECDHE-RSA-AES256-GCM-SHA384
Session-ID: 2D5[…]2F0
Session-ID-ctx: Master-Key: 9D8[…]DCF
Key-Arg : None
PSK identity: None
PSK identity hint: None
SRP username: None
TLS session ticket lifetime hint: 300 (seconds)
TLS session ticket:
0000 - 3d 21 23 92 67 cc 97 a5-17 c5 09 9e 69 da ea 6d =!#.g.......i..m[…]
00b0 - ac fb 79 22 fc c6 fa 9b-ef c8 0e cb 6c 27 72 83 ..y"........l'r.
Start Time: 1455216192
Timeout : 300 (sec)
Verify return code: 20 (unable to get local issuer certificate)
---

If you cannot interpret the result: it failed. Verify return code:20 means that openssl is not able to validate the certificate chain. The certificate chain can be seen here:

  • 0: the certificate of the server
  • 1: the certificate of the CA that signed the servers certificate (0)
  • s: is the name of the server, while I is the name of the signing CA. To get a clearer understanding of the chain, take a look at how this is presented in Chrome:

The certificates send by my server include its own and the StartCom Class 1 DV Server CA.

Server certificate:

StartCom Class 1 DV Server CA

Missing: Root CA: StartCom Certificate Authority. This is the Root CA and already available in a browser. It`s not available in OpenSSL, as the tool comes without a list of trusted CAs. To “install” the root CA as trusted, OpenSSL offers two paramters:

  • CAfile. Point to a single certificate that is used as trusted Root CA
  • CApath. Point to a directory with certificates going to be used as trusted Root CAs.

I will use the CAfile parameter. For this, I`ll have to download the CA certificate from StartSSL (or via Chrome).

openssl.exe s_client -connect www.itsfullofstars.de:443 -CAfile startssl_rootca.cer

Output

Loading 'screen' into random state - done
CONNECTED(000001EC)
depth=2 C = IL, O = StartCom Ltd., OU = Secure Digital Certificate Signing, CN =StartCom Certification Authority
verify return:1
depth=1 C = IL, O = StartCom Ltd., OU = StartCom Certification Authority, CN = StartCom Class 1 DV Server CA
verify return:1
depth=0 CN = www.itsfullofstars.de
verify return:1
---
Certificate chain
0 s:/CN=www.itsfullofstars.de
i:/C=IL/O=StartCom Ltd./OU=StartCom Certification Authority/CN=StartCom Class1 DV Server CA
1 s:/C=IL/O=StartCom Ltd./OU=StartCom Certification Authority/CN=StartCom Class1 DV Server CA
i:/C=IL/O=StartCom Ltd./OU=Secure Digital Certificate Signing/CN=StartCom Certification Authority
---
Server certificate
-----BEGIN CERTIFICATE-----
MIIGJjCCBQ6gAwIBAgIQEH6ZTKIfC5k6iN7ERWeE9zANBgkqhkiG9w0BAQsFADB4sH+ryHeVQVMe4WxKH2nUKbTtE0ppeCQqXL1ExXXDCD1jANVy0pjlVNHbJJJq9voViyYWxhBveiaEJ02N/gOfgkawwIhYiE3Ur6DLlJh0ynXVuXSsRrV5zCI0
-----END CERTIFICATE-----
subject=/CN=www.itsfullofstars.de
issuer=/C=IL/O=StartCom Ltd./OU=StartCom Certification Authority/CN=StartCom Class 1 DV Server CA
---
No client certificate CA names sent
Peer signing digest: SHA512
Server Temp Key: ECDH, P-256, 256 bits
---
SSL handshake has read 4041 bytes and written 443 bytes
---
New, TLSv1/SSLv3, Cipher is ECDHE-RSA-AES256-GCM-SHA384
Server public key is 4096 bit
Secure Renegotiation IS supported
Compression: NONE
Expansion: NONE
No ALPN negotiated
SSL-Session:
Protocol : TLSv1.2
Cipher : ECDHE-RSA-AES256-GCM-SHA384
Session-ID: 9[…]43
Session-ID-ctx: Master-Key: 4C[…]2D
Key-Arg : None
PSK identity: None
PSK identity hint: None
SRP username: None
TLS session ticket lifetime hint: 300 (seconds)
TLS session ticket:
0000 - 3d 21 23 92 67 cc 97 a5-17 c5 09 9e 69 da ea 6d =!#.g.......i..m
0010 - fc 05 be 96 ce bd 98 d6-d0 80 f9 67 1c 09 8c 4a ...........g...J
00b0 - 3a c2 73 77 e3 40 ab 22-84 1b f2 6a 5a 4a 8e 68 :.sw.@."...jZJ.h
Start Time: 1455217879
Timeout : 300 (sec)
Verify return code: 0 (ok)
---

Return code is 0. Now it worked. OpenSSL was able to validate all certificates and the certificate chain is working.

More resources

https://community.qualys.com/docs/DOC-1931

https://www.openssl.org/docs/manmaster/apps/verify.html