Skip to content

Citrix License Server v12.x – How to renew an expired Apache Tomcat Server Certificate

Just recently I came across an expired Server Certificate on my Citrix License Server v12.x. As everybody might know, the Citrix License Server is based on an Apache Tomcat webserver running on your Windows Server. During installation a self-signed server certificate is being issued and bound to the Apache's web server port 8083. So how are you supposed to renew the server certificate in case it has expired and you need secure access to the corresponding Citrix License Server features?

Usually you access the Citrix License Administration Console through the URL

  • http://localhost:8082 or
  • http://<FQDNofYourLicenseServer>:8082

As opposed to the unsecure connection you can access the Citrix Simple License Service through an secure connection via

  • https://<FQDNofYourLicenseServer>:8083

thus requiring a corresponding server certificate reflecting the License Server's FQDN on the certificate.

As I use a PowerShell script for daily reports on my current license consumption and usage (which can be found here), I need secure access to the License Server's service. The script uses the Citrix.Licensing.Admin.V1 snapin and the included cmdlets Get-LicCertificate.ps1 as well as Get-LicInventory.ps1 to retrieve all information required for this purpose. The PowerShell script
Get-CitrixLicenses.ps1 can be found here, courtesy of Clint McGuire's efforts.

The snapin Citrix.Licensing.Admin.V1 has to be installed manually and can be found in LicensingAdmin_PowerShellSnapIn_x64.msi under the \x64\Licensing folder of your XenDesktop 7.x installation medium:

license_server_01

After the server certificate has expired the script stopped working. As soon as the script issued the cmdlet Get-LicInventory -AdminAddress https://<FQDNofYourLicenseServer>:8083/ I received an error stating:

Get-LicInventory : CertificateVerificationFailed

license_server_02

Keep in mind that the exact same error shows up in case you don't trust the server certifcate's issuer, which is usually the case in terms of a default installation.

Interlude

This error pointed me in another direction as well. In order to avoid any certificate related errors while running PowerShell cmdlets against the Citrix License Server's secure address, you have to read the CertHash property first, then provide it to the Get-LicInventory cmdlet, e.g.:

$ServerAddress = "https://<FQDNofYourLicenseServer:8083"
$certhash = (Get-LicCertificate -AdminAddress $ServerAddress).certhash
$LicAll = Get-LicInventory -AdminAddress $ServerAddress -CertHash $certhash

Then you should receive the corresponding License Server information, e.g.:

license_server_03

...
LicenseProductName : XDT
LocalizedLicenseProductName : Citrix XenDesktop Platinum
LicenseEdition : PLT
LicenseLocalizedEdition :
LicenseSubscriptionAdvantageDate : 2014:0826
LicenseType : Retail
LocalizedLicenseType : Retail
LicensesInUse : 44
LicensesAvailable : 44
LicenseOverdraft : 4
LicenseModel : UD
LocalizedLicenseModel : User/Device

LicenseProductName : XDT
LocalizedLicenseProductName : Citrix XenDesktop Platinum
LicenseEdition : PLT
LicenseLocalizedEdition :
LicenseSubscriptionAdvantageDate : 2016:0806
LicenseType : Retail
LocalizedLicenseType : Retail
LicensesInUse : 16
LicensesAvailable : 55
LicenseOverdraft : 5
LicenseModel : UD
LocalizedLicenseModel : User/Device
...

Ok then, back to the actual renewal of the server certifcate….. My methodology looked as follows:

  1. create a new server certificate including a private key
  2. export the server certificate to pfx file format
  3. extract server certificate and private key from pfx to separate files
  4. exchange the Apache Tomcat's expired server certificate with newly created certificate

1. Request a new Server Authentication Certificate

As I sported a Microsoft PKI for internal use server certificates, I simply requested a new Server Authentication Certificate for my Citrix License Server on my Microsoft CA. You only have to ensure that you choose the correct certificate and mark the corresponding key as exportable. The Name should reflect the License Server's FQDN:

license_server_04

Issue the newly requested server certificate on your CA, then import/install it onto your Citrix License Server:

license_server_05

license_server_06

license_server_07

2. Export the Server Certificate inluding Private Key

After importing you need to export the server certificate including the private key, i.e. to the pfx file format. To achieve this simply open a MMC an add the Certificates Snap-in pointing to your Certificates - Current User store. There you should find the recently installed server certificate. Right-click the corresponding certificate and hit All Tasks | Export...:

license_server_08

license_server_09

Now rinse and repeat as we need to export the server certificate once more, this time around in cer file format, i.e. without your private key and Base-64 encoded X.509 (.CER):

license_server_10

license_server_11

3. Extract Private Key and Server Certificate from PFX

In order to achieve this I utilized GnuWin32's OpenSSL binaries for Windows. You can download them here. I downloaded and installed the Complete package, except sources. After installation you'll find the required openssl.exe executable file in C:\Program Files (x86)\GnuWin32\bin. In order to extract both the certificate as well as the certificate's key issue the following commands in an elevated command prompt:

openssl pkcs12 -in <ExportedCertificate>.pfx -nocerts -out key.pem -nodes
openssl rsa -in key.pem -out server.key

After issueing these commands you should at least have two files available:

  • key.pem
  • server.key

4. Import newly created server certificate to Apache Tomcat

The previously exported server.key certificate file can now be used to replace the expired Apache server certificate located at C:\Program Files (x86)\Citrix\Licensing\LS\conf ... or ... C:\Program Files (x86)\Citrix\Licensing\WebServicesForLicensing\Apache\conf ... 

Subsequently you have to verify or adjust the configuration file httpd-ssl.conf which can be found in C:\Program Files (x86)\Citrix\Licensing\WebServicesForLicensing\Apache\conf\extra 

SSLCertificateFile "C:/program files (x86)/citrix/Licensing/WebServicesForLicensing/Apache/conf/server.crt"
SSLCertificateKeyFile "C:/program files (x86)/citrix/Licensing/WebServicesForLicensing/Apache/conf/server.key"

As a final step restart the corresponding Citrix Licensing services.

Navigate to URL https:<FQDNofCitrixLicenseServer>:8083 and verify whether any certificate errors appear:

5. Script

The final script looks as follows:

<#
.SYNOPSIS
Reports on Citrix licenses in use for selected products.
 
.DESCRIPTION
This script will query your Citrix Licnese server and output the in
use and total licenses for individual products.
 
.NOTES
Requires Citrix Licensing Snapin (Citrix.Licensing.Admin.V1)
If your License server has a self-signed cert you may get license
errors when running this.  I've resolved this in my test environments
by installing the cert as a Trusted Root CA Cert.
 
Source: http://www.clintmcguire.com/scripts/get-citrixlicenses/
Author: Clint McGuire
Version 1.0
Copyright 2013

Code edited by Alexander Ollischer
Source: https://blog.ollischer.com
Version 1.1
Copyright 2017
 
.EXAMPLES
PS> .\Get-CitrixLicenses.ps1
Using 71 Citrix XenApp Enterprise of 132 available.
 
#>
############################################################################################
#DEFINE THESE VARIABLES FOR YOUR ENVIRONMENT
 
#Enter the URL for your License server, typically this uses HTTPS and port 8083
#E.G. "https://licensingservername:8083"
$ServerAddress = "https://<LicenseServerName>.domain.local:8083"
 
#Enter the license type you would like to output, this can be a comma separated list, include 
#each option in single quotes
#E.G. 'Citrix XenApp Enterprise','Citrix XenDesktop Enterprise','Citrix EdgeSight for XenApp'
$LicenseTypeOutput = 'Citrix XenApp Enterprise','Citrix XenDesktop Enterprise','Citrix EdgeSight for XenApp','Citrix XenApp Platinum','Citrix XenDesktop Platinum'

############################################################################################
 
#Path to HTMLReport File
$FilePath = "C:\Scripts\LMC\LicAll.html"
$smtpsettings = @{
	To =  "recipient@domain.local"
	From = "sender@domain.local"
    Subject = "Citrix License Usage"
	SmtpServer = "IPorFQDNofYourMailServer"
	}
     
#Check for Licensing Snap-in, add if not currently added
#PowerShell Snap-in is contained in: LicensingAdmin_PowerShellSnapIn_x64.msi
if ( (Get-PSSnapin -Name Citrix.Licensing.Admin.V1 -ErrorAction SilentlyContinue) -eq $null )
{
    Add-PsSnapin Citrix.Licensing.Admin.V1
}
 
#Create Hash tables
$LicAll = @{}
$LicInUse = @{}
$LicAvailable = @{}
 
#Build License Display hash table 
$certhash = (Get-LicCertificate -adminaddress $ServerAddress).certhash
$LicAll = Get-LicInventory -AdminAddress $ServerAddress -CertHash $certhash
Get-LicInventory -AdminAddress $ServerAddress -CertHash $certhash | ConvertTo-HTML | Out-File $FilePath

ForEach ($LicInfo in $LicAll) 
{
    $Prod = $LicInfo.LocalizedLicenseProductName
    $InUse = $LicInfo.LicensesInUse
    $Avail = $LicInfo.LicensesAvailable
    if ($LicInUse.ContainsKey($Prod))
        {
                if ($LicInUse.Get_Item($Prod) -le $InUse) 
                {
                    $LicInUse.Set_Item($Prod, $InUse)
                }
        }
    else
        {
            $LicInUse.add($Prod, $InUse)
        }
    if ($LicAvailable.ContainsKey($Prod))
        {
                if ($LicAvailable.Get_Item($Prod) -le $Avail) 
                {
                    $LicAvailable.Set_Item($Prod, $Avail)
                }
        }
    else
        {
            $LicAvailable.add($Prod, $Avail)
        }
}
 
#Output license usage for each requested type.
Foreach ($Type in $LicenseTypeOutput)
{
    $OutPutLicInUse = $LicInUse.Get_Item($Type)
    $OutPutAvail = $LicAvailable.Get_Item($Type)
    Write-Host "Using" $OutPutLicInUse  $Type  "of" $OutPutAvail "available."
}

#Send Email Notification
$Output = (Get-Content $FilePath | Out-String)
Send-MailMessage @smtpsettings -Body $Output -BodyAsHtml -Encoding ([System.Text.Encoding]::UTF8)

 

Further reading:

Leave a Reply