14 August 2012

Create SSL self signed certificate using with Apache and Windows IIS

You have a website which uses form-login to authenticate users, so you will need to run https to protect the user credential (username/password) agains of snippers on the internet. This post will show you how to create self signed certificate using with apache and IIS.

Requirement :

  • Understanding of ssl Private | Public Key infrastructure.

Alternative software :

  • This post is based on Linux system and did use openssl package for deploying.
  • If you are not familiar with Linux stuff, you can download openssl edition for Windows, it will work as the same on Linux.

Primary steps :

  1. Test playing https with Gmail. 
  2. Create self signed Certificate. 
  3. Apply config to Apache server. 
  4. Apply config to Windows 2003 IIS server. 


Steps in detail :

1. Test playing https with Gmail.

Let's see what happen when playing https with GMail.

Client# curl -v https://mail.google.com

* About to connect() to mail.google.com port 443
* Connected to mail.google.com port 443
* successfully set certificate verify locations:
* CAfile: /etc/pki/tls/certs/ca-bundle.crt
CApath: none
* SSLv2, Client hello (1):
* ...
* Server certificate:
* subject: /C=US/ST=California/L=Mountain View/O=Google Inc/CN=mail.google.com
* start date: 2011-10-26 00:00:00 GMT
* expire date: 2013-09-30 23:59:59 GMT
* common name: mail.google.com (matched)
* issuer: /C=ZA/O=Thawte Consulting (Pty) Ltd./CN=Thawte SGC CA
* SSL certificate verify ok.

Well, as you see GMail uses certificate provided by Thawte CA :
  • Subject : it looks like the one who uses certificate (the buyer). 
  • Issuer : the ssl certificate provider (the seller). 
Let find about Thawte in the ca-bundle.crt file.

Client# grep -i thawte /etc/pki/tls/certs/ca-bundle.crt 

Issuer: C=ZA, ST=Western Cape, L=Cape Town, O=Thawte Consulting, OU=Certification Services Division, CN=Thawte Personal Basic CA/emailAddress=personal-basic@thawte.com
Subject: C=ZA, ST=Western Cape, L=Cape Town, O=Thawte Consulting, OU=Certification Services Division, CN=Thawte Personal Basic CA/emailAddress=personal-basic@thawte.com
Issuer: C=ZA, ST=Western Cape, L=Cape Town, O=Thawte Consulting, OU=Certification Services Division, CN=Thawte Personal Premium CA/emailAddress=personal-premium@thawte.com
Subject: C=ZA, ST=Western Cape, L=Cape Town, O=Thawte Consulting, OU=Certification Services Division, CN=Thawte Personal Premium CA/emailAddress=personal-premium@thawte.com

Very clearly, the default CAfile has alot of info about Thawte CA.

2. Let's make our self signed certificate for running https.

Generate Private key file.

Server# openssl genrsa -out Key.pem 1024

Generating RSA private key, 1024 bit long modulus
..........++++++
..............................................++++++
e is 65537 (0x10001)

Have a look on it

Server# cat Key.pem

-----BEGIN RSA PRIVATE KEY-----
MIICWwIBAAKBgQC708V/HVEbmH3CxdZTD96NkMxxuAzasy1eT81dC1RYKrvBLGMP
...
yx5FwwqkeWq0D8LUai4cSYjP4THEwET5MjiFdU6Wgw==
-----END RSA PRIVATE KEY-----

Of course, it is different with your file.

Generate the Certificate file with the uppon Private Key.

Server# openssl req -out Certificate.pem -key Key.pem -new -x509 -days 3650

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) [GB]:US
State or Province Name (full name) [Berkshire]:
Locality Name (eg, city) [Newbury]:
Organization Name (eg, company) [My Company Ltd]:
Organizational Unit Name (eg, section) []:
Common Name (eg, your name or your server's hostname) []:www.linuxbyexamples.net
Email Address []:admin@linuxbyexamples.net

Notice to enter your full server domain name.

Have a look on it

Server# cat Certificate.pem 

-----BEGIN CERTIFICATE-----
MIIDsjCCAxugAwIBAgIJAO+6byB+ZPZTMA0GCSqGSIb3DQEBBQUAMIGYMQswCQYD
...
Jpw/uvJzn/NYxRzblB513vUFoqnc0sjGOxEFipNIfyE8ppTQpPA=
-----END CERTIFICATE-----

Let's see the human-readabled information in the Certificate file.

Server# openssl x509 -pubkey -subject -issuer -email -dates -noout -in Certificate.pem

-----BEGIN PUBLIC KEY-----
MIGfMA0GCSqGSIb3DQEBAQUAA4GNADCBiQKBgQC708V/HVEbmH3CxdZTD96NkMxx
...
TWWbwQLZlgjm0dyLMQIDAQAB
-----END PUBLIC KEY-----
subject= /C=US/ST=Berkshire/L=Newbury/O=My Company Ltd/CN=www.linuxbyexamples.net/emailAddress=admin@linuxbyexamples.net
issuer= /C=US/ST=Berkshire/L=Newbury/O=My Company Ltd/CN=www.linuxbyexamples.net/emailAddress=admin@linuxbyexamples.net
admin@linuxbyexamples.net

As you can see, the Subject (buyer) and the Issuer (provider) are identical.

Now we have the 2 files :
  1. The Private Key file : Key.pem
  2. The Certificate file (include the Public Key equivalent to the Private Key). 
Verify it.

Server# openssl verify -verbose -CAfile Certificate.pem Certificate.pem

Certificate.pem: OK

3. Apply config to the httpd (apache) server.

Check if the apache server has support for ssl.

Server# rpm -qa | grep mod_ssl

mod_ssl-2.2.3-65

If not, install mod_ssl by yum.

Server# yum install mod_ssl

Point the mod_ssl config to use the 2 above files.

Server# vim /etc/httpd/conf.d/ssl.conf

SSLCertificateFile /etc/httpd/conf.d/Certificate.pem
SSLCertificateKeyFile /etc/httpd/conf.d/Key.pem

Reload the service httpd.

Server# /etc/init.d/httpd reload

Reloading httpd: [ OK ]

Check if the https port 443 has open.

Server# netstat -pnat | grep :443

tcp 0 0 :::443 :::* LISTEN 1711/httpd

Connect from the client.

Using curl.

Client# curl -v https://10.254.10.30

* About to connect() to 10.254.10.30 port 443 (#0)
* Trying 10.254.10.30...
* connected
* Connected to 10.254.10.30 port 443 (#0)
* Initializing NSS with certpath: sql:/etc/pki/nssdb
* CAfile: /etc/pki/tls/certs/ca-bundle.crt
CApath: none
* Certificate is signed by an untrusted issuer: 'E=admin@linuxbyexamples.net,CN=www.linuxbyexamples.net,O=My Company Ltd,L=Newbury,ST=Berkshire,C=US'
* NSS error -8172 (SEC_ERROR_UNTRUSTED_ISSUER)
* Closing connection #0
* Peer certificate cannot be authenticated with given CA certificates
curl: (60) Peer certificate cannot be authenticated with given CA certificates
More details here: http://curl.haxx.se/docs/sslcerts.html

Yep, of course it will error because your Cert is not included in the ca-bundle.crt.

Using s_client.

Client# openssl s_client -quiet -connect 10.254.10.30:443

depth=0 C = US, ST = Berkshire, L = Newbury, O = My Company Ltd, CN = www.linuxbyexamples.net, emailAddress = admin@linuxbyexamples.net
verify error:num=18:self signed certificate
verify return:1
depth=0 C = US, ST = Berkshire, L = Newbury, O = My Company Ltd, CN = www.linuxbyexamples.net, emailAddress = admin@linuxbyexamples.net
verify return:1

Using Firefox.


You can always bypass this warning by chosing Add Exception / Permanently Store the Certificate.

So, all the 3 ways above (curl, s_client, firefox) will get Certificate Error/Warning Message because you used a self-signed Certificate. But you can always bypass the Warning Message at anytime and https will work fine.

Self-signed Certificates are appropriate for internal/local using only, client users have to manually import the certificate in order to bypass the warning message. If your website is public to the internet and you want to run https at your site, you need to buy SSL Certificates from some vendors like : Verisign, Thawte, ...

Next to Part 2 >>