- Updated Definition of Done report with detailed checks and results for backend and frontend tests. - Documented issues related to race conditions and test failures in QA reports. - Improved security scan notes and code cleanup status in QA reports. - Added summaries for rate limit integration test fixes, including root causes and resolutions. - Introduced new debug and integration scripts for rate limit testing. - Updated security documentation to reflect changes in configuration and troubleshooting steps. - Enhanced troubleshooting guides for CrowdSec and Go language server (gopls) errors. - Improved frontend and scripts README files for clarity and usage instructions.
15 KiB
Security Features
Charon includes Cerberus, a security system that protects your websites. It's enabled by default so your sites are protected from the start.
You can disable it in System Settings → Optional Features if you don't need it, or configure it using this guide. The sidebar now shows Cerberus → Dashboard; the page header reads Cerberus Dashboard.
Want the quick reference? See https://wikid82.github.io/charon/security.
What Is Cerberus?
Think of Cerberus as a guard dog for your websites. It has three heads (in Greek mythology), and each head watches for different threats:
- CrowdSec — Blocks bad IP addresses
- WAF (Web Application Firewall) — Blocks bad requests
- Access Lists — You decide who gets in
Turn It On (The Safe Way)
Step 1: Start in "Monitor" Mode
This means Cerberus watches but doesn't block anyone yet.
Add this to your docker-compose.yml:
environment:
- CERBERUS_SECURITY_WAF_MODE=monitor
- CERBERUS_SECURITY_CROWDSEC_MODE=local
Restart Charon:
docker-compose restart
Step 2: Watch the Logs
Check "Security" in the sidebar. You'll see what would have been blocked. If it looks right, move to Step 3.
Step 3: Turn On Blocking
Change monitor to block:
environment:
- CERBERUS_SECURITY_WAF_MODE=block
Restart again. Now bad guys actually get blocked.
CrowdSec (Block Bad IPs)
What it does: Thousands of people share information about attackers. When someone tries to hack one of them, everyone else blocks that attacker too.
Why you care: If someone is attacking servers in France, you block them before they even get to your server in California.
How to Enable It
- Web UI: The Cerberus Dashboard shows a single Start/Stop toggle. Use it to run or stop CrowdSec; there is no separate mode selector.
- Configuration page: Uses a simple Disabled / Local toggle (no Mode dropdown). Choose Local to run the embedded CrowdSec agent.
- Environment variables (optional):
environment:
- CERBERUS_SECURITY_CROWDSEC_MODE=local
That's it. CrowdSec starts automatically and begins blocking bad IPs.
What you'll see: The Cerberus pages show blocked IPs and why they were blocked.
Enroll with CrowdSec Console (optional)
- Enable the feature flag
crowdsec_console_enrollment(off by default) so the Console enrollment button appears in Cerberus → CrowdSec. - Click Enroll with CrowdSec Console and follow the on-screen prompt to generate or paste the Console enrollment key. The flow requests only the minimal scope needed for the embedded agent.
- Charon stores the enrollment secret internally (not logged or echoed) and completes the handshake without requiring sudo or shell access.
- After enrollment, the Console status shows in the CrowdSec card; you can revoke from either side if needed.
Hub Presets (Configuration Packages)
Charon lets you install security configurations (Collections, Parsers, Scenarios) directly from the CrowdSec Hub.
- Search & Sort: Use the search bar to find specific packages (e.g., "wordpress", "nginx"). Sort by name, status, or popularity.
- One-Click Install: Click "Install" on any package. Charon handles the download and configuration.
- Safe Apply: Changes are applied safely. If something goes wrong, Charon can restore the previous configuration.
- Updates: Charon checks for updates automatically. You'll see an "Update" button when a new version is available.
Troubleshooting
Having trouble with CrowdSec? Check out the CrowdSec Troubleshooting Guide.
WAF (Block Bad Behavior)
What it does: Looks at every request and checks if it's trying to do something nasty—like inject SQL code or run JavaScript attacks.
Why you care: Even if your app has a bug, the WAF might catch the attack first.
How to Enable It
environment:
- CERBERUS_SECURITY_WAF_MODE=block
Start with monitor first! This lets you see what would be blocked without actually blocking it.
Access Lists (You Decide Who Gets In)
Access lists let you block or allow specific countries, IP addresses, or networks.
Example 1: Block a Country
Scenario: You only need access from the US, so block everyone else.
- Go to Access Lists
- Click Add List
- Name it "US Only"
- Type: Geo Whitelist
- Countries: United States
- Assign to your proxy host
Now only US visitors can access that website. Everyone else sees "Access Denied."
Example 2: Private Network Only
Scenario: Your admin panel should only work from your home network.
- Create an access list
- Type: Local Network Only
- Assign it to your admin panel proxy
Now only devices on 192.168.x.x or 10.x.x.x can access it. The public internet can't.
Example 3: Block One Country
Scenario: You're getting attacked from one specific country.
- Create a list
- Type: Geo Blacklist
- Pick the country
- Assign to the targeted website
Certificate Management Security
What it protects: Certificate deletion is a destructive operation that requires proper authorization.
How it works:
- Certificates cannot be deleted while in use by proxy hosts (conflict error)
- Automatic backup is created before any certificate deletion
- Authentication required (when auth is implemented)
Backup & Recovery:
- Every certificate deletion triggers an automatic backup
- Find backups in the "Backups" page
- Restore from backup if you accidentally delete the wrong certificate
Best Practice:
- Review which proxy hosts use a certificate before deleting it
- When deleting proxy hosts, use the cleanup prompt to delete orphaned certificates
- Keep custom certificates you might reuse later
Don't Lock Yourself Out
Problem: If you turn on security and misconfigure it, you might block yourself.
Solution: Add your IP to the "Admin Whitelist" first.
How to Add Your IP
- Go to Settings → Security
- Find "Admin Whitelist"
- Add your IP address (find it at ifconfig.me)
- Save
Now you can never accidentally block yourself.
Break-Glass Token (Emergency Exit)
If you do lock yourself out:
- Log into your server directly (SSH)
- Run this command:
docker exec charon charon break-glass
It generates a one-time token that lets you disable security and get back in.
Recommended Settings by Service Type
Internal Admin Panels (Router, Pi-hole, etc.)
Access List: Local Network Only
Blocks all public internet traffic.
Personal Blog or Portfolio
No access list
WAF: Enabled
CrowdSec: Enabled
Keep it open for visitors, but protect against attacks.
Password Manager (Vaultwarden, etc.)
Access List: IP Whitelist (your home IP)
Or: Geo Whitelist (your country only)
Most restrictive. Only you can access it.
Media Server (Plex, Jellyfin)
Access List: Geo Blacklist (high-risk countries)
CrowdSec: Enabled
Allows friends to access, blocks obvious threat countries.
Check If It's Working
- Go to Security → Decisions in the sidebar
- You'll see a list of recent blocks
- If you see activity, it's working!
Live Security Monitoring
Live Log Viewer
What it does: Stream security events in real-time directly in the Cerberus Dashboard.
Where to find it: Cerberus → Dashboard → Scroll to "Live Activity" section
What you'll see:
- Real-time WAF blocks and detections
- CrowdSec decisions as they happen
- ACL denials (geo-blocking, IP filtering)
- Rate limiting events
- All Cerberus security activity
Controls:
- Pause — Stop the stream to examine specific events
- Clear — Remove old entries from the display
- Auto-scroll — Automatically follow new events
- Filter — Search logs by text, level, or source
How to use it:
- Open Cerberus Dashboard
- Scroll to the Live Activity section
- Watch events appear in real-time
- Click "Pause" to stop streaming and review events
- Use the filter box to search for specific IPs, rules, or messages
- Click "Clear" to remove old entries
Technical details:
- Uses WebSocket for real-time streaming (no polling)
- Keeps last 500 entries by default (configurable)
- Server-side filtering reduces bandwidth
- Automatic reconnection on disconnect
Security Notifications
What it does: Sends alerts when critical security events occur.
Why you care: Get immediate notification of attacks or suspicious activity without watching the dashboard 24/7.
Configure Notifications
- Go to Cerberus Dashboard
- Click "Notification Settings" button (top-right)
- Configure your preferences:
Basic Settings:
- Enable Notifications — Master toggle
- Minimum Log Level — Choose: debug, info, warn, or error
error— Only critical events (recommended)warn— Important warnings and errorsinfo— Normal operations plus warnings/errorsdebug— Everything (very noisy, not recommended)
Event Types:
- WAF Blocks — Notify when firewall blocks an attack
- ACL Denials — Notify when access control rules block requests
- Rate Limit Hits — Notify when traffic thresholds are exceeded
Delivery Methods:
- Webhook URL — Send to Discord, Slack, or custom integrations
- Email Recipients — Comma-separated email addresses (requires SMTP setup)
Webhook Integration
Security considerations:
- Use HTTPS webhooks only — Never send security alerts over unencrypted HTTP
- Validate webhook endpoints — Ensure the URL is correct before saving
- Protect webhook secrets — If your webhook requires authentication, use environment variables
- Rate limiting — Charon does NOT rate-limit webhook calls; configure your webhook provider to handle bursts
- Sensitive data — Webhook payloads may contain IP addresses, request URIs, and user agents
Supported platforms:
- Discord (use webhook URL from Server Settings → Integrations)
- Slack (create incoming webhook in Slack Apps)
- Microsoft Teams (use incoming webhook connector)
- Custom HTTPS endpoints (any server that accepts POST requests)
Webhook payload example:
{
"event_type": "waf_block",
"severity": "error",
"timestamp": "2025-12-09T10:30:45Z",
"message": "WAF blocked SQL injection attempt",
"details": {
"ip": "203.0.113.42",
"rule_id": "942100",
"request_uri": "/api/users?id=1' OR '1'='1",
"user_agent": "curl/7.68.0"
}
}
Discord webhook format:
Charon automatically formats notifications for Discord:
{
"embeds": [{
"title": "🛡️ WAF Block",
"description": "SQL injection attempt blocked",
"color": 15158332,
"fields": [
{ "name": "IP Address", "value": "203.0.113.42", "inline": true },
{ "name": "Rule", "value": "942100", "inline": true },
{ "name": "URI", "value": "/api/users?id=1' OR '1'='1" }
],
"timestamp": "2025-12-09T10:30:45Z"
}]
}
Testing your webhook:
- Add your webhook URL in Notification Settings
- Save the settings
- Trigger a test event (try accessing a blocked URL)
- Check your Discord/Slack channel for the notification
Troubleshooting webhooks:
- No notifications? Check webhook URL is correct and HTTPS
- Wrong format? Verify your platform's webhook documentation
- Too many notifications? Increase minimum log level to "error" only
- Notifications delayed? Check your network connection and firewall rules
Log Privacy Considerations
What's logged:
- IP addresses of blocked requests
- Request URIs and query parameters
- User-Agent strings
- Rule IDs that triggered blocks
- Timestamps of security events
What's NOT logged:
- Request bodies (POST data)
- Authentication credentials
- Session cookies
- Response bodies
Privacy best practices:
- Filter logs before sharing — Remove sensitive IPs or URIs before sharing logs externally
- Secure webhook endpoints — Use HTTPS and authenticate webhook requests
- Respect GDPR — IP addresses are personal data in some jurisdictions
- Retention policy — Live logs are kept for the current session only (not persisted to disk)
- Access control — Only authenticated users can access live logs (when auth is implemented)
Compliance notes:
- Live log streaming does NOT persist logs to disk
- Logs are only stored in memory during active WebSocket sessions
- Notification webhooks send log data to third parties (Discord, Slack)
- Email notifications may contain sensitive data
Turn It Off
If security is causing problems:
Option 1: Via Web UI
- Go to Settings → Security
- Toggle "Enable Cerberus" off
Option 2: Via Environment Variable
Remove the security lines from docker-compose.yml and restart.
Common Questions
"Will this slow down my websites?"
No. The checks happen in milliseconds. Humans won't notice.
"Can I whitelist specific paths?"
Not yet, but it's planned. For now, access lists apply to entire websites.
"What if CrowdSec blocks a legitimate visitor?"
You can manually unblock IPs in the Security → Decisions page.
"Do I need all three security features?"
No. Use what you need:
- Just starting? CrowdSec only
- Public service? CrowdSec + WAF
- Private service? Access Lists only
Zero-Day Protection
What We Protect Against
Web Application Exploits:
- ✅ SQL Injection (SQLi) — even zero-days using SQL syntax
- ✅ Cross-Site Scripting (XSS) — new XSS vectors caught by pattern matching
- ✅ Remote Code Execution (RCE) — command injection patterns
- ✅ Path Traversal — attempts to read system files
- ⚠️ CrowdSec — protects hours/days after first exploitation (crowd-sourced)
How It Works
The WAF (Coraza) uses the OWASP Core Rule Set to detect attack patterns. Even if the exploit is brand new, the pattern is usually recognizable.
Example: A zero-day SQLi exploit discovered today:
https://yourapp.com/search?q=' OR '1'='1
- Pattern:
' OR '1'='1matches SQL injection signature - Action: WAF blocks request → attacker never reaches your database
What We DON'T Protect Against
- ❌ Zero-days in Charon itself (keep Charon updated)
- ❌ Zero-days in Docker, Linux kernel (keep OS updated)
- ❌ Logic bugs in your application code (need code reviews)
- ❌ Insider threats (need access controls + auditing)
- ❌ Social engineering (need user training)
Recommendation: Defense in Depth
-
Enable all Cerberus layers:
- CrowdSec (IP reputation)
- ACLs (restrict access by geography/IP)
- WAF (request inspection)
- Rate Limiting (slow down attacks)
-
Keep everything updated:
- Charon (watch GitHub releases)
- Docker images (rebuild regularly)
- Host OS (enable unattended-upgrades)
-
Monitor security logs:
- Check "Security → Decisions" weekly
- Set up alerts for high block rates
More Technical Details
Want the nitty-gritty? See Cerberus Technical Docs.