mkcert: Create Locally Valid HTTPS Certificates on Debian

TL;DR: mkcert is a zero-configuration CLI tool that creates locally trusted TLS certificates on Debian. It installs a local CA into your system trust store, so browsers and tools trust your localhost and LAN dev environments over HTTPS — no security warnings.

What You’ll Learn

By the end of this guide you will be able to:

  • Install mkcert on Debian (Bookworm / Bullseye)
  • Install the local CA into your system and browser trust stores
  • Generate valid HTTPS certificates for localhost, custom domains, and LAN IPs
  • Configure Nginx or Apache to use those certificates
  • Understand how mkcert compares to self-signed certificates and Let’s Encrypt

Prerequisites

OS: Debian 11 (Bullseye) or Debian 12 (Bookworm)
Access: sudo privileges
Network: Internet access for the initial download
Optional: Nginx or Apache for the web server example

Why mkcert — and Why Not Self-Signed Certificates

A self-signed certificate is not trusted by any browser or system by default. Every developer on the team has to manually accept the security exception, and tools like curl reject the connection unless you pass --insecure. That flag disables all TLS verification — which defeats the purpose of testing HTTPS behavior.

mkcert solves this by generating a local Certificate Authority (CA) and installing it into the system trust store, Firefox’s NSS store, and (on Linux with Chromium) the Chrome/Chromium store automatically. Once installed, every certificate mkcert signs is trusted natively — no exceptions, no flags.

Let’s Encrypt is the right tool for production domains. mkcert is the right tool for localhost, *.dev.local, and LAN addresses that Let’s Encrypt cannot reach.

Step 1 — Install Dependencies

mkcert requires certutil (from the libnss3-tools package) to update Firefox and Chromium trust stores. Install it first:

sudo apt update
sudo apt install -y libnss3-tools wget

Step 2 — Download and Install mkcert

Fetch the latest binary from the mkcert releases page. Always check there for the current version before running the commands below:

# Download the latest mkcert binary for Linux AMD64
wget https://github.com/FiloSottile/mkcert/releases/download/v1.4.4/mkcert-v1.4.4-linux-amd64

# Rename and move it into your PATH
sudo mv mkcert-v1.4.4-linux-amd64 /usr/local/bin/mkcert

# Make it executable
sudo chmod +x /usr/local/bin/mkcert

Verify the installation:

mkcert --version
# Expected output: v1.4.4

Step 3 — Install the Local Certificate Authority

mkcert -install generates a local CA keypair and places the root certificate into the system trust store and the NSS database used by Firefox and Chromium:

mkcert -install

Expected output:

Created a new local CA
The local CA is now installed in the system trust store!
The local CA is now installed in the Firefox trust store (requires browser restart)!

You can inspect the CA files location with:

mkcert -CAROOT
# Example: /root/.local/share/mkcert

⚠️ Security warning: The rootCA-key.pem file in your CAROOT directory is the private key for your local CA. Anyone who obtains it can sign certificates your system will trust. Do not share or commit this file.

Step 4 — Generate Certificates

Navigate to the directory where you want to store the certificate files, then run mkcert with the domains or IPs you need:

mkdir -p ~/certs && cd ~/certs
mkcert localhost 127.0.0.1 ::1 myapp.dev.local 192.168.1.100

This produces two files:

localhost+4.pem        ← the certificate (public)
localhost+4-key.pem    ← the private key (keep this secure)

You can also generate a wildcard certificate for a local domain:

mkcert "*.dev.local" dev.local

Step 5 — Configure Nginx to Use the Certificate

Place the certificate files in a secure directory and configure Nginx:

sudo mkdir -p /etc/ssl/certs/local
sudo cp ~/certs/localhost+4.pem     /etc/ssl/certs/local/local.pem
sudo cp ~/certs/localhost+4-key.pem /etc/ssl/certs/local/local-key.pem
sudo chmod 600 /etc/ssl/certs/local/local-key.pem

Create or edit your Nginx server block:

server {
    listen 443 ssl;
    server_name localhost myapp.dev.local;

    ssl_certificate     /etc/ssl/certs/local/local.pem;
    ssl_certificate_key /etc/ssl/certs/local/local-key.pem;

    root /var/www/html;
    index index.html;

    location / {
        try_files $uri $uri/ =404;
    }
}

server {
    listen 80;
    server_name localhost myapp.dev.local;
    return 301 https://$host$request_uri;
}

Test and reload:

sudo nginx -t && sudo systemctl reload nginx

Step 6 — Configure Apache to Use the Certificate

Enable the SSL module and configure a virtual host:

sudo a2enmod ssl
sudo systemctl restart apache2

    ServerName localhost
    ServerAlias myapp.dev.local

    SSLEngine on
    SSLCertificateFile     /etc/ssl/certs/local/local.pem
    SSLCertificateKeyFile  /etc/ssl/certs/local/local-key.pem

    DocumentRoot /var/www/html
sudo apache2ctl configtest && sudo systemctl reload apache2

Troubleshooting / Common Pitfalls

Firefox still shows an untrusted certificate

Firefox uses its own NSS certificate store. Run mkcert -install again after closing Firefox, then restart it. On some Debian setups, certutil must be installed before mkcert can modify the Firefox store.

Chrome / Chromium does not trust the certificate

On Linux, Chrome reads the NSS database at ~/.pki/nssdb. Run mkcert -install and fully restart Chrome.

curl still rejects the certificate

System-wide curl uses the system CA bundle. Verify the CA is installed with:

update-ca-certificates --verbose 2>&1 | grep mkcert

If missing, re-run mkcert -install with sudo.

Certificate does not cover my hostname

List every hostname and IP at generation time. Regenerate with all names:

mkcert localhost 127.0.0.1 myapp.dev.local 192.168.1.50

Running on a remote VM or headless server

mkcert cannot install to a browser trust store on headless systems. Generate the certificate on the server, then copy $(mkcert -CAROOT)/rootCA.pem to each developer’s machine and import it into their browser manually.

Key Takeaways

  • mkcert installs a local CA and issues certificates your system and browsers trust natively — no manual exception clicks required.
  • Run mkcert -install once per machine; generate certificates per-project as needed.
  • The rootCA-key.pem file is sensitive — treat it like a production private key.
  • mkcert is for local development only. Use Let’s Encrypt or a public CA for any internet-facing service.
  • Wildcard certificates (*.dev.local) simplify multi-subdomain local setups.

Further Reading

Similar Posts

Leave a Reply

Your email address will not be published. Required fields are marked *