What is this?

This is basically where I write down stuff that I work with at my job as a GIS Technical Analyst (previously system administrator). I do it because it's practical for documentation purposes (although, I remove stuff that might be a security breach) and I hope it can be of use to someone out there. I frequently search the net for help myself, and this is my way of contributing.

Saturday, June 2, 2018

Geoserver 2.12.1/Jetty - Installing a SSL certificate from a PFX keystore

I'm using a standard Windows 2016 server with Java JRE 8 update 151 and Geoserver 2.12.1 installed with pretty much default settings. This is a step-by-step description of what I had to do to extract a (wildcard) certificate/key from a IIS-type PFX (PKCS12) keystore to a JKS keystore and install it on the Jetty web server that comes bundled with Geoserver.

NOTE! When I import from the PFX keystore to my new JKS keystore I must always use the same password on both the old and new keystore. Trying to use a different password for the new keystore will just give me an error in {geoserver}/logs/wrapper.log when I start Geoserver:
FAILED org.eclipse.jetty.server.Server@104e906: java.security.UnrecoverableKeyException: Cannot recover key

Step 1:
Export data from my PFX keystore to a new JKS keystore file:
C:\Program Files (x86)\Java\jre1.8.0_151\bin>keytool.exe -importkeystore -srckeystore c:\temp\my_keystore.pfx -srcstoretype pkcs12 -destkeystore c:\temp\keystore -deststoretype JKS
Importing keystore c:\temp\my_keystore.pfx to c:\temp\keystore...
Enter destination keystore password: MyPassword
Re-enter new password: MyPassword
Enter source keystore password: MyPassword
Entry for alias le-f8a123c3-abcd-4bbb-b341-40251cf90a0b successfully imported.
Import command completed:  1 entries successfully imported, 0 entries failed or cancelled

Warning:
The JKS keystore uses a proprietary format. It is recommended to migrate to PKCS12 which is an industry standard format using "keytool -importkeystore -srckeystore c:\temp\keystore -destkeystore c:\temp\keystore -deststoretype pkcs12".

Step 2:
Verify that your new keystore is working:
C:\Program Files (x86)\Java\jre1.8.0_151\bin>keytool -list -keystore c:\temp\keystore -storepass MyPassword
Keystore type: JKS
Keystore provider: SUN

Your keystore contains 1 entry

le-f8a123c3-abcd-4bbb-b341-40251cf90a0b, 02.jun.2018, PrivateKeyEntry,
Certificate fingerprint (SHA1): A1:BF:53:7F:30:00:11:22:33:44:8D:F4:8A:20:25:FF:6B:D5:89:7C

Warning:
The JKS keystore uses a proprietary format. It is recommended to migrate to PKCS12 which is an industry standard format using "keytool -importkeystore -srckeystore c:\temp\keystore -destkeystore c:\temp\keystore -deststoretype pkcs12".

Step 3:
Copy c:\temp\keystore to %GEOSERVER_HOME%\etc\keystore (rename the original "keystore" file for backup purposes)

Step 4:
Download the correct (see below) Jetty distribution archive (tar.gz or zip) from https://repo1.maven.org/maven2/org/eclipse/jetty/jetty-distribution/.
Unpack ssl.mod from the archive (it's located in the modules folder) and copy it to %GEOSERVER_HOME%\modules. 7-zip is my prefered tar/gz unpacking tool when I use Windows.
NOTE: Make sure it's the correct version of ssl.mod - if your Geoserver version is different than mine (12.2.1) your Jetty version is probaably different too. You'll see which jetty version you have by checking jetty-servlet files under %GEOSERVER_HOME%/lib.

Step 5 (Optional):
for increased strength cryptography follow this link: http://docs.geoserver.org/latest/en/user/production/java.html#installing-unlimited-strength-jurisdiction-policy-files
(you can download local_policy.jar and US_export_policy.jar that you copy to %JAVA_HOME%\lib\security\policy\unlimited)

Step 6:
Configure Jetty by adding the following lines to %GEOSERVER_HOME%\start.ini:
#SSL
--module=https
jetty.secure.port=8443
jetty.keystore=etc/keystore
jetty.truststore=etc/keystore
jetty.keystore.password=MyPassword
jetty.keymanager.password=MyPassword
jetty.truststore.password=MyPassword

I added them immediately below the following section:
# --------------------------------------- 
# Module: http
--module=http

NOTE! I've seen some references to editing %GEOSERVER_HOME%\etc\jetty-ssl.xml instead of start.ini. I tried that, but I don't think Jetty read the file at all. I would always get the following errors in wrapper.log:
INFO   | jvm 1    | 2018/05/24 23:50:35 | 2018-05-24 23:50:35.874:WARN:oejuc.AbstractLifeCycle:WrapperSimpleAppMain: FAILED SslContextFactory@4b387439(C:\Program Files (x86)\GeoServer 2.13.0\./etc/keystore,C:\Program Files (x86)\GeoServer 2.13.0\./etc/keystore): java.io.IOException: Keystore was tampered with, or password was incorrect
INFO   | jvm 1    | 2018/05/24 23:50:35 | java.security.UnrecoverableKeyException: Password verification failed

Step 7:
Restart the Geoserver service.

Step 8:
Testing! Now you should be able to access your geoserver on both these addresses
http://localhost:8080/geoserver/web/
https://localhost:8443/geoserver/web/ (probably with a certificate warning due to mismatching address as expected, but I'm sure you know to proceed from here)

If Geoserver just starts and stops after a short while there is an issue with your configuration somewhere. Check %GEOSERVER_HOME%\logs\wrapper.log for details.



Thursday, March 15, 2018

Using SSL Wildcard certificates from a pfx file on FME Server (Tomcat)

UPDATE:

I just installed FME Server 2018 today, and the procedure is still more or less the same. To specifically choose pkcs12 as your keystone format use:

keytool -importkeystore -srckeystore c:\temp\my_keystore.pfx -srcstoretype pkcs12 -destkeystore c:\temp\tomcat.keystore -deststoretype pkcs12


-----


I recently installed an instance of FME Server (version 2015.1.3.1) on a Windows 2012R2 server.

The default installation of FME Server uses http so I decided to install the Wildcard SSL certificate we use in my organization to improve security some. Most of our servers are IIS so I only had a .pfx file accessible.

In Safes documentation library I found this description on how to configure FME Server for https:


This describes how to use a self signed certificate or regular CA-authorized certificate from a CSR. None of which applied to my exact need. So instead I created new JKS keystore by importing the .pfx-keychain with "keytool.exe" (the documentation says you need JDK, but I used the JRE binaries that comes with the FME Server installation).

C:\apps\FMEServer\Utilities\jre\bin>keytool -importkeystore -srckeystore c:\temp\my_keystore.pfx -srcstoretype pkcs12

Enter destination keystore password: 
Re-enter new password:
Enter source keystore password:
Entry for alias le-1234abcd-abcd-4444-a395-1234567890ab successfully imported.
Import command completed:  1 entries successfully imported, 0 entries failed or
cancelled

Next I went through Safe's documentation and altered these files accordingly:

<tomcatdir>/conf/server.xml
<tomcatdir>/conf/web.xml
<fmeserverdir>/server/fmeWebSocketConfig.txt
<fmeserverdir>/server/config/subscribers/websocket.properties
<fmeserverdir>/server/config/publishers/websocket.properties
<programdata>\Safe Software\FME Server\localization\publishers\websocket\publisherProperties.xml
<programdata>\Safe Software\FME Server\localization\subscribers\websocket\subscriberProperties.xml

Then I restarted the "FME Server Application Service" but there was no response from https. I checked <tomcatdir>/logs/catalina.<date>.log and found the following useful entries:

mar 19, 2016 6:25:44 AM org.apache.coyote.AbstractProtocol init
SEVERE: Failed to initialize end point associated with ProtocolHandler ["http-bio-443"]
java.io.IOException: Cannot recover key

mar 19, 2016 6:25:44 AM org.apache.catalina.core.StandardService initInternal
SEVERE: Failed to initialize connector [Connector[HTTP/1.1-443]]
org.apache.catalina.LifecycleException: Failed to initialize component [Connector[HTTP/1.1-443]]

I checked around and it turns out that Tomcat was not able to access my newly imported key because I had a different password set for my JKS keystore than what the imported keystore had. I mistakenly assumed that by importing the key from my existing .pfx-keystore it would inherit the password from my new local JKS keystore. Apparently not so. Anyway - by deleting my c:\users\<user>\.keystore file, running the keytool-importkeystore command and making sure both the destination keystore password AND the source keystore password matched I was able to get it running.

PS: After installing the certificate I had to run the post-configuration scripts again manually. It turned out that I wasn't able to edit service properties upon publishing workspaces to FME server:
http://docs.safe.com/fme/html/FME_Server_Documentation/Default.htm#AdminGuide/Post_Config_Steps.htm (you will have to go and manually set services back to https again after doing this though).

Thanks to the guys at Safe for their help.