SSL/TLS Setup Guide for KrakenHashes¶
This guide explains how to set up and trust the self-signed SSL certificates used by KrakenHashes on various platforms.
Overview¶
KrakenHashes uses self-signed certificates by default to secure communications between components. When you first access the web interface, your browser will warn you about the untrusted certificate. This is expected behavior for self-signed certificates.
To avoid these warnings, you need to install the KrakenHashes Certificate Authority (CA) certificate as a trusted root certificate on your system.
Required: the addresses your certificate must cover¶
Agents cannot connect to an address the certificate does not name
The certificate generated on first boot covers only 127.0.0.1 and localhost. An agent connecting to any other address — a LAN IP such as 192.168.1.50, a Tailscale address such as 100.x.y.z, or a hostname — will fail TLS verification and can never connect. This is the single most common cause of an agent that registers but never comes online.
Add every address your agents and browsers use in Admin → Settings → Server Certificate, then click Apply & Reissue. The change takes effect immediately:
- The certificate is reissued under the existing certificate authority, so every already-enrolled agent keeps working with the
ca.crtit already has. - The backend picks up the new certificate on the next connection. No restart is required.
- Agents that were failing reconnect on their own within 30 seconds.
Only private and VPN addresses are accepted — RFC 1918 (10.x, 172.16–31.x, 192.168.x), CGNAT (100.64–127.x), link-local, and IPv6 ULA. Public, internet-routable addresses are rejected: KrakenHashes stores cracked credentials and must never be reachable from the internet.
Self-hosted VPN? Check your network range is actually private
The CGNAT range covers Tailscale and NetBird's default account network, which NetBird's management server picks as a random /16 inside 100.64.0.0/10.
A self-hosted NetBird or WireGuard mesh can be pointed at any range, and it is easy to pick one that is not private. 100.133.64.0/19 looks like CGNAT because it starts with 100., but CGNAT stops at 100.127.255.255 — anything above that is address space assigned to someone else on the internet. KrakenHashes will refuse such an address, and that refusal is correct: an overlay built on someone else's space also stops every peer on it from reaching the real hosts there.
Check yours:
netbird status | grep 'NetBird IP' # NetBird
ip -o -4 addr show wt0 # NetBird interface
ip -o -4 addr show # any VPN interface
If it falls outside 10.0.0.0/8, 172.16.0.0/12, 192.168.0.0/16 or 100.64.0.0/10, change the VPN's network range rather than looking for a way around the check. Note that renumbering re-allocates every peer address, so the backend's VPN address — and therefore this certificate's SAN list and any BackendVPNHost in cloud provider settings — will need updating afterwards.
If an agent is already failing, the address it is trying to reach appears automatically under Discovered addresses on that page, reported by the agent itself, so you can add it with one click.
Setting it before first boot
KH_ADDITIONAL_IP_ADDRESSES and KH_ADDITIONAL_DNS_NAMES still seed the very first certificate, and are imported into the settings above on first start. After that the settings are authoritative and the variables are ignored.
Downloading the CA Certificate¶
The CA certificate can be downloaded from: - Via the web interface: click the download icon in the application header, or go to Settings > Security and click Download CA certificate. Both download https://your-server/ca.crt from the same origin as the web UI, so they work through a VPN or reverse proxy without any extra ports. - HTTPS endpoint: https://your-server/ca.crt (same origin as the web UI) - HTTP endpoint: http://your-server/ca.crt on port 80, or http://your-server:1337/ca.crt directly from the backend. Port 1337 is the agent bootstrap port and should only be reachable by agents (see the Security guide); users should prefer the HTTPS endpoint.
Save the file as krakenhashes-ca.crt for the following instructions.
Browser Certificate Warnings
When accessing KrakenHashes with self-signed certificates before installing the CA, your browser will display a security warning. This is expected behavior. You can proceed past the warning (using "Advanced" > "Proceed anyway" or similar) to access the application and download the CA certificate from the header icon or the Security settings page.
WebSocket Features Require CA Installation
Real-time features like notifications use WebSocket connections (WSS). Unlike regular HTTPS requests, browsers silently reject WebSocket connections to servers with untrusted certificates - there is no option to proceed past the warning. If you're not receiving real-time notifications, ensure the CA certificate is properly installed and your browser has been restarted.
Installation Instructions by Platform¶
Linux Systems¶
Debian/Ubuntu¶
-
Copy the CA certificate to the system certificate directory:
-
Update the certificate store:
-
You should see output indicating the certificate was added:
Fedora/RHEL/CentOS/Rocky Linux¶
-
Copy the CA certificate to the trust anchors directory:
-
Update the trust store:
Arch Linux¶
Using trust anchor command (Recommended):
# This is the official Arch way - it handles everything automatically
sudo trust anchor --store krakenhashes-ca.crt
Note: The trust anchor --store command automatically: - Places the certificate in /etc/ca-certificates/trust-source/anchors/ - Updates the trust database with update-ca-trust - Handles p11-kit integration properly
Additional Step for Chrome/Chromium on Linux¶
Chrome and Chromium browsers maintain their own certificate store on Linux. After installing the system certificate, you also need to:
-
Install the certificate in the NSS database:
-
Restart Chrome/Chromium for the changes to take effect.
To verify the certificate was installed:
To remove the certificate later if needed:
Windows¶
Using Certificate Manager (GUI)¶
- Press
Win + R, typecertmgr.msc, and press Enter - Navigate to "Trusted Root Certification Authorities" > "Certificates"
- Right-click on "Certificates" and select "All Tasks" > "Import..."
- Follow the Certificate Import Wizard:
- Click "Next"
- Browse and select the
krakenhashes-ca.crtfile - Click "Next"
- Ensure "Place all certificates in the following store" is selected with "Trusted Root Certification Authorities"
- Click "Next" and then "Finish"
- When prompted with a security warning, click "Yes" to install the certificate
Using PowerShell (Administrator)¶
# Import the certificate to the Trusted Root store
Import-Certificate -FilePath "C:\path\to\krakenhashes-ca.crt" -CertStoreLocation Cert:\LocalMachine\Root
Using Command Prompt (Administrator)¶
macOS¶
Using Keychain Access (GUI)¶
- Double-click the
krakenhashes-ca.crtfile - Keychain Access will open
- Select "System" keychain (you may need to authenticate)
- The certificate will be added but marked as untrusted
- Double-click on the "KrakenHashes Root CA" certificate
- Expand the "Trust" section
- Change "When using this certificate" to "Always Trust"
- Close the window and authenticate to save changes
Using Command Line¶
# Add certificate to system keychain
sudo security add-trusted-cert -d -r trustRoot -k /Library/Keychains/System.keychain krakenhashes-ca.crt
Verification¶
After installing the certificate, you can verify it's working:
- Browser Test: Navigate to
https://your-server:31337- you should no longer see certificate warnings - Command Line Test:
Certificate Details¶
The self-signed certificates generated by KrakenHashes include:
- CA Certificate: Valid for 10 years (3650 days)
- Server Certificate: Valid for 1 year (365 days)
- Key Size: 4096-bit RSA (configurable)
- Extensions:
- SubjectKeyIdentifier and AuthorityKeyIdentifier for proper chain validation
- BasicConstraints properly set (CA:TRUE for CA, CA:FALSE for server)
- Appropriate KeyUsage and ExtendedKeyUsage flags
Environment Variables¶
You can customize certificate generation with these environment variables:
KH_ADDITIONAL_DNS_NAMES: Comma-separated additional DNS names (e.g., "krakenhashes.local,kraken.internal"). Seeds the first certificate only — see below.KH_ADDITIONAL_IP_ADDRESSES: Comma-separated additional IP addresses (e.g., "192.168.1.100,10.0.0.50"). Seeds the first certificate only — see below.KH_KEY_SIZE: RSA key size (2048 or 4096, default: 4096)KH_SERVER_CERT_VALIDITY: Server certificate validity in days (default: 365)KH_CA_CERT_VALIDITY: CA certificate validity in days (default: 3650)
The two SAN variables are superseded
KH_ADDITIONAL_DNS_NAMES and KH_ADDITIONAL_IP_ADDRESSES seed the very first certificate and are then imported into Admin → Settings → Server Certificate, which becomes authoritative. Editing the variables after that has no effect, and the backend logs a warning if it finds one still set to a different value. Manage addresses in the UI instead.
Security Considerations¶
- Self-signed certificates are suitable for:
- Development environments
- Internal networks
- Testing and staging
-
Environments where you control all clients
-
For production use, consider:
- Using certificates from a trusted CA (Let's Encrypt, etc.)
- Implementing proper certificate rotation
-
Using the
certbotmode if you have a public domain -
Certificate Storage:
- Private keys are stored with 0600 permissions
- Certificates are stored in the configured certs directory
- Default location:
~/.krakenhashes/certs/or/etc/krakenhashes/certs/in Docker
Regenerating Certificates¶
To add or remove addresses (the normal case)¶
Use Admin → Settings → Server Certificate, edit the address lists, and click Apply & Reissue.
This reissues only the server certificate, signed by the existing certificate authority. Nothing else has to change:
| Backend restart | Not needed — the new certificate is served on the next connection |
| Enrolled agents | Unaffected; their existing ca.crt still validates the new certificate |
| Browsers | Unaffected; the CA they trust has not changed |
| Web UI on port 443 | nginx is reloaded automatically; the result is reported in the UI |
Do not delete the certs directory to add an address
Deleting certs/ regenerates the certificate authority as a side effect. That invalidates every enrolled agent and every browser and operating system that trusted the old CA, to change something that lives only on the server certificate. Use the settings page instead.
To rotate the certificate authority (rare)¶
Only necessary if the CA private key may have been exposed. Use the Rotate CA action under Advanced on the same page; it requires typing a confirmation phrase and takes a timestamped backup of the existing material first.
Afterwards every agent must re-fetch the CA. Agents do this automatically the next time a handshake fails, but any browser or operating system that installed the old CA must install the new ca.crt by hand.
Verifying what the certificate actually covers¶
openssl s_client -connect your-backend:31337 </dev/null 2>/dev/null \
| openssl x509 -noout -text | grep -A1 "Subject Alternative Name"
The backend also logs its coverage at startup, so docker logs answers the same question without openssl.
Certificate Modes¶
KrakenHashes supports three TLS modes:
- self-signed (default): Automatically generates and manages certificates
- provided: Use your own certificates from any CA - Detailed Guide
- certbot: Automated ACME certificate management (Let's Encrypt or custom CA) - Custom ACME Guide
To change modes, set the KH_TLS_MODE environment variable.
Choosing a Mode¶
- Self-Signed: Best for development, testing, and isolated environments
- Provided: Best for commercial CAs, existing certificates, or external certificate management
- Certbot: Best for automated certificate lifecycle with ACME-compatible CAs
Certbot Mode (Automated ACME)¶
This mode provides automated certificate management using the ACME protocol. It supports: - Let's Encrypt (default) - Public CA with 90-day certificates - Custom ACME servers - Internal PKI like Smallstep, HashiCorp Vault, etc.
See the Custom ACME Server Guide for using internal PKI systems.
Let's Encrypt Setup¶
This setup uses Let's Encrypt with Cloudflare DNS-01 challenge, ideal for internal applications that aren't publicly accessible.
Prerequisites¶
- Domain Name: You need to own a domain (e.g.,
zerkersec.io) - Cloudflare Account: Your domain must be managed by Cloudflare
- API Token: Create a Cloudflare API token with proper permissions
Step 1: Create Cloudflare API Token¶
- Log in to your Cloudflare dashboard
- Go to My Profile → API Tokens
- Click Create Token
- Use the Custom token template with these permissions:
- Zone → DNS → Edit
- Zone → Zone → Read (optional but recommended)
- Under Zone Resources, select:
- Include → Specific zone → Your domain (e.g.,
zerkersec.io) - Click Continue to summary and Create Token
- Save the token securely - you won't be able to see it again!
Step 2: DNS Configuration¶
Create an A record for your subdomain:
- In Cloudflare dashboard, go to your domain
- Navigate to DNS → Records
- Add a new A record:
- Type: A
- Name:
kraken(or your chosen subdomain) - IPv4 address: Your internal IP (e.g.,
10.0.0.100) - Proxy status: DNS only (gray cloud)
- TTL: Auto
Note: The IP address doesn't need to be publicly accessible. Certbot only needs to verify domain ownership via DNS TXT records.
Step 3: Configure KrakenHashes¶
Edit your .env file:
# Change TLS mode to certbot
KH_TLS_MODE=certbot
# Certbot Configuration
KH_CERTBOT_DOMAIN=kraken.zerkersec.io # Your full domain
KH_CERTBOT_EMAIL=admin@zerkersec.io # Your email for Let's Encrypt
KH_CERTBOT_STAGING=true # Start with staging for testing!
KH_CERTBOT_AUTO_RENEW=true # Enable automatic renewal
# Cloudflare Configuration
CLOUDFLARE_API_TOKEN=your-token-here # The token from Step 1
# Update frontend URLs to use your domain
REACT_APP_API_URL=https://kraken.zerkersec.io:31337
REACT_APP_WS_URL=wss://kraken.zerkersec.io:31337
# Update CORS to allow your domain
CORS_ALLOWED_ORIGIN=https://kraken.zerkersec.io
Step 4: Initial Setup with Staging¶
Important: Always test with Let's Encrypt staging environment first to avoid rate limits!
-
Stop existing containers:
-
Start with certbot mode:
-
Monitor the logs:
-
Look for messages indicating successful certificate generation:
Step 5: Verify Staging Certificates¶
-
Check certificate files:
-
You should see:
fullchain.pem- Certificate chainprivkey.pem- Private keychain.pem- Intermediate certificates-
cert.pem- Domain certificate -
Test the application (you'll get a browser warning for staging certificates)
Step 6: Switch to Production¶
Once staging certificates work:
-
Update
.env: -
Remove staging certificates:
-
Restart to get production certificates:
Certificate Renewal¶
Certificates are automatically renewed:
- Renewal checks run twice daily (3 AM and 3 PM)
- Certificates renew when less than 30 days remain
- Services reload automatically after renewal
Manual Renewal:
Monitor Renewal:
Certbot Troubleshooting¶
Common Issues¶
- "CLOUDFLARE_API_TOKEN environment variable is required"
- Ensure the token is set in your
.envfile -
Token must have DNS:Edit permissions
-
"Failed to obtain certificates"
- Check Cloudflare API token permissions
- Verify domain ownership
-
Check certbot logs:
docker exec <krakenhashes-container> cat /etc/krakenhashes/certs/logs/letsencrypt.log -
Browser still shows certificate warnings
- Ensure you switched from staging to production
- Clear browser cache
-
Verify certificates:
docker exec <krakenhashes-container> openssl x509 -in /etc/krakenhashes/certs/live/kraken.zerkersec.io/cert.pem -text -noout -
Rate Limits
- Let's Encrypt has rate limits (50 certificates per domain per week)
- Always test with staging first
- See: https://letsencrypt.org/docs/rate-limits/
Certificate Information¶
View certificate details:
# Inside container
docker exec <krakenhashes-container> certbot certificates --config-dir /etc/krakenhashes/certs
# Certificate expiry
docker exec <krakenhashes-container> openssl x509 -enddate -noout -in /etc/krakenhashes/certs/live/kraken.zerkersec.io/cert.pem
Additional Domains¶
To add more domains/subdomains:
-
Add them to
KH_ADDITIONAL_DNS_NAMESin.env: -
Ensure all domains are in Cloudflare and accessible by your API token
-
Restart the container to obtain certificates for all domains
Migration from Self-Signed¶
If migrating from self-signed certificates:
- Back up existing certificates (optional)
- Update
.envas shown above - Restart containers
- Update any clients/browsers that have the old CA certificate cached
Troubleshooting¶
Common Issues and Solutions¶
An agent reports the certificate does not cover its address¶
The agent prints something like:
Cannot verify the KrakenHashes server certificate for 192.168.1.50:31337.
The server's certificate does not list this address.
You are connecting to : 192.168.1.50:31337
The certificate covers: IP:127.0.0.1, DNS:localhost
This is a server-side setting. Renewing this agent's certificates will not fix it.
This is a server-side problem. Deleting the agent's certificates, re-running the claim, or reinstalling the agent will not help — the address is missing from the server's certificate.
Fix it in Admin → Settings → Server Certificate: the address will already be listed under Discovered addresses (the agent reports it over the plain-HTTP bootstrap port, which still works when TLS does not). Add it and click Apply & Reissue. The agent reconnects on its own within 30 seconds; no agent restart is needed.
To confirm what the server currently presents:
openssl s_client -connect your-backend:31337 </dev/null 2>/dev/null \
| openssl x509 -noout -text | grep -A1 "Subject Alternative Name"
Browser Still Shows Certificate Warnings¶
- Certificate not properly installed:
- Verify the certificate is in the correct store (Trusted Root, not Personal or Intermediate)
- Check that you installed the CA certificate, not the server certificate
-
Some browsers cache certificate decisions - try clearing browser data or using incognito mode
-
Browser-specific issues:
- Chrome/Edge: May require restart after certificate installation
- Firefox: Has its own certificate store - you may need to import via Firefox settings
-
Safari: Requires explicit trust settings in Keychain Access
-
Certificate regenerated:
- If the backend regenerated certificates, you need to reinstall the new CA certificate
- Remove the old certificate first to avoid conflicts
ERR_SSL_KEY_USAGE_INCOMPATIBLE (Chrome/Edge)¶
This error indicates the certificate doesn't have the correct key usage flags. The updated certificate generation should prevent this, but if you encounter it:
- Ensure you're running the latest version with the certificate improvements
- Delete existing certificates and let them regenerate
- As a temporary workaround on Windows:
# Create registry key to disable the check (use with caution) New-ItemProperty -Path "HKLM:\SOFTWARE\Policies\Microsoft\Edge" -Name "RSAKeyUsageForLocalAnchorsEnabled" -Value 0 -PropertyType DWORD # For Chrome: New-ItemProperty -Path "HKLM:\SOFTWARE\Policies\Google\Chrome" -Name "RSAKeyUsageForLocalAnchorsEnabled" -Value 0 -PropertyType DWORD
Certificate Not Trusted on Linux¶
-
Check certificate format:
-
Verify installation:
-
SELinux issues (RHEL/Fedora):
Certificate Chain Issues¶
-
Verify the full chain is being sent:
-
Validate certificate chain:
Connection Refused or Timeout¶
-
Check the service is running:
-
Firewall rules:
-
Docker networking (if using Docker):
- Ensure ports are properly mapped in docker-compose.yml
- Check Docker network connectivity
Diagnostic Commands¶
View Certificate Details¶
# View CA certificate details
openssl x509 -in krakenhashes-ca.crt -text -noout
# Check certificate dates
openssl x509 -in krakenhashes-ca.crt -noout -dates
# Check certificate subject and issuer
openssl x509 -in krakenhashes-ca.crt -noout -subject -issuer
Test TLS Connection¶
# Test with curl (verbose)
curl -v https://your-server:31337/health
# Test with openssl
openssl s_client -connect your-server:31337 -CAfile krakenhashes-ca.crt
# Test cipher suites
nmap --script ssl-enum-ciphers -p 31337 your-server
Browser Certificate Debugging¶
- Chrome: Navigate to
chrome://settings/certificatesto manage certificates - Firefox: Navigate to
about:preferences#privacy> View Certificates - Edge: Navigate to
edge://settings/privacy> Manage certificates
Removing Old Certificates¶
If you need to remove old certificates before installing new ones:
Arch Linux:
# Find and remove the certificate
sudo rm -f /etc/ca-certificates/trust-source/anchors/krakenhashes-ca.crt
sudo update-ca-trust
# Or use trust anchor to remove by name
sudo trust anchor --remove "KrakenHashes Root CA"
# Remove from Chrome/Chromium
certutil -d sql:$HOME/.pki/nssdb -D -n "KrakenHashes Root CA"
Debian/Ubuntu:
Fedora/RHEL:
Getting Help¶
If you're still experiencing issues:
-
Check the backend logs for certificate generation errors:
-
Ensure your environment variables are set correctly
- Try regenerating certificates with a clean state
- Report issues at: https://github.com/ZerkerEOD/krakenhashes/issues