Windows Tomcat Letsencrypt (win-acme)

How to use Let's Encrypt with Tomcat on a Windows server.

Minimum Requirements:

Tomcat

Add a docbase directory in D:\mytomcat\docbase. Edit at the end of D:\mytomcat\conf\server.xml to look like this:

        <Context docBase="D:\mytomcat\docbase\.well-known" path="/.well-known" />
      </Host>
    </Engine>
  </Service>
</Server>

Stop & start the Tomcat service:

sc stop mytomcat
sc start mytomcat

To better understand how the ACME challenge work you can add some extra HTML-files with these DOS-commands:

mkdir D:\ssl
mkdir D:\mytomcat\docbase\.well-known
copy con D:\mytomcat\docbase\.well-known\index.html
<!DOCTYPE html><html><head><title>Test</title>
<meta http-equiv="Content-Type" content="text/html; charset=UTF-8">
</head><body><h1>
DIR = D:\mytomcat\docbase\.well-known
</h1></body></html>
^Z

The Tomcat configuration can now be tested OK at http://example.org/.well-known/. This is the directory the ACME challenge protocol is going to use so make sure it is working.

wacs.exe

Directories used by wacs.exe:

http://example.org/.well-known/

<Connector
	protocol="org.apache.coyote.http11.Http11AprProtocol"
	port="443"
	maxThreads="200"
	scheme="https"
	secure="true"
	SSLEnabled="true"
	SSLCertificateFile="D:\ssl\example.org-chain.pem"
	SSLCertificateKeyFile="D:\ssl\example.org-key.pem"
	sslEnabledProtocols="TLSv1,TLSv1.1,TLSv1.2"
	ciphers="TLS_ECDHE_RSA_WITH_AES_128_CBC_SHA256, TLS_ECDHE_RSA_WITH_AES_128_CBC_SHA,TLS_ECDHE_RSA_WITH_AES_256_CBC_SHA384, TLS_ECDHE_RSA_WITH_AES_256_CBC_SHA,TLS_ECDHE_RSA_WITH_RC4_128_SHA, TLS_RSA_WITH_AES_128_CBC_SHA256,TLS_RSA_WITH_AES_128_CBC_SHA,TLS_RSA_WITH_AES_256_CBC_SHA256, TLS_RSA_WITH_AES_256_CBC_SHA,SSL_RSA_WITH_RC4_128_SHA"
/>

Renew

wacs.exe --renew --verbose
D:\tool> wacs.exe --verbose --webroot D:\mytomcat\docbase --validation filesystem --target manual --host example.org --store pemfiles --pemfilespath D:\ssl --installation script --script D:\tool\afterwacs.cmd --scriptparameters "'{CertCommonName}' '{CacheFile}'"
 [DBUG] Config folder: D:\ssl\letsencrypt-win-simple\httpsacme-v01.api.letsencrypt.org
 [VERB] Using registry key HKEY_LOCAL_MACHINE\Software\letsencrypt-win-simple\https://acme-v01.api.letsencrypt.org/
 [VERB] Settings SettingsService {ConfigPath="D:\\ssl\\letsencrypt-win-simple\\httpsacme-v01.api.letsencrypt.org", RenewalStore=null, HostsPerPage=50, ScheduledTaskRandomDelay=00:00:00, ScheduledTaskStartBoundary=09:00:00, ScheduledTaskExecutionTimeLimit=02:00:00}
 [VERB] .NET Framework >=4.8 detected
 [INFO] Let's Encrypt Windows Simple (WACS)
 [INFO] Software version 198.2.6594.21512 (RELEASE)
 [INFO] IIS not detected
 [INFO] ACME Server https://acme-v01.api.letsencrypt.org/
 [INFO] Please report issues at https://github.com/Lone-Coder/letsencrypt-win-simple
 [VERB] Verbose mode logging enabled
 [DBUG] Renewal period: 55
 [INFO] Running in Unattended mode
 [INFO] Plugin Manual generated target [Manual] [1 binding - example.org]
 [DBUG] Loading signer from D:\ssl\letsencrypt-win-simple\httpsacme-v01.api.letsencrypt.org\Signer
 [DBUG] Getting AcmeServerDirectory
 [DBUG] Send GET request to https://acme-v01.api.letsencrypt.org/directory
 [DBUG] Loading registration from D:\ssl\letsencrypt-win-simple\httpsacme-v01.api.letsencrypt.org\Registration
 [INFO] Authorize identifier: example.org
 [DBUG] Send POST request to https://acme-v01.api.letsencrypt.org/acme/new-authz
 [INFO] Authorizing example.org using http-01 validation (FileSystem)
 [INFO] Answer should now be browsable at http://example.org/.well-known/acme-challenge/FUqHT946SjlkJKHLHLhssLywYU2PsEFUTc4YKNi0U
 [DBUG] Submitting answer
 [DBUG] Send POST request to https://acme-v01.api.letsencrypt.org/acme/challenge/CRuCf6KB3Ux7887sdaasasj8W3vNbEPw3YIO2Glqv76PW9o/3238820315
 [DBUG] Refreshing authorization
 [DBUG] Send GET request to https://acme-v01.api.letsencrypt.org/acme/authz/CRuCf6KB3Ux7887sdaasasj8W3vNbEPw3YIO2Glqv76PW9o
 [DBUG] Refreshing authorization
 [DBUG] Send GET request to https://acme-v01.api.letsencrypt.org/acme/authz/CRuCf6KB3Ux7887sdaasasj8W3vNbEPw3YIO2Glqv76PW9o
 [INFO] Authorization result: valid
 [DBUG] Deleting answer
 [DBUG] Additional files or folders exist in D:\mytomcat\docbase\.well-known, not deleting.
 [DBUG] Certificate folder: D:\ssl\letsencrypt-win-simple\httpsacme-v01.api.letsencrypt.org
 [DBUG] Certificate store: My
 [DBUG] RSAKeyBits: 2048
 [INFO] Requesting certificate example.org 2018-1-26 2:53:41
 [DBUG] Send POST request to https://acme-v01.api.letsencrypt.org/acme/new-cert
 [INFO] Saving certificate to D:\ssl\letsencrypt-win-simple\httpsacme-v01.api.letsencrypt.org
 [VERB] Converting private key...
 [DBUG] Set private key exportable
 [INFO] Installing certificate in the certificate store
 [DBUG] Opened certificate store My
 [INFO] Adding certificate example.org 2018-1-26 2:53:41  to store My
 [VERB] CN=example.org - CN=Let's Encrypt Authority X3, O=Let's Encrypt, C=US (E295658D7C3847561FCBB926E9AD0BBC904E4AB6)
 [VERB] CN=Let's Encrypt Authority X3, O=Let's Encrypt, C=US - CN=DST Root CA X3, O=Digital Signature Trust Co. (E6A3B45B067679873232396EFE97D5956CCB) to CA store
 [VERB] CN=DST Root CA X3, O=Digital Signature Trust Co. - CN=DST Root CA X3, O=Digital Signature Trust Co. (DAC9024F54D8993248A8B0C1732638CA6AD77C13) to AuthRoot store
 [DBUG] Closing certificate stores
 [INFO] Adding Task Scheduler entry with the following settings
 [INFO] - Name letsencrypt-win-simple httpsacme-v01.api.letsencrypt.org
 [INFO] - Path C:\tool\letsencrypt-win-simple.v1.9.8.2
 [INFO] - Command wacs.exe --renew --baseuri "https://acme-v01.api.letsencrypt.org/"
 [INFO] - Start at 09:00:00
 [INFO] - Time limit 02:00:00
 [DBUG] Creating task to run as system user
 [INFO] Adding renewal for example.org
 [INFO] Next renewal scheduled at 2018-3-22 1:53:45

After the tomcat webserver has been restarted the certificate can be tested at https://example.org/.well-known/.

Note

LESW need access to both the Tomcat docbase directory and https://letsencrypt.org/ (internet access) at the same time. In my installation Tomcat can not access internet by itself so I had to use my desktop PC and mount a SMB share from the webserver:

NET USE W: \\mytomcatsrv\D$ /PERSISTENT:YES

A script could run on my desktop to renew the certificate later on.

Script renewcertificate.cmd:

DIR \\mytomcatsrv\d$\ssl /W
IF NOT %ERRORLEVEL% EQU 0 (
  NET USE \\mytomcatsrv\admin$ /USER:mydom\%USERNAME%
)
FINDSTR "\ssl" wacs.exe.config
wacs.exe --verbose --target manual --validation filesystem --store pemfiles --pemfilespath \\mytomcatsrv\d$\ssl --webroot \\mytomcatsrv\d$\mytomcat\docbase --host example.org
sc \\mytomcatsrv query mytomcat
REM Test this:
REM sc \\mytomcatsrv stop mytomcat
sc \\mytomcatsrv start mytomcat

VirtualSVN Server

TODO With the following premises it is not an easy task:

Task

C:\tool\wacs\wacs.exe --verbose --webroot C:\tomcat\docbase --validation filesystem --target manual --host activemq.example.org  --store pemfiles --pemfilespath C:\ssl --installation script --script C:\tool\pemtojks.cmd --scriptparameters "{CertCommonName}"
REM Put in a script with argument 1 as the hostname
C:\tool\openssl.exe pkcs12 -export -name artemiscrt -in %1-chain.pem -inkey %1-key.pem -out %1.p12 -passout "pass:p4zzword"
keytool.exe -importkeystore -destkeystore %1.keystore -deststorepass p4zzword -destkeypass p4zzword -srckeystore %1.p12 -srcstoretype PKCS12 -srcstorepass "p4zzword"
NET STOP artemis-vdvrd-0.0.0.0
NET START artemis-vdvrd-0.0.0.0

VirtualSVN Server

When the keys has been generated and the certificate received, the certificate can be loaded with these commands:

TYPE example.org-key.pem example.org-chain.pem > "%VISUALSVN_SERVER%certs\server.pem"
COPY example.org-chain.pem "%VISUALSVN_SERVER%certs\certchain.pem"
NET STOP VisualSVNServer
NET START VisualSVNServer

For more information go to visualsvn.com/server .

validator