Let's Encrypt SSL with Apache (Reverse Proxy) + Tomcat using win-acme

Objective

Secure a website (example.com) served by Tomcat (port 8080) through an Apache reverse proxy on Windows using a free Let's Encrypt SSL certificate generated by win-acme.

Prerequisites

  • Domain name pointing to your public IP.

  • Apache (XAMPP) installed and running on port 80.

  • Tomcat server running on port 8080.

  • win-acme ACME client (https://www.win-acme.com/).

Apache Virtual Host Configuration (Port 80)

<VirtualHost *:80>
    ServerName example.com

    # Serve ACME challenge
    Alias /.well-known/acme-challenge/ "C:/xampp/.well-known/acme-challenge/"
    <Directory "C:/xampp/.well-known/acme-challenge/">
        Options None
        AllowOverride None
        Require all granted
    </Directory>

    # Prevent proxying of ACME challenge
    ProxyPassMatch ^/.well-known ! 

    # Reverse proxy to Tomcat
    ProxyPreserveHost On
    ProxyPass /exampledept/ http://localhost:8080/exampledept/
    ProxyPassReverse /exampledept/ http://localhost:8080/exampledept/

    ProxyPass / http://localhost:8080/exampledept/
    ProxyPassReverse / http://localhost:8080/exampledept/

    ErrorLog "logs/example.com-error.log"
    CustomLog "logs/example.com-access.log" common
</VirtualHost>

win-acme Manual Validation Setup

  • Run wacs.exe and choose M (Full Options).

  • Select manual input of domain: example.com

  • Choose HTTP validation method: Save verification files on (network) path

  • Path for challenge files: C:\xampp\ (No need to mention .well-known/acme-challenge)

  • Choose to skip web.config copy.

  • Choose key type: RSA

  • Output format: PEM files Output directory: C:\example_ssl

  • Skip additional installation or bindings steps.

Validation Troubleshooting (Optional)

  • Ensure the ACME challenge file is directly accessible at: http://example.com/.well-known/acme-challenge/<token>

  • If you see 404s, verify:

    • Apache is not proxying .well-known paths.

    • Challenge file exists in C:/xampp/.well-known/acme-challenge/.

    • No Tomcat redirection is interfering with validation.

Installing SSL

Apache Virtual Host Configuration (Port 443)

<VirtualHost *:443>
    ServerName example.com

    SSLEngine on
    SSLCertificateFile "C:/xampp/ssl/cert.pem"
    SSLCertificateKeyFile "C:/xampp/ssl/key.pem"
    SSLCertificateChainFile "C:/xampp/ssl/chain.pem"

    # Serve .well-known/acme-challenge locally (optional, for renewal)
    Alias /.well-known/acme-challenge/ "C:/xampp/.well-known/acme-challenge/"
    <Directory "C:/xampp/.well-known/acme-challenge/">
        Options None
        AllowOverride None
        Require all granted
    </Directory>

    ProxyPreserveHost On
    ProxyPass /exampledept/ http://localhost:8080/exampledept/
    ProxyPassReverse /exampledept/ http://localhost:8080/exampledept/

    ProxyPass / http://localhost:8080/exampledept/
    ProxyPassReverse / http://localhost:8080/exampledept/

    ErrorLog "logs/example-ssl-error.log"
    CustomLog "logs/example-ssl-access.log" common
</VirtualHost>

Final Steps

  • Restart Apache and Tomcat.

  • Access your secure site via: https://example.com/exampledept/

  • (Optional) Setup a scheduled task or cron for renewal with win-acme.

In your current port 80 VirtualHost, add this to redirect users to HTTPS:

<VirtualHost *:80>
    ServerName example.com

    # Redirect everything to HTTPS
    Redirect permanent / https://example.com/

    # Keep acme challenge local (optional for renewal)
    Alias /.well-known/acme-challenge/ "C:/xampp/.well-known/acme-challenge/"
    <Directory "C:/xampp/.well-known/acme-challenge/">
        Options None
        AllowOverride None
        Require all granted
    </Directory>

    ErrorLog "logs/example.com-error.log"
    CustomLog "logs/example.com-access.log" common
</VirtualHost>

Last updated

Was this helpful?