Skip to content

Instantly share code, notes, and snippets.

@justinhartman
Last active January 27, 2024 13:22
Show Gist options
  • Save justinhartman/36cccc6ce26a01378369b35fd048748a to your computer and use it in GitHub Desktop.
Save justinhartman/36cccc6ce26a01378369b35fd048748a to your computer and use it in GitHub Desktop.
How to create self-signed SSL certificates for localhost that actually works

How to create self-signed SSL certificates for localhost

Option 1

Create a directory in your user root directory where we will store the necessary generated files.

$ cd ~/
$ mkdir .localhost
$ cd .localhost

Now run this single command and you will have both a certificate and private key which was used to sign the certificate.

$ openssl req -x509 -out localhost.crt -keyout localhost.key \
  -newkey rsa:4096 -nodes -sha256 \
  -subj '/CN=localhost' -extensions EXT -config <( \
   printf "[dn]\nCN=localhost\n[req]\ndistinguished_name = dn\n[EXT]\nsubjectAltName=DNS:localhost\nkeyUsage=digitalSignature\nextendedKeyUsage=serverAuth")

Option 2

This option uses a pre-defined configuration file called openssl.cnf of which you can see the contents in this gist, added as an attachment.

Create a directory in your user root directory where we will store the necessary generated files.

$ cd ~/
$ mkdir .localhost
$ cd .localhost

Make sure you use the attached openssl.cnf by modifying it to your needs and then saving the file in the ~/.localhost folder.

$ nano openssl.cnf

Once your file is saved you can now run the following commands to generate your self-signed certificate.

$ sudo openssl genrsa -out localhost.key 4096
$ sudo openssl req -new -out localhost.csr -key localhost.key -config openssl.cnf
$ sudo openssl x509 -req -days 8030 -in server.csr -signkey localhost.key -out localhost.crt -extensions v3_req -extfile openssl.cnf

Apache2 Configuration

You will need to change your VHOST configuration to enable SSL and to ensure Apache accepts SSL traffic. Make sure that you have mod_ssl enabled. You can check if it is enabled in your httpd.conf file under the Dynamic Shared Object (DSO) Support directives.

Ensure that LoadModule ssl_module lib/httpd/modules/mod_ssl.so is uncommented as per the example below.

#
# Dynamic Shared Object (DSO) Support
#
# To be able to use the functionality of a module which was built as a DSO you
# have to place corresponding `LoadModule' lines at this location so the
# directives contained in it are actually available _before_ they are used.
# Statically compiled modules (those listed by `httpd -l') do not need
# to be loaded here.
#
# Example:
# LoadModule foo_module modules/mod_foo.so
#
#LoadModule expires_module lib/httpd/modules/mod_expires.so
LoadModule headers_module lib/httpd/modules/mod_headers.so
#LoadModule proxy_connect_module lib/httpd/modules/mod_proxy_connect.so
LoadModule ssl_module lib/httpd/modules/mod_ssl.so
#LoadModule dialup_module lib/httpd/modules/mod_dialup.so
#LoadModule http2_module lib/httpd/modules/mod_http2.so

Once mod_ssl is enabled you need to configure the Apache VHOST as per the apache2-ssl-vhost-settings.conf file that I've attached to this gist. The key bits that need to be added are:

    SSLEngine on
    SSLCertificateFile "/Users/macbookpro/.localhost/localhost.crt"
    SSLCertificateKeyFile "/Users/macbookpro/.localhost/localhost.key"

This enables the Apache SSL engine and tells Apache where it should look for both the Certificate and Certificate Key files. Assuming you have completed all these steps you can restart Apache and it should all be working.

Good luck.

[req]
distinguished_name = req_distinguished_name
req_extensions = v3_req
[req_distinguished_name]
countryName = ZA
countryName_default = ZA
stateOrProvinceName = Western Cape
stateOrProvinceName_default = Western Cape
localityName = Cape Town
localityName_default = Cape Town
organizationName = 22 Digital
organizationName_default = 22 Digital
organizationalUnitName = Development Team
organizationalUnitName_default = Development Team
commonName = localhost
commonName_default = localhost
commonName_max = 64
[ v3_req ]
# Extensions to add to a certificate request
basicConstraints = CA:FALSE
keyUsage = nonRepudiation, digitalSignature, keyEncipherment
subjectAltName = @alt_names
[alt_names]
DNS.1 = *.localhost
DNS.2 = *.hartman.localhost
DNS.3 = *.22digital.localhost
DNS.4 = *.laravel.localhost
DNS.5 = *.grav.localhost
<VirtualHost _default_:443>
ServerName localhost
DocumentRoot "/var/www/html/localhost"
ErrorLog /var/log/apache2/error-ssl-localhost.log
CustomLog /var/log/apache2/access-ssl-localhost.log combined
SSLEngine on
SSLCertificateFile "/Users/macbookpro/.localhost/localhost.crt"
SSLCertificateKeyFile "/Users/macbookpro/.localhost/localhost.key"
</VirtualHost>
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment