diff --git a/PBS/Tech/Projects/pbs-security-hardening.md b/PBS/Tech/Projects/pbs-security-hardening.md index 3fb8ebc..c1a8508 100644 --- a/PBS/Tech/Projects/pbs-security-hardening.md +++ b/PBS/Tech/Projects/pbs-security-hardening.md @@ -1,3 +1,4 @@ + --- project: pbs-security-hardening type: project-plan @@ -16,9 +17,8 @@ tags: - n8n created: 2026-04-02 updated: 2026-04-02 -path: PBS/Tech/Projects +path: PBS/Tech/Projects/ --- - # PBS Security Hardening - Unified Project Plan ## Project Goal @@ -31,9 +31,7 @@ manual Wordfence email monitoring 2. **Authelia** — SSO with 2FA for all admin/infrastructure services **Approach:** Deploy and validate on staging first, then roll to production. - --- - ## Current Security Baseline ### What's in place today @@ -52,20 +50,18 @@ scanning - No SSO — separate credentials for Portainer, Uptime Kuma, n8n, pbs-hub, phpMyAdmin - No confidence that attacks aren't slipping through - --- - ## Architecture Overview ### Traffic flow after implementation -``` + Internet → Cloudflare (edge WAF/CDN) → Traefik → Crowdsec Bouncer (block/allow decision) → Authelia (SSO check for admin services) → Service (Portainer, n8n, pbs-hub, etc.) → WordPress (own auth, Wordfence for malware scanning only) -``` + ### Tiered alerting model (Crowdsec) - **Tier 1 — Silent block:** Generic bot attempts (admin, test, wp-admin). @@ -88,9 +84,7 @@ on real account, file integrity changes. ### Services NOT behind Authelia - WordPress (uses its own auth + Wordfence + 2FA) - --- - ## Phase 1: Crowdsec on Staging ### Estimated time: 3-4 hours @@ -130,9 +124,7 @@ datasource - [ ] Verify admin tools still accessible - [ ] Check `cscli metrics` for activity - [ ] Check `cscli alerts list` for decisions - --- - ## Phase 2: Crowdsec Alerting via n8n ### Estimated time: 2-3 hours @@ -159,9 +151,7 @@ sub-workflow - [ ] Confirm Tier 3 sends Google Chat alert with username info - [ ] Confirm Tier 4 sends urgent alert - [ ] Verify no false positives from normal browsing - --- - ## Phase 3: Authelia on Staging ### Estimated time: 3-4 hours @@ -200,9 +190,7 @@ two_factor - [ ] Test SSO: login once, access other protected services without re-auth - [ ] Verify WordPress login is unaffected - [ ] Verify public site is unaffected - --- - ## Phase 4: Integration Testing on Staging ### Estimated time: 2 hours @@ -221,9 +209,7 @@ Service - [ ] Crowdsec blocking bots silently - [ ] Tier 3/4 alerts arriving in Google Chat - [ ] No performance degradation - --- - ## Phase 5: Roll to Production ### Estimated time: 2-3 hours @@ -254,9 +240,7 @@ Service - [ ] Verify Wordfence lockout emails have dropped significantly - [ ] Demote Wordfence to malware-scanning-only role - [ ] Consider disabling Wordfence firewall features (now redundant) - --- - ## Phase 6: Codify in Ansible ### Estimated time: 3-4 hours @@ -280,9 +264,7 @@ Service - [ ] Verify Crowdsec + Authelia come up correctly - [ ] Verify alerting works after rebuild - [ ] Verify SSO works after rebuild - --- - ## Wordfence Transition Plan After Crowdsec is stable on production: @@ -294,9 +276,7 @@ checks - [ ] Disable lockout email notifications (the whole point!) - [ ] Document remaining Wordfence role in tech wiki - [ ] Long-term: when WordPress is replaced, Wordfence goes away entirely - --- - ## Security Maintenance Cadence After full deployment: @@ -316,13 +296,11 @@ After full deployment: - Check Docker image updates (Traefik, WordPress, Crowdsec, Authelia) - Review Cloudflare analytics - Spot-check Crowdsec community blocklist enrollment - --- - ## Troubleshooting ### Crowdsec not blocking -```bash +bash # Check if bouncer is connected cscli bouncers list @@ -334,10 +312,10 @@ cscli metrics # Manually test a ban cscli decisions add --ip 1.2.3.4 --reason "test ban" --duration 5m -``` + ### Authelia not redirecting -```bash +bash # Check Authelia logs docker logs authelia @@ -346,26 +324,24 @@ docker exec traefik wget -qO- http://localhost:8080/api/http/middlewares # Check forwardAuth is reaching Authelia docker logs authelia | grep "authorization" -``` + ### False positives -```bash +bash # Whitelist your own IP cscli decisions delete --ip YOUR_IP cscli parsers install crowdsecurity/whitelists # Add your IP to /etc/crowdsec/parsers/s02-enrich/whitelists.yaml -``` + ### Locked out of Authelia -```bash +bash # Reset user password docker exec authelia authelia hash-password -- 'newpassword' # Update users_database.yml with new hash docker restart authelia -``` --- - ## Resources ### Crowdsec @@ -387,9 +363,7 @@ https://www.authelia.com/configuration/prologue/introduction/ - ForwardAuth middleware: https://doc.traefik.io/traefik/middlewares/http/forwardauth/ - Plugin catalog: https://plugins.traefik.io/ - --- - ## Success Criteria - [ ] Wordfence lockout emails drop to near zero @@ -400,9 +374,7 @@ https://doc.traefik.io/traefik/middlewares/http/forwardauth/ - [ ] Public site unaffected - [ ] Everything codified in Ansible and reproducible - [ ] Daily security overhead reduced from 15+ minutes to under 1 minute - --- - *Last Updated: April 2, 2026* *Maintained by: Travis* *Project: Plant Based Southerner Infrastructure*