Generating certificate requests with additional subject identities using OpenSSL

The below provides steps to how the process used to create a certificate request to issue to certificate authority server in an internal environment. However, the steps to create the certificate request can be performed if submitting a certificate request to a third party certificate authority.

Firstly, I will create a configuration file (openssl.cnf) to be used generating the certificate request. The certificate request will be created specifying a default key size of 2048 bits, and sha256 digest algorithm. In this example, I will be submitting a certificate request for the server ‘server1.domain.local’ with the additional subject identities ‘server1,’192.168.0.1’, ‘server1.domain.local’ and ‘www.dean.local’.

[ req ]
default_bits = 2048
‚Äčdefault_md = sha256
default_keyfile = rui.key
distinguished_name = req_distinguished_name
encrypt_key = no
prompt = no
string_mask = nombstr
req_extensions = v3_req

[ v3_req ]
basicConstraints = CA:FALSE
keyUsage = digitalSignature, keyEncipherment, dataEncipherment
extendedKeyUsage = serverAuth, clientAuth
subjectAltName = DNS:server1, IP:192.168.0.1, DNS:server1.dean.local, DNS: www.dean.local

[ req_distinguished_name ]
countryName = GB
stateOrProvinceName = Midlothian
localityName = Edinburgh
0.organizationName = Dean Grant
organizationalUnitName = Servers
commonName = server1.dean.local ‚Äč

We will now create the certificate request to send to the certificate authority, to which the original public key generated in the certificate request will be converted to be in RSA format and remove the original file. Once the certificate request has been generated place the in a location which may be accessible for the submission to the certificate authority server.

cd /tmp
openssl req -new -nodes -out server1.dean.local.csr -keyout orig-server1.dean.local.key -config openssl.cnf
openssl rsa -in orig-server1.dean.local.key -out server1.dean.local.key
rm -f orig-server1.dean.local

In this example I am submitting my certificate request to a certificate authority running Active Directory Certificate Services on Windows Server 2012. The certificate request is submitted specifying the ‘WebServer’ certificate template and the certificate request file created previously. If prompted select the certificate authority which will now create certificate file (server1.dean.local.crt) and the certficate chain file (server1.dean.local.pfx).

cd %temp%
certreq -attrib "CertificateTemplate:WebServer" -submit server1.dean.local.csr server1.dean.local.crt server1.dean.local.pfx

The certificate files may now be placed on the server to which you configure encryption, depending on the certificate file requirements you should have the following files available.

server1.dean.local.crt # certificate file
server1.dean.local.pfx # certificate chain file in personal exchange file (.pfx) format.
server1.dean.local.key # private key file

Forcing SSL with permanent redirect for Nagios XI

The scope of this article is to describe the steps required to configure SSL for Nagios XI and to force SSL with a permanent redirection. In this example, I have made the assumption that certificate files have been generated and in this example I will be using the hostname ‘nagios.dean.local’ for my Nagios XI server throughout the configuration steps.

In order to configure SSL version 2011R1.6 or later of Nagios XI is required to ensure all of data is displayed correctly in Nagios XI interface. The installation of Nagios XI should install the required SSL components, to verify this run the following command on the Nagios XI server.

sudo yum install mod_ssl openssl -y 

Also, you will need to ensure that inbound connectivity on TCP service port 443 for the https protocol is permitted. If this is not the case we can create input chain to accept connections.

sudo iptables -I INPUT -p tcp --dport 443 -j ACCEPT 
sudo service iptables save

Prior to configuring SSL for Nagios XI we will create a backup of the configuration files which will modify as part of this process in case we are required to revert the changes. The SSL certificate files will need to be available¬†NagiosXI server, place the certificate file in ‘/etc/pki/tls/certs’ and the key file in ‘/etc/pki/tls/private’.

sudo cp /etc/httpd/conf/httpd.conf /etc/httpd/conf/httpd.conf.backup
sudo cp /etc/httpd/conf.d/ssl.conf /etc/httpd/conf.d/ssl.conf.backup 
sudo cp /etc/httpd/conf.d/nagiosxi.conf /etc/httpd/conf.d/nagiosxi.conf.backup
sudo cp /usr/local/nagiosxi/html/config.inc.php /usr/local/nagiosxi/html/config.inc.php.backup 

Once the certificate and key files have been copied to the locations we need to configure the httpd service by modifying the file ‘/etc/httpd/conf.d/ssl.conf’

SSLCertificateFile /etc/pki/tls/certs/nagios.dean.local.crt
SSLCertificateKeyFile /etc/pki/tls/private/nagios.dean.local.key 

Also, we will need to configure the virtual host to listen to requests on TCP server port 443 for the https protocol by modifying the file ‘/etc/httpd/conf/httpd.conf’.

NameVirtualHost *:443 

Once the file has been modified we will restart the ‘httpd’ service to apply the configuration. We may verify the connection to the server by browsing to the server, in this example https://nagios.dean.local.

sudo service httpd restart 

Now we will need to edit ‘/usr/local/nagiosxi/html/config.inc.php’ and modify the below line to which the value by default should be configured as ¬†‘false’.

$cfg['use_https']=true;

Now browse to the Nagios XI web interface and browse to Admin > System Settings and modify the program URL value to contain the https protocol instead of http and select ‘Update Settings‘. For Example https://nagios.dean.local/nagiosxi.

Nagios_System_Settings

Next, browse to ‘Configure > Core Config Manager > Config Manager Admin > Config Manager Settings’ and modify the Server Protocol value to be https and select ‘Save‘.

Nagios_Global_Settings

 

 

 

 

 

 

 

 

 

 

 

 

Finally, we will need to edit the file ‘/etc/httpd.conf.d/nagiosxi.conf’, which by default should be similar to the below:

# NameVirtualHost * :443
<VirtualHost *:80> 
<Directory "/usr/local/nagiosxi/html">
   #SSLRequireSSL
   Options None 
   AllowOverride None 
   Order allow, deny 
   Allow from all 
   # Order deny,allow
   # Deny from all
   # Allow from 127.0.0.1
   # AuthName "Nagios XI"
   # AuthType Basic 
   # AuthUserFile /usr/local/nagiosxi/etc/htpasswd.users
   # Require valid-user 
</Directory
</VirtualHost> 

We now will add the following to configuration file to enable the virtual host to listen on HTTPS and specify the path to the certificate files that been generated.

<VirtualHost *:443>
   SSLEngine on 
   SSLCertificateFile /etc/pki/tls/certs/nagios.dean.local.crt
   SSLCertificateKeyFile /etc/pki/tls/private/nagios.dean.local.key 
   <Directory "/user/local/nagiosxi/html">
   AllowOverride All 
</Directory> 
</VirtualHost>
Alias /nagiosxi "/usr/local/nagiosxi/html"

To force SSL with a permanent redirection the following will be required to be added between ‘<VirtualHost>’ and ‘</VirtualHost>’ tags and add the configuration for the rewrite engine between the start and end tags for the virtual host listing on TCP service port 443.

Redirect permanent / https://nagios.dean.local 
<IfModule mod_rewrite.c> 
   RewriteEngine On 
   RewriteCond %{REQUEST_FILENAME} !-f
   RewriteCond %{REQUEST_FILENAME} !-d
   RewriteRule nagiosxi/api/v1/(.*)$ /usr/local/nagiosxi/html/api/v1/index.php?request=$1 [QSA,NC,L]
</IfModule>

Once saved, the updated configuration file ‚Äė/etc/httpd.conf.d/nagiosxi.conf‚Äô should look similar to the below:

# NameVirtualHost * :443
<VirtualHost *:80> 
<Directory "/usr/local/nagiosxi/html">
   #SSLRequireSSL
   Options None 
   AllowOverride None 
   Order allow, deny 
   Allow from all 
   Redirect permanent / https://nagios.dean.local 
   # Order deny,allow
   # Deny from all
   # Allow from 127.0.0.1
   # AuthName "Nagios XI"
   # AuthType Basic 
   # AuthUserFile /usr/local/nagiosxi/etc/htpasswd.users
   # Require valid-user 
</Directory
</VirtualHost> 

<VirtualHost *:443>
   SSLEngine on 
   SSLCertificateFile /etc/pki/tls/certs/nagios.dean.local.crt
   SSLCertificateKeyFile /etc/pki/tls/private/nagios.dean.local.key 
<Directory "/user/local/nagiosxi/html">
   AllowOverride All 
</Directory> 
<IfModule mod_rewrite.c> 
   RewriteEngine On 
   RewriteCond %{REQUEST_FILENAME} !-f
   RewriteCond %{REQUEST_FILENAME} !-d
   RewriteRule nagiosxi/api/v1/(.*)$ /usr/local/nagiosxi/html/api/v1/index.php?request=$1 [QSA,NC,L]
</IfModule>
</VirtualHost>

Alias /nagiosxi "/usr/local/nagiosxi/html"

This completes the configuration steps required to force SSL with a permanent direct for the Nagios XI server. In my example, I would verify the connection to browsing to ‘http:\\nagios.dean.local\nagiosxi’ which should redirect to ‘https:\\nagios.dean.local\nagiosxi’. The configuration files that are required be modified can be found as examples at the following link.

Creating concatenated certificate container files using Windows PowerShell

I was recently enabling SSL on a web application which required the certificate file to be provided as a concatenated certificate container file containing all SSL certificates in the chain.

The method to perform the above is relatively simple and just requires each certificate to the chain to be opened in a text editor and the content to be combined into a single file.

Whilst relatively simple, I decided to use Windows PowerShell and create an advanced function to achieve the above.

Firstly, we need to specify the certificate files to combine to a container file and the in correct order of the certificate path. For Example, if you were to open the SSL certificate and view the certification path the order of the certificate files you specify should be in ascending order. Also, optionally you require to specify the private key in some scenarios in this case this should be the first certificate file specified. By default, the container file is created in the location of the users profile in PEM format but you may specify an alternative location and/or file extension.

Once we have a list of certificates to combine to a container file in the correct order to retrieve (Get-Content) the content of each certificate file and add the content (Add-Content) to the container file. When I reference the content of a certificate file we are retrieving the body of each file including the begin and end tags as below.

Once the content of each certificate file has been retrieved and the content has been added to the container file this will create a file in the location specified or by default in the location of the users profile folder in PEM format.

Below is an example of the invoking the function and the output generated with the verbose message stream enabled.

ConvertTo-CertificateContainerResults

The advanced function is available from here.

 

 

 

 

 

 

 

 

 

 

Unable to issue Exchange certificate with Denied By Policy Module 0√ó80094801.

I was recently renewing an SSL certificate for Exchange services with an internal certificate authority, when issuing the certificate request the following error was received:

Denied By Policy Module 0√ó80094801, The Request does not contain a certificate template extension or the certificate template request attribute

In order to issue the certificate request I was required to invoke the certreq utility as below agaisnt the certificate request generated, in the below example this is named certrequest.req.

certreq -submit -attrib "CertificateTemplate:WebServer" certrequest.req

Monitoring multiple SSL certificates on a single host using Nagios XI

I was recently looking to monitor multiple SSL certificates on a host for multiple network services, to which Nagios appeared to have a limitation within the ‘check_xi_service_http_cert’ check command ¬†to which it can only monitor a single SSL certificate per monitored host.¬†

I therefore created a powershell script to allow for multiple certificates to be monitored based on the port number used for the network service and return the expiry date of the SSL certificate to generate a service status.

The script is dependent on two parameters, one to retrieve the host name (where by default this retrieves the local host FQDN) and a mandatory parameter for the port number.

Param ([string] $URL= ([System.Net.Dns]::GetHostByName(($env:computerName))).HostName, [parameter(Mandatory =$true)][string] $Port) 

Once we have specified the parameters required we will initiate a client connection to the TCP network service by invoking the ‘System.Net.Sockets.TcpClient’ class.

$TCPClient = New-Object System.Net.Sockets.TcpClient($URL,$Port) 

Once the client connection has been generated, we will provide a stream  for client-server communication that uses the Secure Socket Layer (SSL) security protocol to authenticate the server and optionally the client.

$SSLStream = New-Object System.Net.Security.SslStream($TCPClient.GetStream())
$SSLStream.AuthenticateAsClient($URL) 

This will now allow for the expiration date of the certificate used to authenticate the remote endpoint to be retrieved, and store this as a variable to compare in the conditional logic to determine the service status.

$Certificate = $SSLStream.Get_RemoteCertificate()
$Expiry = [datetime]::Parse($Certificate.GetExpirationDatestring())

Now we will use conditional logic to compare the expiry date to a date in the future from the current date and use the following criteria.

  • If the the expiry date is less than 30 days in future report the service status as ‘OK’
  • If the expiry date is greater or equal to 7 days in the future report the service status as ‘Critical’
  • If the expiry date is greater or equal to 30 days in the future report the service status as ‘Warning’
If (((Get-Date).AddDays(30)) -lt $Expiry)
    { 
    "OK - Certificate will expire on " + $Expiry.ToString("dd/MM/yyyy HH:mm") 
    $returncode = "0" 
    } 
    
ElseIf (((Get-Date).AddDays(7)) -ge $Expiry)
    { 
    "Critical - Certificate will expire on " + $Expiry.ToString("dd/MM/yyyy HH:mm") 
    $returncode = "2" 
    } 
    
ElseIf (((Get-Date).AddDays(30)) -ge $Expiry)
    { 
    "Warning - Certificate will expire on " + $Expiry.ToString("dd/MM/yyyy HH:mm") 
    $returncode = "1" 
    } 

Once the service status has been determined, the powershell session will exist returning an exit code.

exit $returncode

Once¬†you have configured the external script to run within Nagios (http://wp.me/p15Mdc-eC), you will be able to monitor multiple SSL certificate expiration’s on a single host. Alternatively, you can invoke the script from the powershell console as below:

./Check-SSLCertificates.ps1 -URL server.domain.local -Port 443

Exporting SSL certificate from IIS to Apache

I was recently required to implement SSL on a Apache web server to which I currently held a SSL certificate for the namespace which was generated using IIS.

So rather than purchasing an additional certificate, I was able to convert the original SSL certificate from IIS into a the format required for Apache using OpenSSL, as below:

1) Open the Certificates snap-in for the computer account of local machine containing the SSL certificate.

2) Browse to Personal, highlight your certificate you wish to convert and select Export.

3) To extract the private key and the certificate from the from the exported .pfx file, perform the following:

openssl pkcs12 -in <filename>.pfx -nocerts -out key.pem

4) From the generated .pem file we will be required to remove the password:

openssl rsa -in <filename>.pem -out <filename>.key

5) Now will we will need to export the certificate:

openssl pkcs12 -in <filename>.pfx -clcerts -nokeys -out cert.pem

Within the key.pm file this will contain RSA private key, copy and save this with the .key file extension and the cert.pem file will contain the certificate, copy and save this with the .cert file extenstion.

You should now be able to use the SSL certificate on the Apache web server.

Retrieving TLS\SSL server information

I was recently looking to retrieve information in regards to TLS\SSL compression for a number of websites to address the BREACH vulnerability and found this useful utility at http://www.bolet.org/TestSSLServer/.

TestSSLServer is a command line utility which contacts a TLS\SSL server and returns the following information:

  • Supported versions (among SSL 2.0, SSL 3.0, TLS 1.0, TLS 1.1 and TLS 1.2).
  • Support of Deflate compression (TLS-level compression,¬†not¬†HTTP-level gzip/deflate compression, which this tool does not consider).
  • Supported cipher suites, for each protocol version.
  • Server certificate hash and name.