Usage
In its default configuration, this web app will give you a ZIP file containing
a self-signed root/CA certificate and an end/leaf certificate signed by the CA certificate.
You also get the corresponding private keys.
The CA certificate is what should be trusted by your client software.
Most software relies on your OS' trust store but may have alternative ways to trust certificates.
Some software, notably Firefox, has its own trust store and does not use your operating system's by default.
The end/leaf certificate is what has to be presented to the client by your server software.
Your client will verify that it's signed by a trusted CA certificate and gives an error if it isn't.
Trusting the CA certificate
You likely want your client software to trust the CA certificate so you don't get security errors when using your dev site.
Your client in this case could be a web browser or something else such as a program calling your REST API.
You should do some web searches or consult your client, library, or browser documentation to figure out how to do this.
This page lists some methods for popular software.
Operating Systems
Browsers
- Firefox:
- Go to Settings > Privacy & Security > Security > View Certificates:
- Swap to the Authorities tab and import the certificate. Make sure to check the "Trust this CA to identify websites" option.
- You can also make Firefox use your OS trust store through the
security.enterprise_roots.enabled
option.
- Chrome:
- Chrome on Windows uses your OS trust store. On Linux, it depends on your distribution.
- On Linux, Chrome also checks a separate trust store in your home directory.
You can choose to add your certificate just here instead of system wide.
Go to Settings > Privacy and Security > Security > Manage certificates:
- Swap to the Authorities tab and import the certificate. Make sure to check the "Trust this certificate for identifying websites" option.
HTTP Clients
- cURL:
- Python requests:
- The requests package uses the
certifi
library,
it does not use your operating system's trust store by default.
- There are several options available
to make requests trust your certificate.
You change the code or set the
REQUESTS_CA_BUNDLE
environment variable.
- OpenSSL:
openssl s_client -verify_return_error -verifyCAfile path/to/ca_cert.crt -crlf -connect localhost:443
- Postman:
Configuring the HTTP server
This is where you'll use the [domain name].crt and [domain name].key files.
NGINX
See the official documentation here, but
the gist is this:
server {
listen 443 ssl;
server_name [domain name];
ssl_certificate path/to/[domain name].crt;
ssl_certificate_key path/to/[domain name].key;
ssl_protocols TLSv1.2 TLSv1.3;
ssl_ciphers HIGH:!aNULL:!MD5;
}
Apache HTTP Server
Checkout the official documentation here.
LoadModule socache_shmcb_module modules/mod_socache_shmcb.so
LoadModule ssl_module modules/mod_ssl.so
Include conf/extra/httpd-ssl.conf
SSLCertificateFile "path/to/[domain name].crt"
SSLCertificateKeyFile "path/to/[domain name].key"
Caddy
See the full documentation for the tls
directive.
[domain name] {
tls "path/to/[domain name].crt" "path/to/[domain name].key"
}
HAProxy
For more details, see the HAProxy TLS Documentation.
For HAProxy, you must combine the certificate and key into one file with the key
coming last. On a Unix-like environment, you can do that with the following command:
$ cat "path/to/[domain name].crt" "path/to/[domain name].key" >"path/to/[domain name].combined.crt"
frontend www
bind :80
bind :443 ssl crt path/to/[domain name].combined.crt
http-request redirect scheme https unless { ssl_fc }
Lighttpd
Lighttpd TLS documentation.
server.modules += ("mod_openssl")
$SERVER["socket"] == ":443" {
ssl.engine = "enable"
ssl.pemfile = "path/to/[domain name].crt"
ssl.privkey = "path/to/[domain name].key"
}
NPM http-server
See all available run options.
$ npx http-server --tls --cert "path/to/[domain name].crt" --key "path/to/[domain name].key" dist/
Node.js
Also see the official documentation.
const https = require('node:https');
const fs = require('node:fs');
const options = {
cert: fs.readFileSync('path/to/[domain name].crt'),
key: fs.readFileSync('path/to/[domain name].key'),
};
https.createServer(options, (req, res) => {
res.writeHead(200);
res.end('hello world\n');
}).listen(443);
Cowboy
Use cowboy:start_tls/3
along with the certfile
and keyfile
ranch_ssl:opts()
options.
start(_StartType, _StartArgs) ->
Dispatch = cowboy_router:compile([
{'_', [{"/", hello_handler, []}]}
]),
{ok, _} = cowboy:start_tls(my_https_listener,
[{port, 443},
{certfile, "path/to/[domain name].crt"},
{keyfile, "path/to/[domain name].key"}],
#{env => #{dispatch => Dispatch}}
),
tls_example_sup:start_link().
Kestrel
See the Kestrel Endpoint configuration docs.
Add something like the following into your appsettings.json
:
{
"Kestrel": {
"Endpoints": {
"Https": {
"Url": "https://localhost:443",
"Certificate": {
"Path": "path/to/[domain name].crt",
"KeyPath": "path/to/[domain name].key"
}
}
}
}
}
Gunicorn
Gunicorn SSL settings.
There are various ways to configure Gunicorn; this example uses the command line:
gunicorn \
--bind :443 \
--certfile "path/to/[domain name].crt" \
--keyfile "path/to/[domain name].key" \
app:app
Uvicorn
Uvicorn HTTPS settings.
uvicorn \
--port 443 \
--ssl-certfile="path/to/[domain name].crt" \
--ssl-keyfile="path/to/[domain name].key" \
app:app
uWSGI
uWSGI HTTPS support.
uwsgi \
--https "0.0.0.0:443,path/to/[domain name].crt,path/to/[domain name].key,HIGH" \
--wsgi-file app.py