First things first. SSL (Secure Sockets Layer) is the predecessor to TLS (Transport Layer Security). Since people keep referring to TLS for websites as SSL, that’s what I’ll call it as well. Perhaps someday, no one will use the SSL terminology anymore.
Creating self-signed SSL certificates is relatively easy. Getting them to work with different web browsers can be a challenge. It’s not safe to use them outside a local IP address range, but perfectly safe to use them for local web development.
You don’t have to use the localhost, of course. It’s perfectly fine to use one of the IP addresses on your LAN. My laptop computer uses the static IP address of 192.168.1.100. The domain name I use for web development is simple - domain.local. Since I like working with wildcards, my “hosts” file entry is:
192.168.1.100 domain.local first.domain.local second.domain.local
Every project I work on uses a subdomain, making it easy to drop one without affecting the others.
This is the command I use for creating a self-signed wildcard certificate, which I just tested today:
openssl req -new -x509 -out domain.local.crt -keyout domain.local.key \
-newkey rsa:2048 -nodes -sha256 \
-subj "/CN=*.domain.local" -extensions SAN -reqexts SAN \
-config <(cat /etc/ssl/openssl.cnf <(printf '[SAN]nsubjectAltName=DNS:*.domain.local')) \
I use 3650 days (about 10 years) because why not?
All web browsers treat self-signed certificates as unsafe, regardless of where you use them. To get rid of the interruptions with Chromium-based browsers, put “chrome://flags/#allow-insecure-localhost” in the address bar and enable it (Brave will change “chrome” to “brave”). With Firefox, when you approve it, it gets added to the exceptions.
There’s a better way. Don’t use SSL at all when doing local web development. If you’re using someone else’s code or CMS, you may not have a choice. When you do it yourself, you always have a choice.
If you want your code to be transportable, make it conditional. With PHP, this is what I do:
$site_url = 'http' . ($_SERVER['SERVER_PORT'] == 443 ? 's' : '') . '://' . $_SERVER['HTTP_HOST'];
HTTP_HOST includes alternate port numbers, when you use them. You can do something similar with cookies, to include the secure flag or not.