How to Setup "Let's Encrypt" for Apache on Windows

Let's Encrypt is an effort by the Internet Security Research Group (ISRG) to provide free SSL certificates in order to encourage website owners to secure their websites with encryption. It is gaining in popularity and recently issued its two-millionth certificate.

There are many benefits of enabling SSL encryption on a website, including securing user information if they need to login to the site and getting a higher ranking on Google Search.

If you currently run Apache (or the other distributions such as XAMPP and WampServer) on Windows, then this guide is for you.

 

(A) Download the tools (letsencrypt-win-simple)

We will use a third party tool call letsencrypt-win-simple created specifically for Windows platform. This is because the official letsencrypt-auto script does not support Windows at this point of writing.

Download the latest version from the letsencrypt-win-simple release page here: https://github.com/Lone-Coder/letsencrypt-win-simple/releases

At this point of writing, the latest release is v1.9.0 and this is the direct link to the binary download in zip format: https://github.com/Lone-Coder/letsencrypt-win-simple/releases/download/v...

[EDIT: Auto renewal doesn't work with v1.9.0 (see #195), so you should download v1.8.0 at the moment, until the corresponding fix is released for newer version.]

Extract the zip into a folder which you will keep permanently and have write access. If you are unsure, the folder "C:\letsencrypt-win-simple\" should be a good choice.

 

(B) Obtain an SSL certificate (Test Run)

Open the command prompt and navigate to the previous letsencrypt-win-simple folder.

cd C:\letsencrypt-win-simple

Then run the letsencrypt tool to generate a certificate for your domain in test mode. By using the test mode, the generated certificates will not count against the rate limit.

letsencrypt.exe --manualhost <domain-name> --webroot <document-root> --test

Replace <domain-name> with the actual domain name which you want to create the certificate for.
Replace <document-root> with the htdocs or www folder of Apache.
For example:

letsencrypt.exe --manualhost www.commaster.net --webroot "C:\xampp\htdocs" --test

If the certificate generation is successful, a message similar to the following will appear.

Authorizing Identifier <domain-name> Using Challenge Type http-01
 Writing challenge answer to <document-root>\.well-known/acme-challenge/<challenge-text>
 Answer should now be browsable at <document-root>/.well-known/acme-challenge/<challenge-text>
 Submitting answer
 Refreshing authorization
 Authorization Result: valid

Requesting Certificate
 Request Status: Created
 Saving Certificate to C:\Users\<username>\AppData\Roaming\letsencrypt-win-simple\httpsacme-stage.api.letsencrypt.org\<domain-name>-crt.der
 Saving Issuer Certificate to D:\Users\<username>\AppData\Roaming\letsencrypt-win-simple\httpsacme-stage.api.letsencrypt.org\ca-<hex>-crt.pem
 Saving Certificate to D:\Users\<username>\AppData\Roaming\letsencrypt-win-simple\httpsacme-stage.api.letsencrypt.org\<domain-name>-all.pfx

You can safely skip the below to Section C if your test generation is successful.

In order to authorize itself, the letsencrypt tool will answer the HTTP challenge from Let's Encrypt server, by placing the challenge file under the folder <domain-root>/.well-known/. Therefore, it's important that the .well-known folder can be publicly accessed through http://<domain-name/.well-known/. A usual problem for many users of PHP or Python framework is that the framework redirect the root path of the domain url to their own processing script. In this case, you need to place an alias in your Apache configuration file such as below:

Alias /.well-known <domain-root>/.well-known

Replace domain-root accordingly. For example:

Alias /.well-known "C:/xampp/htdocs/.well-known"

Restart Apache server and attempt the test generation above again.

 

(C) Obtain an SSL certificate (Actual Run)

If your test generation has been successful, proceed to generate the actual certificate by removing the --test argument from the command.

letsencrypt.exe --manualhost <domain-name> --webroot <document-root>

The tool will ask you for some information. Answer accordingly.

Lastly, the tool will setup a schedule task which runs every 9.00am in the morning. Let's Encrypt certificates are issued with a validity of 90 days. This task will help to renew the certificates within 30 days before expiry, so you will never have to worry about certificate expiry anymore.

From the output of the tool, note the path of the certificate file and issuer certificate file.

 

(D) Configure Apache to use the SSL certificate

You need to configure an SSL-enabled virtual host for your domain name. Refer to the Apache docs on how to do that. In the virtual host configuration, specify the path to the certificate file, certificate key file, and the certificate chain (issuer certificate) file, which you note down from the output actual generation in Section C (not test generation in Section B). Besides, it is recommended that you redirect all the http traffic to the https site with the correct domain name of your certificate.

Here is an example of a partial Apache configuration.

On the non-SSL virtual host:

<VirtualHost *:80>
    ServerAdmin [email protected]
    ServerName www.commaster.net
    
    RewriteEngine On
    # Redirect to the HTTPS site
    RewriteCond %{HTTPS} off
    RewriteRule ^/?(.*)$ https://www.commaster.net/$1 [NE,L,R=301]
</VirtualHost>

On the SSL virtual host:

<VirtualHost *:443>
    ServerAdmin [email protected]
    ServerName www.commaster.net
    
    RewriteEngine On
    # Redirect to the correct domain name
    RewriteCond %{HTTP_HOST} !^www.commaster.net$ [NC]
    RewriteRule ^/?(.*)$ https://www.commaster.net/$1 [NE,L,R=301]

    Alias /.well-known C:/xampp/htdocs/.well-known

    SSLEngine on
    SSLCertificateFile "C:/Users/<username>/AppData/Roaming/letsencrypt-win-simple/httpsacme-v01.api.letsencrypt.org/<domain-name>-crt.pem"
    SSLCertificateKeyFile "C:/Users/<username>/AppData/Roaming/letsencrypt-win-simple/httpsacme-v01.api.letsencrypt.org/<domain-name>-key.pem"
    SSLCertificateChainFile "C:/Users/<username>/AppData/Roaming/letsencrypt-win-simple/httpsacme-v01.api.letsencrypt.org/ca-<hex>-crt.pem"
</VirtualHost>

Note that the alias for /.well-known path must be copied to the SSL virtual host because it is needed for future certificate renewals.

[EDIT: The "ServerAlias" directive has been removed from the configuration above because the certificate generated is only for a single subdomain. If you wish to have alternate domain names, you may use a redirection as suggested by Alexander in his comments below.]

Restart Apache server so that the new configuration will take effect.

 

References: