This is a quick guide on how to set up a locally hosted and SSL-enabled Apache web server, running on a Windows PC.
It is way too hard to find a comprehensive explanation on how to enable SSL on a locally hosted Apache web server. There’s bits and pieces, but most of the information available online is either based on how to set it up on a Linux system, or how to set it up for a public-facing website (using SSL providers like Let’s Encrypt), or how to get started on a Windows system… but nobody seems to have a complete start-to-finish manual on how to:
- Set up a local CA (Certificate Authority),
- Incorporate said CA on all systems,
- Create a server-validating SSL certificate (using that CA) on the web server, and finally:
- Activate said server-validating SSL certificate in Apache.
Now, one might ask “Why would you need SSL on a locally hosted web server? Localhost is already treated as inherently safe by most—if not all—web browsers?” And that’s a very fair point, but there is an explanation: Having local SSL available for development purposes allows you to test websites (and their behavior) in a working environment—SSL websites work in a different way, especially when it comes to adding things like JavaScript.
Before actually getting started, a couple of remarks/caveats:
- The instructions are meant specifically for an environment which is closed off from the internet (e.g.: a firewalled development/personal playground environment), and is not meant to be used on any local network that is in any way, shape or form, accessible from “the outside” – creating a local CA and making it trusted will make your systems vulnerable to so-called Man-in-the-middle attacks, with the possibility of marking unsafe/malicious sites, apps/applications and executables as “trusted”, as well.
So if you do follow these instructions, you do so at your own risk, and I shall not and will not be held accountable for any security issues (including but not limited to loss, involuntary sharing or unavailability of private/confidential information, and/or any broken security/protection of your systems and/or data).
- I realize there’s faster ways than will be shown to get information loaded into the certificates by using config files, or complete command-line options. I opted to go for the more interactive way, however, to prevent having to use long, looooong lines of text and/or mishaps with filename extensions in the default Windows setup. The method outlined below worked for me, and should work for anyone.
- The values I show should be adjusted to match your setup. Mine is based on the availability of a local DNS system, the fact that my web server runs on a separate PC, and all my systems are named and added to a “domain” I simply called “home”.
So remember that YMMV.
All that said, let’s get to certifying, shall we? It’s not a long manual, but it does require paying close attention to ensure you’re not confronted with undecipherable errors, leaving you stumped and frustrated, like I was, several times over during the discovery process.
Prerequisites and preparation
To get working on creating a local Certificate Authority and the subsequent validation certificate(s), there’s actually a variety of tools available. I’m going to use the free OpenSSL tool, as it has the most readily and abundantly available information on how to use it (so naturally, that’s what I used).
You can get it via (not from) the official OpenSSL website: https://wiki.openssl.org/index.php/Binaries. I used the very first download link (https://slproweb.com/products/Win32OpenSSL.html), which also worked on my 64-bit Windows system.
After installing the software, to add some convenience (by not having to remember the full exe path for the actual certificate creation), include its location to your system’s PATH variable:
- Start – Run:
C:\Windows\System32\systempropertiesadvanced.exe - Select the Advanced tab, then click the Environment Variables button at the bottom
- In the User variables for [yourname], double-click the Path line, and add the full path of the folder in which the executable openssl.exe is placed.
- Click OK, and OK again, to save the adjusted path variable.
Now, I have my web server running on a secondary PC (my HTPC boxxen), not my everyday-use-system. For the creation of the CA and other certificates this makes no difference—you can create the certificates wherever. I opted to use a mapped network drive on my HTPC to create all files, but any folder will do. You won’t need to actually work on the web server until part 2 of this manual.
What we are going to do is create two certificates: one for our local CA (Certification Authority), and one for the web server. For our purposes, that’s really all we need.
1. Create and implement the CA certificate
- Create a folder on your working system or the web server PC (but mind to NOT create it inside the htdocs folder); this folder will, when we’re done, contain all certificate and key files.
- Open a Command Prompt window. No need to do this as an Administrator.
- CD to the newly created folder – in my example, I created the folder on the HTPC’s C: drive, mapped to my working PC as drive J:.
- In here, we first generate what is called a key file; this is required for creating a valid certificate. We’ll make it an unprotected 4096-bit RSA key.
Note: Normally, a key file should be protected with a password, but because this is local network only, and not used on the greater expanses of the internet, we’ll skip that.
If you do want to password-protect the key, add the option-aes256betweengenrsaand-out. This will prompt you to enter a pass-phrase after hitting ENTER.
Type the following line, and confirm with ENTER:openssl genrsa -out ca.key 4096
- With the key file in place, we can generate the actual certificate. We’ll keep it straightforward, and make it valid for 10 years (something you absolutely shouldn’t do if this were an internet-facing thing. Which it shouldn’t be!)
Type the following line, and confirm with ENTER:openssl req -new -x509 -days 3650 -key ca.key -out ca.crt
- You will be prompted to add information to the certificate; remember what you fill in, because you will need these items later on for the Server certificate. In order of appearance:
Country: Enter the two-character country code for the country you’re in.
State or Province name: I entered the two-character code for the province I live in. You can enter full country name, state name or abbreviation, or make something up.
Locality name: Name of the city you reside in. Or make something up.
Organization name: Really, whatever. I used my own internet domain (what else?), but really, whatever works for you.
Organizational Unit Name: Once again, whatever. I just went for what I filled in for Organization name.
Common Name: Domain name, your name, company name, once again, whatever (I chose “home”, but it can be anything—as long as the Server certificate later on does NOT have to use this same value!)
Email Address: Can be anything, even empty.
- After the last item has been entered, no further feedback will be given, but your folder will now contain both a ca.key and a ca.crt file.
Now, on all systems that will need to access the SSL-protected web server when it’s online (including the web server itself), this certificate must be added to Windows’ Trusted Root Certificate Authorities list. This is a simple enough process, fortunately.
- Start, type mmc.exe, choose Run as administrator.
- Click File: Add/Remove Snap-in…
- Select Certificates on the left, click Add > in the middle.
- Select Computer account and click Next.
- Leave the next option as indicated (“Local computer”) and click Finish.
- Click OK to continue loading the Certificate Manager.
- Expand the Console Root on the left, then Trusted Root Certification Authorities, right-click on its subfolder Certificates, and select All tasks > Import…
- Browse to and select the ca.crt file you just created.
After this, the certificate should be listed under the name you indicated earlier as the Common name:
You can now close the MMC console again, and that’s it for part 1.
2. Create the server certificate
With the CA created, we can now move on to generating the actual SSL certificate for our web server. To do so, we’ll need to do a tiny bit of preparation, to ensure the web server works by itself as well as from other systems on the network.
In the folder we created the CA certificate and key, create a new Text file, and name it domains.ext:
Open the file in your text editor of choice, and add the following information verbatim, but change servername and servername.domain to match your setup:
authorityKeyIdentifier=keyid,issuer
basicConstraints=CA:FALSE
keyUsage = digitalSignature, nonRepudiation, keyEncipherment, dataEncipherment
subjectAltName = @alt_names
[alt_names]
DNS.1=localhost
DNS.2=servername
DNS.3=servername.domain
Save and close the file.
Now, we create a key file and a so-called “certificate request” for the server certificate in one go. In the Command Prompt window, type the following command, replacing the [bracketed] values (including the brackets) with the values you entered above (in the CA information list).
So you would, for example, replace [COUNTRY] with US, [PROVINCE/STATE] with ME, [CITY] with Castle Rock, etc.. Make sure to not include the brackets themselves in the command line!
openssl req -new -nodes -newkey rsa:2048 -keyout server.key -out server.csr -subj "/C=[COUNTRY]/ST=[PROVINCE/STATE]/L=[CITY]/O=[ORGANIZATION]/CN=[servername.domain]"
If all goes well, several lines of dots and pluses should appear to indicate an encrypted key file is generated. After this, type:
openssl x509 -req -sha256 -days 1825 -in server.csr -CA ca.crt -CAkey ca.key -CAcreateserial -extfile domains.ext -out server.crt
This will generate the actual server certificate, which will finally allow you to add SSL-abilities to your Apache web server (which is valid for 5 years, so set yourself a reminder for 4 years, 11 months and 3 weeks into the future to create a new certificate).
All of that brings us to:
3. Adding the certificates to and enabling them in Apache
Note that this is assuming the simplest possible setup:
- A working Apache installation,
- A single htdocs folder, containing:
- One (1, already existing) website called localhost, which is or is not accessible from other systems as well, by its servername or servername.domain name.
- In the Apache main directory (or really anywhere but the htdocs folder), create a new folder called SSL. I placed mine under the conf folder.
- Copy the server.key and server.crt files to that SSL folder.
- Open conf\httpd.conf in your text editor of choice.
- Find the line that says
Listen 80. Directly below that line, addListen 443
- Find the line
#LoadModule ssl_module modules/mod_ssl.so, and remove the#at the start.
- Find the line
#Include conf/extra/httpd-vhosts.conf, and remove the#at the start.
- Save and close httpd.conf.
- Open conf\extra\httpd-vhosts.conf in the text editor.
- If the default VirtualHost entries are listed, remove them, and add the following text verbatim, only replacing the servername.domain and folder parts (marked red):
<VirtualHost *:443>
ServerName servername.domain
DocumentRoot "${SRVROOT}/htdocs"
SSLEngine on
SSLCertificateFile "${SRVROOT}/folder/ssl/server.crt"
SSLCertificateKeyFile "${SRVROOT}/folder/ssl/server.key"
</VirtualHost>
- Save and close httpd-vhosts.conf.
- Restart the Apache service.
4. Cleanup
All that remains is a bit of cleanup. You created a local CA certificate with a key to match. You’re going to have to keep it in a safe place, so that, should your system be compromised, people can’t just use it for whatever. On the other hand—it’s a local DEV CA with no validation from the actual root CAs already online, so it’ll be pretty worthless… but to make sure your own systems are kept safe-ish, use a vault-surrogate, by creating a password-protected ZIP file (7-Zip File Manager has a built-in option to do so):
- In 7-Zip File Manager, browse to the folder that contains the original certificates and keys.
- Select all files, and click the Add icon. This will open a window called Add to Archive. In here:
Set Archive format to zip;
Set Compression level to Store;
Set Update mode to Add and replace files;
Set Path mode to Relative pathnames;
Enter a password (twice, of course);
Set Encryption method to AES-256.
- Click OK to create the password-protected ZIP file, and close the File Manager.
- Try to extract the ZIP file, and verify it asks for a password.
- Delete the original CRT, KEY, CSR and EXT files.
- Keep the ZIP file somewhere safe. And don’t forget to remember its password.
susiso dot nl