chore: git cache cleanup

This commit is contained in:
GitHub Actions
2026-03-04 18:34:49 +00:00
parent c32cce2a88
commit 27c252600a
2001 changed files with 683185 additions and 0 deletions

View File

@@ -0,0 +1,366 @@
# CrowdSec Traffic Blocking - Final Validation Report
**Date:** December 15, 2025
**Agent:** QA_Security
**Environment:** Docker container `charon:local`
---
## ❌ VERDICT: FAIL
**Traffic blocking is NOT functional end-to-end.**
---
## Test Results Summary
| Component | Status | Details |
|-----------|--------|---------|
| CrowdSec Process | ✅ RUNNING | PID 324, started manually |
| LAPI Health | ✅ HEALTHY | Accessible at <http://127.0.0.1:8085> |
| Bouncer Registration | ✅ REGISTERED | `caddy-bouncer` active, last pull at 20:06:01Z |
| Bouncer API Connectivity | ✅ CONNECTED | Bouncer successfully querying LAPI |
| CrowdSec App Config | ✅ CONFIGURED | API key set, ticker_interval: 10s |
| Decision Creation | ✅ SUCCESS | Test IP 203.0.113.99 banned for 15m |
| **BLOCKING TEST** | ❌ **FAIL** | **Banned IP returned HTTP 200 instead of 403** |
| Normal Traffic | ✅ PASS | Non-banned traffic returns 200 OK |
| Pre-commit | ✅ PASS | All checks passed, 85.1% coverage |
---
## Critical Issue: HTTP Handler Middleware Not Applied
### Problem
While the CrowdSec bouncer is successfully:
- Running and connected to LAPI
- Fetching decisions from LAPI
- Registered with valid API key
The **Caddy HTTP handler middleware is not applied to routes**, so blocking decisions are not enforced on incoming traffic.
### Evidence
#### 1. CrowdSec LAPI Running and Healthy
```bash
$ docker exec charon ps aux | grep crowdsec
324 root 0:01 /usr/local/bin/crowdsec -c /app/data/crowdsec/config/config.yaml
$ docker exec charon sh -c 'cd /app/data/crowdsec && /usr/local/bin/cscli lapi status'
Trying to authenticate with username "844aa6ea34104e829b80a8b9f459b4d9QqsifNBhWtcwmq1s" on http://127.0.0.1:8085/
You can successfully interact with Local API (LAPI)
```
#### 2. Bouncer Registered and Active
```bash
$ docker exec charon sh -c 'cd /app/data/crowdsec && /usr/local/bin/cscli bouncers list'
---------------------------------------------------------------------------------------------
Name IP Address Valid Last API pull Type Version Auth Type
---------------------------------------------------------------------------------------------
caddy-bouncer 127.0.0.1 ✔️ 2025-12-15T20:06:01Z caddy-cs-bouncer v0.9.2 api-key
---------------------------------------------------------------------------------------------
```
#### 3. Decision Created Successfully
```bash
$ docker exec charon sh -c 'cd /app/data/crowdsec && /usr/local/bin/cscli decisions add --ip 203.0.113.99 --duration 15m --reason "FINAL QA VALIDATION TEST"'
level=info msg="Decision successfully added"
$ docker exec charon sh -c 'cd /app/data/crowdsec && /usr/local/bin/cscli decisions list' | grep 203.0.113.99
| 1 | cscli | Ip:203.0.113.99 | FINAL QA VALIDATION TEST | ban | | | 1 | 14m54s | 1 |
```
#### 4. ❌ BLOCKING TEST FAILED - Traffic NOT Blocked
```bash
$ curl -H "X-Forwarded-For: 203.0.113.99" http://localhost:8080/ -v
> GET / HTTP/1.1
> Host: localhost:8080
> User-Agent: curl/8.5.0
> Accept: */*
> X-Forwarded-For: 203.0.113.99
>
< HTTP/1.1 200 OK
< Accept-Ranges: bytes
< Content-Length: 687
< Content-Type: text/html; charset=utf-8
< Last-Modified: Mon, 15 Dec 2025 17:46:43 GMT
< Date: Mon, 15 Dec 2025 20:05:59 GMT
```
**Expected:** HTTP 403 Forbidden
**Actual:** HTTP 200 OK
**Result:** ❌ FAIL
#### 5. Caddy HTTP Routes Missing CrowdSec Handler
```bash
$ docker exec charon curl -s http://localhost:2019/config/apps/http/servers | jq '.[].routes[0].handle'
[
{
"handler": "rewrite",
"uri": "/unknown.html"
},
{
"handler": "file_server",
"root": "/app/frontend/dist"
}
]
```
**No `crowdsec` handler present in the middleware chain.**
#### 6. CrowdSec Headers
No `X-Crowdsec-*` headers were present in the response, confirming the middleware is not processing requests.
---
## Root Cause Analysis
### Configuration Gap
1. **CrowdSec App Level**: ✅ Configured with API key and URL
2. **HTTP Handler Level**: ❌ **NOT configured** - Missing from route middleware chain
The Caddy server has the CrowdSec bouncer module loaded:
```bash
$ docker exec charon caddy list-modules | grep crowdsec
admin.api.crowdsec
crowdsec
http.handlers.crowdsec
layer4.matchers.crowdsec
```
But the `http.handlers.crowdsec` is not applied to any routes in the current configuration.
### Why This Happened
Looking at the application logs:
```
{"bin_path":"/usr/local/bin/crowdsec","data_dir":"/app/data/crowdsec","level":"info","msg":"CrowdSec reconciliation: starting startup check","time":"2025-12-15T19:59:33Z"}
{"db_mode":"disabled","level":"info","msg":"CrowdSec reconciliation skipped: both SecurityConfig and Settings indicate disabled","setting_enabled":false,"time":"2025-12-15T19:59:33Z"}
```
And later:
```
Initializing CrowdSec configuration...
CrowdSec configuration initialized. Agent lifecycle is GUI-controlled.
```
**The system initialized CrowdSec configuration but did NOT auto-start it or configure Caddy routes because:**
- The reconciliation logic checked both `SecurityConfig` and `Settings` tables
- Even though I manually set `crowd_sec_mode='local'` and `enabled=1` in the database, the startup check at 19:59:33 found them disabled
- The system then initialized configs but left "Agent lifecycle GUI-controlled"
- Manual start of CrowdSec LAPI succeeded, but Caddy route configuration was never updated
---
## What Works
**CrowdSec Core Components:**
- LAPI running and healthy
- Bouncer registered and polling decisions
- Decision management (add/delete/list) working
- `cscli` commands functional
- Database integration working
- Configuration files properly structured
**Infrastructure:**
- Backend tests: 100% pass
- Code coverage: 85.1% (meets 85% requirement)
- Pre-commit hooks: All passed
- Container build: Successful
- Caddy admin API: Accessible and responsive
---
## What Doesn't Work
**Traffic Enforcement:**
- HTTP requests from banned IPs are not blocked
- CrowdSec middleware not in Caddy route handler chain
- No automatic configuration of Caddy routes when CrowdSec is enabled
**Auto-Start Logic:**
- CrowdSec does not auto-start when database is configured to `mode=local, enabled=true`
- Reconciliation logic may have race condition or query timing issue
- Manual intervention required to start LAPI process
---
## Production Readiness: NO
### Blockers
1. **Critical:** Traffic blocking does not work - primary security feature non-functional
2. **High:** Auto-start logic unreliable - requires manual intervention
3. **High:** Caddy route configuration not synchronized with CrowdSec state
### Required Fixes
#### 1. Fix Caddy Route Configuration (CRITICAL)
**File:** `backend/internal/caddy/manager.go` or similar Caddy config generator
**Action Required:**
When CrowdSec is enabled, the Caddy configuration builder must inject the `crowdsec` HTTP handler into the route middleware chain BEFORE other handlers.
**Expected Structure:**
```json
{
"handle": [
{
"handler": "crowdsec",
"trusted_proxies_raw": ["10.0.0.0/8", "172.16.0.0/12", "192.168.0.0/16", "127.0.0.1/32", "::1/128"]
},
{
"handler": "rewrite",
"uri": "/unknown.html"
},
{
"handler": "file_server",
"root": "/app/frontend/dist"
}
]
}
```
The `trusted_proxies_raw` field must be set at the HTTP handler level (not app level).
#### 2. Fix Auto-Start Logic (HIGH)
**File:** `backend/internal/services/crowdsec_startup.go`
**Issues:**
- Line 110-117: The check `if cfg.CrowdSecMode != "local" && !crowdSecEnabled` is skipping startup even when database shows enabled
- Possible issue: `db.First(&cfg)` not finding the manually-created record
- Consider: The `Name` field mismatch (code expects "Default Security Config", DB has "default")
**Recommended Fix:**
```go
// At line 43, ensure proper fallback:
if err := db.First(&cfg).Error; err != nil {
if err == gorm.ErrRecordNotFound {
// Try finding by uuid='default' as fallback
if err := db.Where("uuid = ?", "default").First(&cfg).Error; err != nil {
// Then proceed with auto-initialization logic
// ...
}
}
}
```
#### 3. Add Integration Test for End-to-End Blocking
**File:** `scripts/crowdsec_blocking_integration.sh` (new)
**Test Steps:**
1. Enable CrowdSec in DB
2. Restart container
3. Verify LAPI running
4. Verify bouncer registered
5. Add ban decision
6. **Test traffic with banned IP → Assert 403**
7. Test normal traffic → Assert 200
8. Cleanup
This test must be added to CI/CD and must FAIL if traffic is not blocked.
---
## Recommendation
### **DO NOT DEPLOY**
The CrowdSec feature is **non-functional for its primary purpose: blocking traffic**. While all the supporting infrastructure works correctly (LAPI, bouncer registration, decision management), the absence of HTTP middleware enforcement makes this a **critical security feature gap**.
### Next Steps (Priority Order)
1. **IMMEDIATE (P0):** Fix Caddy route handler injection in `caddy/manager.go`
- Add `crowdsec` handler to route middleware chain
- Include `trusted_proxies_raw` configuration
- Reload Caddy config when CrowdSec is enabled/disabled
2. **HIGH (P1):** Fix CrowdSec auto-start reconciliation logic
- Debug why `db.First(&cfg)` returns 0 rows despite data existing
- Fix query or add fallback to uuid lookup
- Ensure consistent startup behavior
3. **HIGH (P1):** Add blocking integration test
- Create `crowdsec_blocking_integration.sh`
- Add to CI pipeline
- Must verify actual 403 responses
4. **MEDIUM (P2):** Add automatic bouncer registration
- When CrowdSec starts, auto-register bouncer if not exists
- Update Caddy config with generated API key
- Eliminate manual registration step
5. **LOW (P3):** Add admin UI controls
- Start/Stop CrowdSec buttons
- Bouncer status display
- Decision management interface
---
## Test Environment Details
**Container Image:** `charon:local`
**Build Date:** December 15, 2025
**Caddy Version:** (with crowdsec module v0.9.2)
**CrowdSec Version:** LAPI running, `cscli` available
**Database:** SQLite at `/app/data/charon.db`
**Host OS:** Linux
---
## Files Modified During Testing
- `data/charon.db` - Added `security_configs` and `settings` entries
- Caddy live config - Added `apps.crowdsec` configuration via admin API
**Note:** These changes are ephemeral in the container and not persisted in the repository.
---
## Conclusion
CrowdSec infrastructure is **80% complete** but missing the **critical 20%** - actual traffic enforcement. The foundation is solid:
- LAPI works
- Bouncer communicates
- Decisions are managed correctly
- Database integration works
- Code quality is high (85% coverage)
**However**, without the HTTP handler middleware properly configured, **zero traffic is being blocked**, making the feature unusable in production.
**Estimated effort to fix:** 4-8 hours
1. Add HTTP handler injection logic (2-4h)
2. Fix auto-start logic (1-2h)
3. Add integration test (1-2h)
4. Verify end-to-end (1h)
---
**Report Author:** QA_Security Agent
**Report Status:** FINAL
**Next Action:** Development team to implement fixes per recommendations above