Monday, January 26, 2015

One with System Administration

If you work for a company with existing certificate authority, or have service from any of big players – lucky you. Just look this through and get all necessary certificates with CLR and OCSP parts in it.
If you are not so lucky, you need to issue certificates:
  • Old system with SSLv3/TLSv1 support to expose our application
  • Codebase server with latest TLSv1.1 and TLSv1.2 support to publish our Forms/applets.
  • Personal certificate to sign Java libraries
Before we issue any new certificates, reconfigure CA settings.  Java 8 requires every verification for certificate with CRL (Certificate Revocation Lists) and with modern OCSP (Online Certificate Online Status) protocol.  I am going to skip OCSP server configuration (Latest OpenSSL versions allow implement it. Here is a good article).

Certificate Authority preparation

Locate OpenSSL default configuration file /usr/local/openssl.cf and add information in section:
[ usr_cert ]
crlDistributionPoints = URI:https://apps.vb.mmikhail.com:445/crl/crl.pem


and  
[ v3_ca ]
crlDistributionPoints = URI:https://apps.vb.mmikhail.com:445/crl/crl.pem


Of course, you should use your own server name. Save CA configuration and issue some certificates.

Server Certificates

I am going to create new virtual host with TLS 1.2 and of course it requires new certificate.
Create new certificate request for new virtual host name:
[root@rhas48 ~]# openssl req -new -nodes -newkey 2048 -days 1846 -sha1 -out sslCA/apps-demo-crq.pem -keyout sslCA/pps-demo-key.pem
Generating a 2048 bit RSA private key
..........................................................+++
.............................................+++
writing new private key to 'apps-demo-key.pem'
-----
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) [Florida]:
Locality Name (eg, city) [Naples]:
Organization Name (eg, company) [mmikhail]:
Organizational Unit Name (eg, section) []:
Common Name (e.g. server FQDN or YOUR name) []:apps.vb.mmikhail.com
Email Address []:


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


Sign new request and issue certificate:
[root@rhas48 ~]# openssl ca -in sslCA/apps-demo-crq.pem -out sslCA/apps-demo-crt.pem -md sha1 -days 1826
Using configuration from /usr/local/openssl/openssl.cnf
Enter pass phrase for /root/sslCA/private/cakey.pem:
Check that the request matches the signature
Signature ok
Certificate Details:
..........
Certificate is to be certified until Jan 24 18:44:11 2020 GMT (1826 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
[root@rhas48 ~]#


We already have certificate for server name, revoke the previous one and reissue certificate with additional fields.
[root@rhas48 ~]# openssl ca -revoke sslCA/rhas48-sha1-crt.pem
Using configuration from /usr/local/openssl/openssl.cnf
Enter pass phrase for /root/sslCA/private/cakey.pem:
Revoking Certificate 1004.
Data Base Updated
[root@rhas48 ~]#


I use the very same request to issue new certificate:
[root@rhas48 ~]# openssl ca -in apps-demo-crq.pem -out apps-demo-crt.pem -md sha1 -days 1826
Using configuration from /usr/local/openssl/openssl.cnf
Enter pass phrase for /root/sslCA/private/cakey.pem:
Check that the request matches the signature
Signature ok
Certificate Details:
.........

Certificate is to be certified until Jan 24 18:44:11 2020 GMT (1826 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
[root@rhas48 ~]#


Copy new certificates and keys to Apache configuration directory (I use old configuration directory in /etc/httpd but you free to choose any).
[root@rhas48 ~]# cp  sslCA/apps-demo-crt.pem sslCA/apps-demo-key.pem /etc/httpd/conf/
[root@rhas48 ~]# cp  sslCA/rhs48-crt.pem sslCA/rhas48-key.pem /etc/httpd/conf/


Revocation List publication


Now we need to create certificate revocation list. It’s simple operation and for production purposes you need update revocation list. Local address for CRL file is /usr/local/apache2/htdocs/crl/crl.pem
[root@rhas48 ~]# mkdir –p /usr/local/apache2/htdocs/crl
[root@rhas48 ~]# openssl ca -keyfile sslCA/private/cakey.pem -cert sslCA/cacert.pem -gencrl -out /usr/local/apache2/htdocs/crl/crl.pem
Using configuration from /usr/local/openssl/openssl.cnf
Enter pass phrase for sslCA/private/cakey.pem:
[root@rhas48 ~]#


We are about to change Apache configuration.

Virtual Hosts configuration.


My goal is simulate the situation when you have one production server with SSLv3 and TLSv1 support and new virtual host to meet modern high security requirements. Here is my application configuration file /usr/local/apache2/config/apex/apex.conf below and quick explanation right here:


  • Virtual host on port 80 defines permanent redirect to protected server.
  • Virtual host on port 443 describes reverse proxy access to old business application (Oracle APEX 10g). To simulate old Web applications there is only SSLv3 and TLSv1 protocols allowed.
  • Listen port 445 to enable different TLS protocols on the same Apache instance and different server name. We need this port because with named virtual hosts you will have single SSL enabled port with common protocol versions. I am going to use this virtual host for CRL publications and as code base for applets in business applications.
<VirtualHost *:80>
 RewriteEngine On
 RewriteCond %{HTTPS} off
 RewriteRule (.*) https://%{HTTP_HOST}%{REQUEST_URI}
 Redirect permanent / https://%{HTTP_HOST}%{REQUEST_URI}
</VirtualHost>
<IfModule ssl_module>


<VirtualHost *:443>
   SSLEngine on
DocumentRoot "/usr/local/apache2/htdocs"
ServerName rhas48.vb.mmikhail.com
SSLCertificateFile "/etc/httpd/conf/rhas48-sha1-cert.pem"
SSLCertificateKeyFile "/etc/httpd/conf/rhas48-key.pem"
ServerAdmin me@mmikhail.com
       SSLProtocol  SSLv3 TLSv1
ErrorLog /var/log/httpd/apex-error_log
CustomLog /var/log/httpd/apex-access_log common
RewriteEngine On
RewriteRule ^/$ /apex/f?p=4500:1000 [R=301]
ProxyRequests On
<Proxy *>
Order allow,deny
Allow from all
</Proxy>
ProxyPass / http://localhost:8080/
ProxyPassReverse / http://localhost:8080/
</VirtualHost>


Listen 445
<VirtualHost *:445>
   SSLEngine on
   SSLProtocol TLSv1.2
SSLCertificateFile "/etc/httpd/conf/apps-crt.pem"
SSLCertificateKeyFile "/etc/httpd/conf/apps-key.pem"


DocumentRoot "/usr/local/apache2/htdocs"
ServerName apps.vb.mmikhail.com
ServerAdmin me@mmikhail.com
</VirtualHost>
</IfModule>


Before apply new configuration, I also made some changes in hosts configuration. 
In etc/hosts file and add alias to server name:
# that require network functionality will fail.
127.0.0.1               localhost.localdomain localhost
XX.XX.XX.XX       rhas48.vb.mmikhail.com  rhas48  apps.vb.mmikhail.com


Create or modify configuration and restart your HTTP server:
[root@rhas48 ~]# service httpd restart
Stopping httpd:                                            [  OK  ]
Starting httpd:                                            [  OK  ]


Check new configuration and CRL accessibility:

Now it's time to get workstation ready.

No comments: