Showing posts with label ssl. Show all posts
Showing posts with label ssl. Show all posts

Saturday, 2 June 2018

How to create a Self-Signed SSL certificate with Subject Alternate Names - SAN

In this post, I want to record the steps to generate a self-signed SSL/TLS certificate with SAN extentions.
This is becoming important as may of the modern browsers now check the SAN section rather than the CN common name for the certificate subject.

To begin, lets generate our root CA certificate:
openssl genrsa -out selfca.key 2048

Then we create the root CA:
[root@localhost ~]# openssl req -x509 -key selfca.key -sha256 -days 2000 -out selfca.crt
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) [XX]:NL    
State or Province Name (full name) []:Noord Holland
Locality Name (eg, city) [Default City]:Amsterdam
Organization Name (eg, company) [Default Company Ltd]:SHERIF Ltd
Organizational Unit Name (eg, section) []:IT
Common Name (eg, your name or your server's hostname) []:IT Root CA
Email Address []:
[root@localhost ~]#


Next we create our website private key:
openssl genrsa -out www.sherif.site.key 2048


And then we generate a CSR (certificate signing request):
[root@localhost ~]# openssl req -out www.sherif.site.csr -key www.sherif.site.key -new
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) [XX]:EG
State or Province Name (full name) []:Cairo
Locality Name (eg, city) [Default City]:Cairo
Organization Name (eg, company) [Default Company Ltd]:SHERIF Ltd
Organizational Unit Name (eg, section) []:IT
Common Name (eg, your name or your server's hostname) []:www.sherif.site
Email Address []:root@sherif.site

Please enter the following 'extra' attributes
to be sent with your certificate request
A challenge password []:
An optional company name []:
[root@localhost ~]#


Then we sign the certificate and we are done:
[root@localhost ~]# openssl x509 -req -in www.sherif.site.csr -CA selfca.crt -CAkey selfca.key -CAcreateserial -out mydomain.com.crt -days 720 -sha256
Signature ok
subject=/C=EG/ST=Cairo/L=Cairo/O=SHERIF Ltd/OU=IT/CN=www.sherif.site/emailAddress=root@sherif.site
Getting CA Private Key
[root@localhost ~]#



Now lets check the certificate, we can clearly see the information of the CA and also for the certificate owner, but there is no SAN information in the certificate.
[root@localhost ~]# openssl x509 -in www.sherif.site.crt -text -noout
Certificate:
    Data:
        Version: 1 (0x0)
        Serial Number:
            c8:4b:f0:5d:26:4a:18:4b
    Signature Algorithm: sha256WithRSAEncryption
        Issuer: C=NL, ST=Noord Holland, L=Amsterdam, O=SHERIF Ltd, OU=IT, CN=ROOT CA
        Validity
            Not Before: Jun  2 12:18:17 2018 GMT
            Not After : May 22 12:18:17 2020 GMT
        Subject: C=EG, ST=Cairo, L=Cairo, O=SHERIF Ltd, OU=IT, CN=www.sherif.site/emailAddress=root@sherif.site
        Subject Public Key Info:
            Public Key Algorithm: rsaEncryption
                Public-Key: (2048 bit)
                Modulus:
                    00:c6:d6:c3:96:6d:0f:b2:63:74:d6:04:7a:2c:c1:
                    e3:bd:6d:6e:0a:89:a4:14:83:de:e6:d9:e9:4b:f1:
                   .....


Adding SAN information:


Now lets try to create a certificate using multiple SAN (Subject alternate names).
To do this, we need to pass the openssl command a customized configuration file while we are generating the CSR.
Below is an example file:

[root@localhost ~]# cat san_config.cfg
[ req ]
default_bits            = 2048
default_md              = sha256
default_keyfile         = privkey.pem
distinguished_name      = req_distinguished_name
x509_extensions = v3_ca # The extensions to add to the self signed cert

prompt = no
string_mask = utf8only

[ req_distinguished_name ]
countryName             = XX
stateOrProvinceName     = State
localityName            = Default City
0.organizationName      = Default Company Ltd
organizationalUnitName  = Unit
commonName              = localhost
emailAddress            = root@localhost

[ v3_ca ]
basicConstraints = CA:FALSE
keyUsage = nonRepudiation, digitalSignature, keyEncipherment
subjectAltName=@alternate_names

[alternate_names ]
DNS.1        = www
DNS.2        = fingon
DNS.3        = Fingon
[root@localhost ~]#


The file serves 2 purposes, it will automatically fill the CSR question form for us using the values above and will also introduce the SAN extensions to the certificate.
To use this file we add the -config parameter to the openssl command to generate the CSR:

openssl req -out www.sherif.site.csr -key www.sherif.site.key -new -config san_config.cfg

Then we also add the the -extfile & -extensions parameters to the openssl command to generate the certificate:

openssl x509 -req -in www.sherif.site.csr -CA selfca.crt -CAkey selfca.key -CAcreateserial -out www.sherif.site.san.crt -days 720 -sha256 -extfile ./san_config.cfg -extensions 'v3_ca'

Once the Certificate is created, we can check the alternate names section we configured:

[root@localhost ~]# openssl x509 -in www.sherif.site.san.crt -text -noout|grep -i -A3 -B6 fin
        X509v3 extensions:
            X509v3 Basic Constraints:
                CA:FALSE
            X509v3 Key Usage:
                Digital Signature, Non Repudiation, Key Encipherment
            X509v3 Subject Alternative Name:
                DNS:www, DNS:fingon, DNS:Fingon
    Signature Algorithm: sha256WithRSAEncryption
         a5:e2:a5:89:76:f4:59:ed:46:46:a7:6e:76:ab:ab:ee:e2:cd:
         ef:c9:c4:22:f8:93:92:26:f3:87:51:cd:e7:e7:b5:4e:73:fb:
[root@localhost ~]#

This ensures that all subject alternative names are added to the certificate.

Enjoy SSL 👌

Friday, 9 March 2018

How to check Client SSL cert from certain IPs only


Lately, I had a requirement to configure Apache reverse proxy in such a way to ensure any user logging through the Apache reverse proxy is presenting a valid client certificate if they are not internal users.

Internal users using local network IPs and local domain names should be allowed to access without any certificate validation.

To achieve this, we can use the below simple construct if we are using Apache 2.4.x:


<If "%{REMOTE_ADDR} !~ /^127.0.0.1$/ && %{REMOTE_ADDR} !~ /^192.168.[0-9]+.[0-9]+$/">
        SSLVerifyClient require
        SSLVerifyDepth 2
</If>

In case we are using Apache 2.2, the config needs to involve mod_rewrite as below:

SSLVerifyClient optional

SSLVerifyDepth  2
<Location / >
        Order deny,allow
        Deny from all
        Satisfy any
        Allow from ALL
        RewriteEngine on
        RewriteCond %{SSL:SSL_CLIENT_VERIFY} !^SUCCESS$
        RewriteCond %{REMOTE_ADDR} !^127.0.0.1$
        RewriteCond %{REMOTE_ADDR} !^192.168.1.[1-9]+$
        RewriteRule   ^  -  [F]
</Location>

Using SSL verifyclient optional will still try to verify clients but will not block their access.
This, allows us to test if the verification worked or not with mod_rewrite as seen above.

Wednesday, 13 July 2016

Fixing Docker SSL problems in Centos

I have been blocked by SSL issues and unable to use docker for quite a while now.
I did some reading and found out some useful info in OpenSSL documentation and on a user blog about docker.

The issue is my company uses its own SSL cert to re-encrypt all SSL traffic after it is filtered in the company internal network.
The Root CA cert is not trusted by all browsers and tools thus needs to be imported to make your life less painful :)

To import a cert on Centos we need to save it under the below path:

/usr/share/pki/ca-trust-source/anchors

The anchors folder should contain certs that are in PEM format.
Once the cert is saved, you need to run the command:

 update-ca-trust

This will update the system wide trust store at:

/etc/pki/ca-trust/extracted/openssl/ca-bundle.trust.crt

This file is linked under:

/etc/ssl/certs

Once this is done.

you need to follow the steps in this wiki:
http://richmegginson.livejournal.com/27936.html

In my case, the steps are:


 cd /etc/docker/certs.d
 mkdir dseab33srnrn.cloudfront.net
 cd dseab33srnrn.cloudfront.net
 ln -s /etc/pki/ca-trust/extracted/openssl/ca-bundle.trust.crt
 systemctl restart docker

Each time a docker pull is needed from a certain web host, we need to execute the last part of the steps so that docker can trust the cert.

Thanks for Rich Meggisnson for solving this issue by looking up the docker code.