This guide shows how to configure Nginx Proxy Manager (NPM) to use mutual TLS (mTLS) authentication with client certificates generated using the issue-client-cert.sh script.
π mTLS ensures that only users with valid certificates can access specific services β ideal for securing admin panels, dashboards, or private endpoints.
- Youβve already issued a client certificate using the main script.
- You have access to your root CA certificate:
roots.pem(generated or cached). - NPM is running via Docker and you can edit its config/volumes.
Mount your roots.pem (or root_ca.crt) into the NPM container:
services:
npm:
image: jc21/nginx-proxy-manager
ports:
- "80:80"
- "443:443"
volumes:
- ./data:/data
- ./letsencrypt:/etc/letsencrypt
- /home/youruser/step-ca/roots.pem:/etc/nginx/ssl/roots.pem:roOr copy manually:
docker cp roots.pem npm:/etc/nginx/ssl/roots.pem- Open NPM UI β Proxy Hosts β Edit the host you want to protect.
- Go to the Advanced tab.
- Add the following block:
ssl_client_certificate /etc/nginx/ssl/roots.pem;
ssl_verify_client on;β This tells Nginx to:
- Require a client certificate
- Verify it against your CA's root
You must restart NPM for changes to take effect:
docker restart npmFrom the client device:
- Install the
.p12bundle you created - Use a browser that supports client certs (most do)
- Visit the domain/subdomain β NPM will prompt for a client certificate
If the cert is valid and signed by your CA, access is granted π
| Problem | Cause | Solution |
|---|---|---|
| 400 Bad Request | No certificate presented | Check browser or mobile config |
| 403 Forbidden | Invalid or unknown cert | Ensure it's signed by your CA |
| NPM wonβt start | Bad config in Advanced tab | Remove ssl_ lines and retry |
- Protecting admin panels (NPM, Portainer, etc.)
- Exposing private services to a trusted circle
- Securing public domains with client-side identity checks
roots.pemβ trusted CA file in NPM*.p12β installed on client devicesissue-client-cert.shβ generates everything you need
- Use mTLS together with Authelia for SSO + 2FA + identity-based policies.
- Rotate client certs yearly using the script β it's fast.
- Use
qrencodeandserve-certs.shto quickly deliver certs to phones.