nexus-ncm-certs.sh¶
mTLS client certificate manager for the NeXuS NCM web dashboard.
Location: ~/scripts/ncm/nexus-ncm-certs.sh
Repo: hackenstacks/nexus-scripts · hackenstacks/nexus-connection-manager
What It Does¶
The NCM web dashboard at https://localhost:8443/ncm/ includes a live terminal (xterm.js → PTY shell). mTLS locks it down so only browsers holding a valid client certificate can connect — rejection happens at the TLS handshake before any HTTP is served.
This script manages the full certificate lifecycle:
- Creates a local CA (Certificate Authority) stored in
~/vault/ncm-ca/ - Issues
.p12bundles (cert + key + CA, ready for browser import) for each trusted device - Revokes compromised certs and rebuilds the CRL
- Patches the web server and proxy script to enforce client cert auth
Quick Start¶
# 1. Create the CA (one time per node)
nexus-ncm-certs.sh init
# 2. Issue a cert for your laptop browser
nexus-ncm-certs.sh issue laptop
# → creates ~/vault/ncm-ca/clients/laptop.p12
# → prints a random import password
# 3. Wire the CA into the web server
nexus-ncm-certs.sh install
# 4. Restart the web server
nexus-api-proxy.sh restart
# 5. Import laptop.p12 into LibreWolf/Firefox:
# Settings → Privacy & Security → Certificates → Your Certificates → Import
Commands¶
init¶
Creates the Certificate Authority. Run once per node.
Generates a 4096-bit RSA CA key and a self-signed CA certificate valid for 10 years. Both live in ~/vault/ncm-ca/ with permissions set to 700.
issue <name>¶
Issues a client certificate for one trusted device.
Each invocation:
- Generates a 2048-bit RSA key for the device
- Signs a certificate valid for 2 years
- Exports a
.p12bundle with a randomly-generated import password - Prints the import password and browser import instructions
Keep the import password
The .p12 import password is printed once and saved alongside the file as <name>.pass. The password protects the key inside the .p12 — without it the browser cannot import the cert.
Transfer to another device:
# Via SCP
scp ~/vault/ncm-ca/clients/phone.p12 user@192.168.1.x:/tmp/
# As base64 (paste into remote terminal)
base64 ~/vault/ncm-ca/clients/phone.p12
Browser import:
| Browser | Path |
|---|---|
| LibreWolf / Firefox | Settings → Privacy & Security → Certificates → Your Certificates → Import |
| Chromium / Chrome | Settings → Privacy & Security → Manage Certificates → Import |
| Android (Chrome) | Settings → Security → Install a Certificate → VPN & App User Certificate |
list¶
Shows all issued certificates and their status.
Output:
── NeXuS NCM Client Certificates ──
CA: /home/user/vault/ncm-ca/ca.crt (expires Sep 3 06:39:30 2036 GMT)
NAME EXPIRES STATUS
────────────────────────────────────────────────────────────
laptop Sep 3 06:39:30 2028 GMT VALID
phone Sep 3 06:39:30 2028 GMT VALID
old-device Sep 3 06:39:30 2027 GMT REVOKED
revoke <name>¶
Revokes a certificate and rebuilds the CRL (Certificate Revocation List).
- Marks the cert as revoked in the OpenSSL index
- Rebuilds
~/vault/ncm-ca/crl.pem - Removes the
.p12so it cannot be re-imported - The revoked cert is rejected on the next TLS handshake after the web server reloads the CRL
Note
Restart the web server after revoking to enforce the new CRL immediately.
install¶
Patches the web server to require client certificates on every connection.
Two files are patched:
nexus_web_server.py— adds--ca-certand--ca-crlCLI arguments; wires them into the SSL context withssl.CERT_REQUIREDnexus-api-proxy.sh— passes--ca-cert ~/vault/ncm-ca/ca.crt --ca-crl ~/vault/ncm-ca/crl.pemto the server start command
After running install, restart the web server. Any browser without a valid client cert will receive a TLS handshake failure — no HTTP response, no page, no error message to fingerprint.
uninstall¶
Removes the client cert requirement (interactive confirmation required).
Removes the --ca-cert flags from nexus-api-proxy.sh. The web server reverts to HTTPS-only (no client cert check) after restart.
show-ca¶
Prints the CA certificate in PEM format for importing into device trust stores.
Useful when a device needs to trust the CA (e.g., to avoid TLS warnings when accessing other services signed by the same CA).
File Layout¶
~/vault/ncm-ca/
├── ca.key — CA private key (600 permissions)
├── ca.crt — CA certificate (import this on devices that need to trust the CA)
├── ca.srl — Serial number counter
├── crl.pem — Certificate Revocation List (rebuilt on every revoke)
├── index.txt — OpenSSL certificate database
├── openssl.cnf — OpenSSL CA configuration (auto-generated)
└── clients/
├── laptop.key — Device private key (600)
├── laptop.crt — Device certificate
├── laptop.p12 — Browser import bundle (cert + key + CA)
└── laptop.pass — Import password (keep safe)
Security Model¶
Browser (laptop.p12 installed)
│
│ TLS ClientHello + Certificate
▼
NeXuS Web Server (ssl.CERT_REQUIRED)
│ Verifies against CA + CRL
├── VALID → connection proceeds, HTTP served
└── INVALID → TLS handshake fails, connection dropped
no HTTP response, no fingerprint
The CA key never leaves ~/vault/ncm-ca/. Client keys never leave the device they were issued for (the .p12 is the transfer mechanism — once imported and the file deleted from the target device, the key is only in the browser's certificate store).
Environment Variables¶
| Variable | Default | Description |
|---|---|---|
NCM_CA_DIR |
~/vault/ncm-ca |
CA and client cert storage |
NEXUS_PROXY_SCRIPT |
~/scripts/nexus-api-proxy.sh |
Script to patch for mTLS |
NEXUS_WEB_SERVER |
~/Projects/nexus-web-server/nexus_web_server.py |
Server to patch |