SSL Client Side Cert

Summary of Certificate keywords

CSR = Certificate SIgning Request = Common Certificate Information + Public key

CRT = SSL certificate = CSR signed by Certificate Authority = CA (CSR)

Key = Private key

PEM = Union (CSR | CRT | Key)

CSR

What is a CSR? A CSR or Certificate Signing request is a block of encrypted text that is generated on the server that the certificate will be used on. It contains information that will be included in your certificate such as your organization name, common name (domain name), locality, and country. It also contains the public key that will be included in your certificate. A private key is usually created at the same time that you create the CSR.

A certificate authority will use a CSR to create your SSL certificate, but it does not need your private key. You need to keep your private key secret. What is a CSR and private key good for if someone else can potentially read your communications? The certificate created with a particular CSR will only work with the private key that was generated with it. So if you lose the private key, the certificate will no longer work.

.csr

This is a Certificate Signing Request. Some applications can generate these for submission to certificate-authorities. The actual format is PKCS10 which is defined in RFC 2986. It includes some/all of the key details of the requested certificate such as subject, organization, state, whatnot, as well as the public key of the certificate to get signed. These get signed by the CA and a certificate is returned. The returned certificate is the public certificate (which includes the public key but not the private key), which itself can be in a couple of formats.

.pem

Defined in RFC's 1421 through 1424, this is a container format that may include just the public certificate (such as with Apache installs, and CA certificate files /etc/ssl/certs), or may include an entire certificate chain including public key, private key, and root certificates. Confusingly, it may also encode a CSR (e.g. as used here) as the PKCS10 format can be translated into PEM. The name is from Privacy Enhanced Mail (PEM), a failed method for secure email but the container format it used lives on, and is a base64 translation of the x509 ASN.1 keys.

.key

This is a PEM formatted file containing just the private-key of a specific certificate and is merely a conventional name and not a standardized one. In Apache installs, this frequently resides in /etc/ssl/private. The rights on these files are very important, and some programs will refuse to load these certificates if they are set wrong.

.pkcs12 .pfx .p12

Originally defined by RSA in the Public-Key Cryptography Standards, the "12" variant was enhanced by Microsoft. This is a passworded container format that contains both public and private certificate pairs. Unlike .pem files, this container is fully encrypted. Openssl can turn this into a .pem file with both public and private keys: openssl pkcs12 -in file-to-convert.p12 -out converted-file.pem -nodes

CA, server and client certificate setup

Execute all certificate generation commands on any single machine, to be deemed as CA

Certificate authority creation

$ export CA_SUBJECT='/C=IN/ST=Karnataka/L=Bengaluru/CN=ca'

$ openssl genrsa -out ca.key 4096

$ openssl req -new -x509 -days 365 -key ca.key -out ca.crt -subj "$CA_SUBJECT"

Server certificate creation

Here server is HAProxy node as SSL terminates over HAProxy.

$ export SERVER_SUBJECT='/C=IN/ST=Karnataka/L=Bengaluru/CN=haproxy'

$ openssl genrsa -out server.key 1024

$ openssl req -new -key server.key -out server.csr -subj "$SERVER_SUBJECT"

$ openssl x509 -req -days 365 -in server.csr -CA ../ca/ca.crt -CAkey ../ca/ca.key -set_serial 01 -out server.crt

Client1 certificate creation

Here client should be understood as Sensor

$ export CLIENT1_SUBJECT='/C=IN/ST=Karnataka/L=Bengaluru/CN=backend1'

$ openssl genrsa -out client1.key 1024

$ openssl req -new -key client1.key -out client1.csr -subj "$CLIENT1_SUBJECT"

$ openssl x509 -req -days 365 -in client1.csr -CA ../ca/ca.crt -CAkey ../ca/ca.key -set_serial 02 -out client1.crt

# Browsers generally want a .p12 file, so we should generate one as well:

$ openssl pkcs12 -export -clcerts -in client1.crt -inkey client1.key -out client1.p12

Client2 certificate creation

$ export CLIENT2_SUBJECT='/C=IN/ST=Karnataka/L=Bengaluru/CN=backend2'

$ openssl genrsa -out client2.key 1024

$ openssl req -new -key client2.key -out client2.csr -subj "$CLIENT2_SUBJECT"

$ openssl x509 -req -days 365 -in client2.csr -CA ../ca/ca.crt -CAkey ../ca/ca.key -set_serial 02 -out client2.crt

Package server certificate and private key in a pem file

$ cat server.crt server.key > server.pem

Copy server pem file over HAProxy

$ scp server.pem root@1.0.0.5:/etc/haproxy/server.pem

Copy CA certificate over HAProxy

This CA certificate would be used for client certificate validation

$ scp ca.crt root@1.0.0.5:/etc/haproxy/ca.crt

Add HAProxy SSL config

sudo vi /etc/haproxy/haproxy.cfg

frontend http-in

mode http

bind *:443 ssl crt /etc/haproxy/server.pem ca-file /etc/haproxy/ca.crt verify required

default_backend servers

reqadd X-Forwarded-Proto:\ https if { ssl_fc }

option forwardfor

Restart HAProxy

sudo service haproxy restart

Test the SSL connection using curl

Execute from client node

$ curl -vk --key client1.key --cert client1.crt https://1.0.0.5/whoami.html

Test the SSL connection using openssl from client

$ openssl s_client -connect 1.0.0.5:443 -cert ./client1.crt -key client1.key

CA, Intermediate CA, server and client certificate setup

Certificate authority creation

$ cd certinter\ca

$ export CA_SUBJECT='/C=IN/ST=Karnataka/L=Bengaluru/CN=ca'

$ openssl genrsa -out ca.key 4096

$ openssl req -new -x509 -nodes -sha1 -days 365 -key ca.key -out ca.crt -subj "$CA_SUBJECT"

Intermediate Certificate authority creation

$ cd certinter\cainter

$ export CAINTER_SUBJECT='/C=IN/ST=Karnataka/L=Bengaluru/CN=cainter'

$ openssl genrsa -out cainter.key 4096

$ openssl req -new -sha1 -key cainter.key -out cainter.csr -subj "$CAINTER_SUBJECT"

Server certificate creation

Here server is HAProxy node as SSL terminates over HAProxy.

$ cd certinter\server

$ export SERVER_SUBJECT='/C=IN/ST=Karnataka/L=Bengaluru/CN=server'

$ openssl genrsa -out server.key 1024

$ openssl req -new -key server.key -out server.csr -subj "$SERVER_SUBJECT"

$ openssl x509 -req -days 365 -in server.csr -CA ../cainter/cainter.crt -CAkey ../cainter/cainter.key -set_serial 01 -out server.crt

Client1 certificate creation

Here client should be understood as Sensor

$ cd certinter\client1

$ export CLIENT1_SUBJECT='/C=IN/ST=Karnataka/L=Bengaluru/CN=client1'

$ openssl genrsa -out client1.key 1024

$ openssl req -new -key client1.key -out client1.csr -subj "$CLIENT1_SUBJECT"

$ openssl x509 -req -days 365 -in client1.csr -CA ../cainter/cainter.crt -CAkey ../cainter/cainter.key -set_serial 02 -out client1.crt

Package server certificate and private key in a pem file

$ cat server.crt server.key > server.pem

Copy server pem file over HAProxy

$ scp server.pem root@1.0.0.5:/etc/haproxy/cainter/server.pem

Create the certificate chain file

$ cat cainter.crt ../ca/ca.crt > cainter.chain

Copy CA Intermediate certificate over HAProxy

This CA certificate would be used for client certificate validation

$ scp cainter.crt root@1.0.0.5:/etc/haproxy/cainter/cainter.crt

$ scp cainter.chain root@1.0.0.5:/etc/haproxy/cainter/cainter.chain

References:

Github

Client side certificate information in HTTP Headers

SSL certificate with HAProxy, SSL Termination and Passthrough

SSL Termination with HAProxy

HTTPS HSTS, thanks to HAProxy

Setup HAProxy

HAProxy client side ssl certificates

Client side certificate Auth

Common Openssl commands

What is PEM file

OpenSSL essentials, working with SSL certificates

Create CA, client\server certificate and test on Apache

SSH over SSL

Create SSL tunnel using Stunnel

SSL with client side certificate HAProxy setup

SSL over HTTPS through HAProxy

Use HAProxy to tunnel SSH through https

Client Certificate Management