Make Self-Signed Certificate

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

HTTP Clients

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.

# /usr/local/apache2/conf/httpd.conf

# ...

LoadModule socache_shmcb_module modules/mod_socache_shmcb.so
LoadModule ssl_module modules/mod_ssl.so

# Secure (SSL/TLS) connections
Include conf/extra/httpd-ssl.conf

# ...
# /usr/local/apache2/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