---
title: CrowdSec Setup Guide
description: A beginner-friendly guide to setting up CrowdSec with Charon for threat protection.
---

# CrowdSec Setup Guide

Protect your websites from hackers, bots, and other bad actors. This guide walks you through setting up CrowdSec with Charon—even if you've never touched security software before.

---

## What Is CrowdSec?

Imagine a neighborhood watch program, but for the internet. CrowdSec watches the traffic coming to your server and identifies troublemakers—hackers trying to guess passwords, bots scanning for vulnerabilities, or attackers probing your defenses.

When CrowdSec spots suspicious behavior, it blocks that visitor before they can cause harm. Even better, CrowdSec shares information with thousands of other users worldwide. If someone attacks a server in Germany, your server in California can block them before they even knock on your door.

**What CrowdSec Catches:**

- 🔓 **Password guessing** — Someone trying thousands of passwords to break into your apps
- 🕷️ **Malicious bots** — Automated scripts looking for security holes
- 💥 **Known attackers** — IP addresses flagged as dangerous by the global community
- 🔍 **Reconnaissance** — Hackers mapping out your server before attacking

---

## How Charon Makes It Easy

Here's the good news: **Charon handles most of the CrowdSec setup automatically**. You don't need to edit configuration files, run terminal commands, or understand networking. Just flip a switch in the Settings.

### What Happens Behind the Scenes

When you enable CrowdSec in Charon:

1. **Charon starts the CrowdSec engine** — A security service begins running inside your container
2. **A "bouncer" is registered** — This allows Charon to communicate with CrowdSec (more on this below)
3. **Your websites are protected** — Bad traffic gets blocked before reaching your apps
4. **Decisions sync in real-time** — You can see who's blocked in the Security dashboard

All of this happens in about 15 seconds after you flip the toggle.

---

## Quick Start: Enable CrowdSec

**Prerequisites:**

- Charon is installed and running
- You can access the Charon web interface

**Steps:**

1. Open Charon in your browser (usually `http://your-server:8080`)
2. Click **Security** in the left sidebar
3. Find the **CrowdSec** card
4. Flip the toggle to **ON**
5. Wait about 15 seconds for the status to show "Active"

That's it! Your server is now protected by CrowdSec.

> **✨ New in Recent Versions**
>
> Charon now **automatically generates and registers** your bouncer key the first time you enable CrowdSec. No terminal commands needed—just flip the switch and you're protected!

### Verify It's Working

After enabling, the CrowdSec card should display:

- **Status:** Active (with a green indicator)
- **PID:** A number like `12345` (this is the CrowdSec process)
- **LAPI:** Connected

If you see these, CrowdSec is running properly.

---

## Understanding "Bouncers" (Important!)

A **bouncer** is like a security guard at a nightclub door. It checks each visitor's ID against a list of banned people and either lets them in or turns them away.

In CrowdSec terms:

- The **CrowdSec engine** decides who's dangerous and maintains the ban list
- The **bouncer** enforces those decisions by blocking bad traffic

**Critical Point:** For the bouncer to work, it needs a special password (called an **API key**) to communicate with the CrowdSec engine. This key must be **generated by CrowdSec itself**—you cannot make one up.

> **✅ Good News: Charon Handles This For You!**
>
> When you enable CrowdSec for the first time, Charon automatically:
> 1. Starts the CrowdSec engine
> 2. Registers a bouncer and generates a valid API key
> 3. Saves the key so it survives container restarts
>
> You don't need to touch the terminal or set any environment variables.

> **⚠️ Common Mistake Alert**
>
> If you set `CHARON_SECURITY_CROWDSEC_API_KEY=mySecureKey123` in your docker-compose.yml, **it won't work**. CrowdSec has never heard of "mySecureKey123" and will reject it.
>
> **Solution:** Remove any manually-set API key and let Charon generate one automatically.

---

## How Auto-Registration Works

When you flip the CrowdSec toggle ON, here's what happens behind the scenes:

1. **Charon starts CrowdSec** and waits for it to be ready
2. **A bouncer is registered** with the name `caddy-bouncer`
3. **The API key is saved** to `/app/data/crowdsec/bouncer_key`
4. **Caddy connects** using the saved key

### Your Key Is Saved Forever

The bouncer key is stored in your data volume at:

```
/app/data/crowdsec/bouncer_key
```

This means:

- ✅ Your key survives container restarts
- ✅ Your key survives Charon updates
- ✅ You don't need to re-register after pulling a new image

### Finding Your Key in the Logs

When Charon generates a new bouncer key, you'll see a formatted banner in the container logs:

```bash
docker logs charon
```

Look for a section like this:

```
╔══════════════════════════════════════════════════════════════╗
║              🔑 CrowdSec Bouncer Registered!                ║
╠══════════════════════════════════════════════════════════════╣
║  Your bouncer API key has been auto-generated.               ║
║  Key saved to: /app/data/crowdsec/bouncer_key                ║
╚══════════════════════════════════════════════════════════════╝
```

### Providing Your Own Key (Advanced)

If you prefer to use your own pre-registered bouncer key, you still can! Environment variables take priority over auto-generated keys:

```yaml
environment:
  - CHARON_SECURITY_CROWDSEC_API_KEY=your-pre-registered-key
```

> **⚠️ Important:** This key must be registered with CrowdSec first using `cscli bouncers add`. See [Manual Bouncer Registration](#manual-bouncer-registration) for details.

---

## Viewing Your Bouncer Key in the UI

Need to see your bouncer key? Charon makes it easy:

1. Open Charon and go to **Security**
2. Look at the **CrowdSec** card
3. Your bouncer key is displayed (masked for security)
4. Click the **copy button** to copy the full key to your clipboard

This is useful when:

- 🔧 Troubleshooting connection issues
- 📋 Sharing the key with another application
- ✅ Verifying the correct key is in use

---

## Environment Variables Reference

Here's everything you can configure for CrowdSec. For most users, **you don't need to set any of these**—Charon's defaults work great.

### Safe to Set

| Variable | Description | Default | When to Use |
|----------|-------------|---------|-------------|
| `CHARON_SECURITY_CROWDSEC_CONSOLE_KEY` | Your CrowdSec Console enrollment token | None | When enrolling in CrowdSec Console (optional) |

### Do NOT Set Manually

| Variable | Description | Why You Should NOT Set It |
|----------|-------------|--------------------------|
| `CHARON_SECURITY_CROWDSEC_API_KEY` | Bouncer authentication key | Must be generated by CrowdSec, not invented |
| `CHARON_SECURITY_CROWDSEC_API_URL` | LAPI address | Uses correct default (port 8085 internally) |
| `CHARON_SECURITY_CROWDSEC_MODE` | Enable/disable mode | Use GUI toggle instead |

### Correct Docker Compose Example

```yaml
services:
  charon:
    image: ghcr.io/wikid82/charon:latest
    container_name: charon
    restart: unless-stopped
    ports:
      - "8080:8080"   # Charon web interface
      - "80:80"       # HTTP traffic
      - "443:443"     # HTTPS traffic
    volumes:
      - ./data:/app/data
      - /var/run/docker.sock:/var/run/docker.sock:ro
    environment:
      - CHARON_ENV=production
      # ✅ CrowdSec is enabled via the GUI, no env vars needed
      # ✅ API key is auto-generated, never set manually
```

---

## Manual Bouncer Registration

In rare cases, you might need to register the bouncer manually. This is useful if:

- You're recovering from a broken configuration
- Automatic registration failed
- You're debugging connection issues

### Step 1: Access the Container Terminal

```bash
docker exec -it charon bash
```

### Step 2: Register the Bouncer

```bash
cscli bouncers add caddy-bouncer
```

CrowdSec will output an API key. It looks something like this:

```
Api key for 'caddy-bouncer':

   f8a7b2c9d3e4a5b6c7d8e9f0a1b2c3d4

Please keep it safe, you won't be able to retrieve it!
```

### Step 3: Verify Registration

```bash
cscli bouncers list
```

You should see `caddy-bouncer` in the list.

### Step 4: Restart Charon

Exit the container and restart:

```bash
exit
docker restart charon
```

### Step 5: Re-enable CrowdSec

Toggle CrowdSec OFF and then ON again in the Security dashboard. Charon will detect the registered bouncer and connect.

---

## CrowdSec Console Enrollment (Optional)

The CrowdSec Console is a free online dashboard where you can:

- 📊 View attack statistics across all your servers
- 🌍 See threats on a world map
- 🔔 Get email alerts about attacks
- 📡 Subscribe to premium blocklists

### Getting Your Enrollment Key

1. Go to [app.crowdsec.net](https://app.crowdsec.net) and create a free account
2. Click **Engines** in the sidebar
3. Click **Add Engine**
4. Copy the enrollment key (a long string starting with `clapi-`)

### Enrolling Through Charon

1. Open Charon and go to **Security**
2. Click on the **CrowdSec** card to expand options
3. Find **Console Enrollment**
4. Paste your enrollment key
5. Click **Enroll**

Within 60 seconds, your instance should appear in the CrowdSec Console.

### Enrollment via Command Line

If the GUI enrollment isn't working:

```bash
docker exec -it charon cscli console enroll YOUR_ENROLLMENT_KEY
```

Replace `YOUR_ENROLLMENT_KEY` with the key from your Console.

---

## Troubleshooting

### "Access Forbidden" Error

**Symptom:** Logs show "API error: access forbidden" when CrowdSec tries to connect.

**Cause:** The bouncer API key is invalid or was never registered with CrowdSec.

**Solution:**

1. Check if you're manually setting an API key:
   ```bash
   grep -i "crowdsec_api_key" docker-compose.yml
   ```

2. If you find one, **remove it**:
   ```yaml
   # REMOVE this line:
   - CHARON_SECURITY_CROWDSEC_API_KEY=anything
   ```

3. Follow the [Manual Bouncer Registration](#manual-bouncer-registration) steps above

4. Restart the container:
   ```bash
   docker restart charon
   ```

---

### "Connection Refused" to LAPI

**Symptom:** CrowdSec shows "connection refused" errors.

**Cause:** CrowdSec is still starting up (takes 30-60 seconds) or isn't running.

**Solution:**

1. Wait 60 seconds after container start

2. Check if CrowdSec is running:
   ```bash
   docker exec charon cscli lapi status
   ```

3. If you see "connection refused," try toggling CrowdSec OFF then ON in the GUI

4. Check the logs:
   ```bash
   docker logs charon | grep -i crowdsec
   ```

---

### Bouncer Status Check

To see all registered bouncers:

```bash
docker exec charon cscli bouncers list
```

You should see `caddy-bouncer` with a "validated" status.

---

### How to Delete and Re-Register a Bouncer

If the bouncer is corrupted or misconfigured:

```bash
# Delete the existing bouncer
docker exec charon cscli bouncers delete caddy-bouncer

# Register a fresh one
docker exec charon cscli bouncers add caddy-bouncer

# Restart
docker restart charon
```

---

### Console Shows Engine "Offline"

**Symptom:** CrowdSec Console dashboard shows your engine as "Offline" even though it's running.

**Cause:** Network issues preventing heartbeats from reaching CrowdSec servers.

**Check connectivity:**

```bash
# Test DNS
docker exec charon nslookup api.crowdsec.net

# Test HTTPS connection
docker exec charon curl -I https://api.crowdsec.net
```

**Required outbound connections:**

| Host | Port | Purpose |
|------|------|---------|
| `api.crowdsec.net` | 443 | Console heartbeats |
| `hub.crowdsec.net` | 443 | Security preset downloads |

If you're behind a corporate firewall, you may need to allow these connections.

---

## Advanced Configuration

### Using an External CrowdSec Instance

If you already run CrowdSec separately (not inside Charon), you can connect to it.

> **⚠️ Warning:** This is an advanced configuration. Most users should use Charon's built-in CrowdSec.

> **📝 Note: Auto-Registration Doesn't Apply Here**
>
> The auto-registration feature only works with Charon's **built-in** CrowdSec. When connecting to an external CrowdSec instance, you **must** manually register a bouncer and provide the key.

**Steps:**

1. Register a bouncer on your external CrowdSec:
   ```bash
   cscli bouncers add charon-bouncer
   ```

2. Save the API key that's generated (you won't see it again!)

3. In your docker-compose.yml:
   ```yaml
   environment:
     - CHARON_SECURITY_CROWDSEC_API_URL=http://your-crowdsec-server:8080
     - CHARON_SECURITY_CROWDSEC_API_KEY=your-generated-key
   ```

4. Restart Charon:
   ```bash
   docker restart charon
   ```

**Why manual registration is required:**

Charon cannot automatically register a bouncer on an external CrowdSec instance because:

- It doesn't have terminal access to the external server
- It doesn't know the external CrowdSec's admin credentials
- The external CrowdSec may have custom security policies

---

### Installing Security Presets

CrowdSec offers pre-built detection rules called "presets" from their Hub. Charon includes common ones by default, but you can add more:

1. Go to **Security → CrowdSec → Hub Presets**
2. Browse or search for presets
3. Click **Install** on the ones you want

Popular presets:

- **crowdsecurity/http-probing** — Detect reconnaissance scanning
- **crowdsecurity/http-bad-user-agent** — Block known malicious bots
- **crowdsecurity/http-cve** — Protect against known vulnerabilities

---

### Viewing Active Blocks (Decisions)

To see who's currently blocked:

**In the GUI:**

1. Go to **Security → Live Decisions**
2. View blocked IPs, reasons, and duration

**Via Command Line:**

```bash
docker exec charon cscli decisions list
```

---

### Manually Banning an IP

If you want to block someone immediately:

**GUI:**

1. Go to **Security → CrowdSec**
2. Click **Add Decision**
3. Enter the IP address
4. Set duration (e.g., 24h)
5. Click **Ban**

**Command Line:**

```bash
docker exec charon cscli decisions add --ip 1.2.3.4 --duration 24h --reason "Manual ban"
```

---

### Unbanning an IP

If you accidentally blocked a legitimate user:

```bash
docker exec charon cscli decisions delete --ip 1.2.3.4
```

---

## Summary

| Task | Method |
|------|--------|
| Enable CrowdSec | Toggle in Security dashboard |
| Verify it's running | Check for "Active" status in dashboard |
| Fix "access forbidden" | Remove hardcoded API key, let Charon generate one |
| Register bouncer manually | `docker exec charon cscli bouncers add caddy-bouncer` |
| Enroll in Console | Paste key in Security → CrowdSec → Console Enrollment |
| View who's blocked | Security → Live Decisions |

---

## Related Guides

- [Web Application Firewall (WAF)](../features/waf.md) — Additional application-layer protection
- [Access Control Lists](../features/access-control.md) — Manual IP blocking and GeoIP rules
- [Rate Limiting](../features/rate-limiting.md) — Prevent abuse by limiting request rates
- [CrowdSec Feature Documentation](../features/crowdsec.md) — Detailed feature reference

---

## Need Help?

- 📖 [Full Documentation](../index.md)
- 🐛 [Report an Issue](https://github.com/Wikid82/Charon/issues)
- 💬 [Community Discussions](https://github.com/Wikid82/Charon/discussions)
