Commit Graph

39 Commits

Author SHA1 Message Date
f7ef34b988 feat(api/ssl/bundle): clean up superseded lineages after issuance
All checks were successful
HAProxy Manager Build and Push / Build-and-Push (push) Successful in 53s
The bundle endpoint correctly issued multi-SAN certs but left old
single-SAN .pem files (e.g. <name>-0001.pem) in /etc/haproxy/certs/.
HAProxy's `bind ... ssl crt /etc/haproxy/certs` loads everything in the
directory and picked the alphabetically-first matching file — typically
the older single-SAN one — so the new bundle had no effect on what was
served. Repro on peptidesaver.net: bundle covered 4 SANs but HAProxy
kept serving peptidesaver.net-0001.pem (single SAN, April-issued).

After a successful bundle write, walk SSL_CERTS_DIR and remove any
.pem whose CN is in the new bundle's name list (excluding the bundle's
own combined file). Drop the matching certbot lineage with
`certbot delete --cert-name <X> -n` so `certbot renew` stops touching
the dead lineage too.

Returns a `cleanup` summary in the API response so callers can log /
display what was deleted.

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
2026-05-09 11:58:21 -07:00
90255cc4b3 feat(api): add /api/ssl/bundle for per-site SAN cert issuance
All checks were successful
HAProxy Manager Build and Push / Build-and-Push (push) Successful in 1m1s
WHP's renewal orchestrator now bundles a site's domains into one cert
covering all SANs, instead of N separate single-domain orders. Single
ACME order = better behavior under Let's Encrypt's 50/hour orders limit
when many domains need attention at once.

Endpoint: POST /api/ssl/bundle
Body: {"primary": "example.com", "sans": ["www.example.com", ...]}

- Uses --cert-name <primary> so the lineage stays stable across renewals
  (no -0001/-0002 proliferation seen with the legacy single-domain flow).
- Single combined .pem at /etc/haproxy/certs/<primary>.pem; HAProxy SNI-
  matches against the cert's SAN list, so one file serves all included
  hostnames.
- Updates the domains table for every SAN in the bundle.
- Hard cap at 100 SANs (LE limit).

Existing /api/ssl single-domain endpoint kept for backwards compat.
The WHP haproxy_manager::bundleSSL() helper falls back to a per-domain
loop if /api/ssl/bundle returns 404, so the WHP side keeps working
during the rolling image upgrade window.

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
2026-05-09 11:32:15 -07:00
124a5373d2 Fix wildcard SSL cert: find certbot -NNNN dirs and use _wildcard_ filename
All checks were successful
HAProxy Manager Build and Push / Build-and-Push (push) Successful in 1m1s
Add find_certbot_live_dir() helper to locate the most recent certbot live
directory for a domain, handling -NNNN suffixed dirs from repeated requests.
Fix combined cert filename from *.domain.pem to _wildcard_.domain.pem.
Apply the helper across all SSL endpoints (request, renew, verify, download).

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-02-20 06:38:28 -08:00
657cd28344 Fix certbot hook script paths and add logging
All checks were successful
HAProxy Manager Build and Push / Build-and-Push (push) Successful in 3m4s
Hook scripts are at /haproxy/scripts/ inside the container (per
Dockerfile COPY), not /app/scripts/. Also added logging of certbot
stdout/stderr so failures are visible in haproxy-manager.log.

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-02-20 06:18:14 -08:00
91c92dd07e Add wildcard domain support with DNS-01 ACME challenge flow
All checks were successful
HAProxy Manager Build and Push / Build-and-Push (push) Successful in 1m17s
Support wildcard domains (*.domain.tld) in HAProxy config generation
with exact-match ACLs prioritized over wildcard ACLs. Add DNS-01
challenge endpoints that coordinate with certbot via auth/cleanup
hook scripts for wildcard SSL certificate issuance.

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-02-19 13:06:08 -08:00
1fcb25bb88 Update SQL logic to update instead of delete and re-add
All checks were successful
HAProxy Manager Build and Push / Build-and-Push (push) Successful in 1m18s
2025-12-18 12:23:06 -08:00
1d22d789b8 Simplify certificate renewal scripts and add certbot cleanup
All checks were successful
HAProxy Manager Build and Push / Build-and-Push (push) Successful in 59s
Simplified all certificate renewal scripts to be more straightforward and reliable:
- Scripts now just run certbot renew and copy cert+key files to HAProxy format
- Removed overly complex retry logic and error handling
- Both in-container and host-side scripts work with cron scheduling

Added automatic certbot cleanup when domains are removed:
- When a domain is deleted via API, certbot certificate is also removed
- Prevents renewal errors for domains that no longer exist in HAProxy
- Cleans up both HAProxy combined cert and Let's Encrypt certificate

Script changes:
- renew-certificates.sh: Simplified to 87 lines (from 215)
- sync-certificates.sh: Simplified to 79 lines (from 200+)
- host-renew-certificates.sh: Simplified to 36 lines (from 40)
- All scripts use same pattern: query DB, copy certs, reload HAProxy

Python changes:
- remove_domain() now calls 'certbot delete' to remove certificates
- Prevents orphaned certificates from causing renewal failures

🤖 Generated with [Claude Code](https://claude.com/claude-code)

Co-Authored-By: Claude <noreply@anthropic.com>
2025-11-20 09:56:56 -08:00
71f4b9ef05 Add CIDR notation support for IP blocking
All checks were successful
HAProxy Manager Build and Push / Build-and-Push (push) Successful in 2m1s
- Update map file format to include value (IP/CIDR 1)
- Fix HAProxy template to use map_ip() for CIDR support
- Update runtime map commands to include value
- Document CIDR range blocking in API documentation
- Support blocking entire network ranges (e.g., 192.168.1.0/24)

This allows blocking compromised ISP ranges and other large-scale attacks.
2025-11-17 12:07:32 -08:00
65248680a5 Fix HAProxy 3.0.11 compatibility issues
All checks were successful
HAProxy Manager Build and Push / Build-and-Push (push) Successful in 1m54s
Major syntax and configuration updates for HAProxy 3.0.11:

Configuration Fixes:
- Remove conflicting stick-table declarations in frontend
- Move security tables to separate backend sections
- Fix ACL syntax errors (missing_browser_headers → separate ACLs)
- Remove unsupported add-var() syntax
- Simplify threat scoring to use flags instead of cumulative values

Security Table Architecture:
- security_blacklist: 24h persistent offender tracking
- wp_403_track: WordPress authentication failure monitoring
- Separated from main frontend table to avoid conflicts

Simplified Threat Detection:
- low_threat: Rate abuse, suspicious methods, missing headers
- medium_threat: SQL injection, directory traversal, WordPress brute force
- high_threat: Bot scanners, admin scans, shell attempts
- critical_threat: Blacklisted IPs, auto-blacklist candidates

Response System:
- Low threat: Warning headers only
- Medium threat: Tarpit delays
- High threat: Immediate deny (403)
- Critical threat: Blacklist and deny

Enhanced Compatibility:
- Removed HAProxy 2.6-specific syntax
- Updated to HAProxy 3.0.11 requirements
- Maintained security effectiveness with simpler logic
- Added security tables template integration

The system maintains comprehensive protection while being compatible
with HAProxy 3.0.11's stricter parsing and syntax requirements.

🤖 Generated with [Claude Code](https://claude.ai/code)

Co-Authored-By: Claude <noreply@anthropic.com>
2025-09-22 17:29:32 -07:00
e2f350ce95 Add comprehensive anti-scan and brute force protection
All checks were successful
HAProxy Manager Build and Push / Build-and-Push (push) Successful in 54s
Implement multi-layered security system to protect against exploit
scanning and brute force attacks while maintaining legitimate traffic flow.

Security Features:
- Attack detection for common exploit paths (WordPress, phpMyAdmin, shells)
- Malicious user agent filtering (sqlmap, nikto, metasploit, etc.)
- SQL injection and directory traversal pattern detection
- Progressive rate limiting (50 req/10s, 20 conn/10s, 10 err/10s)
- Three-tier response: tarpit → deny → repeat offender blocking
- Strict authentication endpoint protection (5 req/10s limit)
- Real IP detection through proxy headers (Cloudflare, X-Real-IP)

Management Tools:
- manage-blocked-ips.sh: Dynamic IP blocking/unblocking
- monitor-attacks.sh: Real-time threat monitoring
- API endpoints for security stats and temporary blocking
- Auto-expiring temporary blocks with cleanup endpoint

HAProxy 2.6 Compatibility:
- Removed silent-drop (not available in 2.6)
- Fixed stick table counter syntax
- Using standard tarpit and deny actions

🤖 Generated with [Claude Code](https://claude.ai/code)

Co-Authored-By: Claude <noreply@anthropic.com>
2025-09-22 16:50:35 -07:00
2406d9f995 Add 403 status to blocked IP page and reload HAProxy on IP block/unblock
All checks were successful
HAProxy Manager Build and Push / Build-and-Push (push) Successful in 51s
- Modified /blocked-ip route to return 403 Forbidden status with HTML page
- Added HAProxy reload after adding blocked IP to ensure consistency
- Added HAProxy reload after removing blocked IP to ensure consistency
- Includes error handling for reload failures without breaking the operation

🤖 Generated with [Claude Code](https://claude.ai/code)

Co-Authored-By: Claude <noreply@anthropic.com>
2025-08-22 10:06:04 -07:00
7869b81f27 CRITICAL FIX: Migrate HAProxy IP blocking from ACL to map files
All checks were successful
HAProxy Manager Build and Push / Build-and-Push (push) Successful in 51s
**Problem Solved:**
- HAProxy ACL 64-word limit caused config parsing failures
- "too many words, truncating after word 64" error
- Complete service outage when >64 IPs were blocked
- Error: "no such ACL : 'is_blocked'" broke all traffic routing

**Solution: HAProxy Map Files (v1.6+)**
-  Unlimited IP addresses (no word limits)
-  Runtime updates without config reloads
-  Better performance (hash table vs linear search)
-  Safer config management with validation & rollback

**Technical Implementation:**

**Map File Integration:**
- `/etc/haproxy/blocked_ips.map` stores all blocked IPs
- `http-request deny status 403 if { src -f /etc/haproxy/blocked_ips.map }`
- Runtime updates: `echo "add map #0 IP" | socat stdio /var/run/haproxy.sock`

**Safety Features Added:**
- `create_backup()` - Automatic config/map backups before changes
- `validate_haproxy_config()` - Config validation before applying
- `restore_backup()` - Automatic rollback on failures
- `reload_haproxy_safely()` - Safe reload with validation pipeline

**Runtime Management:**
- `update_blocked_ips_map()` - Sync database to map file
- `add_ip_to_runtime_map()` - Immediate IP blocking without reload
- `remove_ip_from_runtime_map()` - Immediate IP unblocking

**New API Endpoints:**
- `POST /api/config/reload` - Safe config reload with rollback
- `POST /api/blocked-ips/sync` - Sync database to runtime map

**Template Changes:**
- Replaced ACL method: `acl is_blocked src IP1 IP2...` (64 limit)
- With map method: `http-request deny if { src -f blocked_ips.map }` (unlimited)

**Backwards Compatibility:**
- Existing API endpoints unchanged (GET/POST/DELETE /api/blocked-ips)
- Database schema unchanged
- Automatic migration on first config generation

**Performance Improvements:**
- O(1) hash table lookups vs O(n) linear ACL search
- No config reloads needed for IP changes
- Supports millions of IPs if needed
- Memory efficient external file storage

**Documentation:**
- Complete migration guide in MIGRATION_GUIDE.md
- Updated API documentation with new endpoints
- Runtime management examples
- Troubleshooting guide

**Production Safety:**
- All changes include automatic backup/restore
- Config validation prevents bad deployments
- Runtime updates avoid service interruption
- Comprehensive error logging and monitoring

This fixes the critical production outage caused by ACL word limits
while providing a more scalable and performant IP blocking solution.

🤖 Generated with [Claude Code](https://claude.ai/code)

Co-Authored-By: Claude <noreply@anthropic.com>
2025-08-22 08:31:17 -07:00
ca37a68255 Add IP blocking functionality to HAProxy Manager
All checks were successful
HAProxy Manager Build and Push / Build-and-Push (push) Successful in 1m1s
- Add blocked_ips database table to store blocked IP addresses
- Implement API endpoints for IP blocking management:
  - GET /api/blocked-ips: List all blocked IPs
  - POST /api/blocked-ips: Block an IP address
  - DELETE /api/blocked-ips: Unblock an IP address
- Update HAProxy configuration generation to include blocked IP ACLs
- Create blocked IP page template for denied access
- Add comprehensive API documentation for WHP integration
- Include test script for IP blocking functionality
- Update .gitignore with Python patterns
- Add CLAUDE.md for codebase documentation

🤖 Generated with [Claude Code](https://claude.ai/code)

Co-Authored-By: Claude <noreply@anthropic.com>
2025-08-21 18:32:47 -07:00
d4f54aef35 Fix HAProxy crash loop and improve startup resilience
All checks were successful
HAProxy Manager Build and Push / Build-and-Push (push) Successful in 36s
- Add configuration regeneration before HAProxy startup
- Add configuration validation before starting HAProxy
- Add automatic configuration regeneration if invalid config detected
- Prevent container crashes when HAProxy fails to start
- Allow container to continue running even if HAProxy is not available
- Add better error handling and logging for startup issues
2025-07-11 19:37:41 -07:00
fac6cef0db Fix HAProxy 2.6 compatibility for default backend
All checks were successful
HAProxy Manager Build and Push / Build-and-Push (push) Successful in 37s
- Replace http-response set-body (HAProxy 2.8+) with local server approach
- Add separate Flask server on port 8080 to serve default page
- Update default backend template to use local server instead of inline HTML
- Maintain all customization features via environment variables
- Fix JavaScript error handling for domains API response
2025-07-11 19:27:42 -07:00
27f3f8959b Add default backend page for unmatched domains
All checks were successful
HAProxy Manager Build and Push / Build-and-Push (push) Successful in 37s
- Add default backend template (hap_default_backend.tpl)
- Add customizable default page HTML template (default_page.html)
- Modify generate_config() to include default backend for unmatched domains
- Add environment variables for customizing default page content:
  - HAPROXY_DEFAULT_PAGE_TITLE
  - HAPROXY_DEFAULT_MAIN_MESSAGE
  - HAPROXY_DEFAULT_SECONDARY_MESSAGE
- Update README with documentation and examples
- Ensure backward compatibility with existing configurations
- Remove email contact link as requested
2025-07-11 19:10:05 -07:00
ef488a253d Add /api/certificates/request endpoint for programmatic certificate requests, update docs and add test script
All checks were successful
HAProxy Manager Build and Push / Build-and-Push (push) Successful in 37s
2025-07-11 17:14:01 -07:00
7b0b4c0476 Major upgrade: API key authentication, certificate renewal/download endpoints, monitoring/alerting scripts, improved logging, and documentation updates. See UPGRADE_SUMMARY.md for details.
All checks were successful
HAProxy Manager Build and Push / Build-and-Push (push) Successful in 43s
2025-07-11 06:24:56 -07:00
7550df9890 Fixing reload issue 2025-04-18 16:52:57 -07:00
8ae1a6b99f debug reload
All checks were successful
HAProxy Manager Build and Push / Build-and-Push (push) Successful in 1m9s
2025-03-09 11:56:18 -07:00
9de12c72de added missing return
All checks were successful
HAProxy Manager Build and Push / Build-and-Push (push) Successful in 58s
2025-03-09 11:11:35 -07:00
cb58f1d762 Switch reload from post to get
All checks were successful
HAProxy Manager Build and Push / Build-and-Push (push) Successful in 35s
2025-03-09 11:07:21 -07:00
2492eab708 Fix missing '/'
All checks were successful
HAProxy Manager Build and Push / Build-and-Push (push) Successful in 35s
2025-03-09 11:02:20 -07:00
64c707317f Adding reload function and more tweaks for backends
All checks were successful
HAProxy Manager Build and Push / Build-and-Push (push) Successful in 48s
2025-03-09 10:59:03 -07:00
9621786175 Adding web interface
All checks were successful
HAProxy Manager Build and Push / Build-and-Push (push) Successful in 1m18s
2025-03-06 16:51:29 -08:00
c5f29374e1 Fix Template Override
All checks were successful
HAProxy Manager Build and Push / Build-and-Push (push) Successful in 38s
2025-02-21 10:17:15 -08:00
d944a75fb5 fix backend creation
All checks were successful
HAProxy Manager Build and Push / Build-and-Push (push) Successful in 39s
2025-02-21 08:28:56 -08:00
ac40737fd7 Adding template overrides
All checks were successful
HAProxy Manager Build and Push / Build-and-Push (push) Successful in 38s
2025-02-21 08:07:58 -08:00
6b28c118de Adding template overrides
All checks were successful
HAProxy Manager Build and Push / Build-and-Push (push) Successful in 38s
2025-02-21 08:01:16 -08:00
c47118729f add new line at the end of the server block to prevent issue with haproxy reloading
All checks were successful
HAProxy Manager Build and Push / Build-and-Push (push) Successful in 38s
2025-02-21 06:42:30 -08:00
ff529be07f Fix Templates from causing errors with haproxy when added, Fix add notice when haproxy fails check
All checks were successful
HAProxy Manager Build and Push / Build-and-Push (push) Successful in 38s
2025-02-21 06:28:51 -08:00
c951103b3b adding function on start up
All checks were successful
HAProxy Manager Build and Push / Build-and-Push (push) Successful in 39s
2025-02-21 06:00:37 -08:00
1df58758b5 Make haproxy start with the script
All checks were successful
HAProxy Manager Build and Push / Build-and-Push (push) Successful in 39s
2025-02-20 17:00:28 -08:00
32498f1a04 fix order of acls and backends, put db in volume
All checks were successful
HAProxy Manager Build and Push / Build-and-Push (push) Successful in 38s
2025-02-20 16:26:27 -08:00
ff46f0a616 Add regenerate endpoint
All checks were successful
HAProxy Manager Build and Push / Build-and-Push (push) Successful in 38s
2025-02-20 15:40:32 -08:00
576666d9da Fixing order for haproxy config
All checks were successful
HAProxy Manager Build and Push / Build-and-Push (push) Successful in 39s
2025-02-20 15:29:42 -08:00
cef684b0a9 register certbot by default 2025-02-20 14:01:53 -08:00
305fffba42 haproxy manager 2025-02-20 13:41:38 -08:00
9c52edd53a Not fully working, but saving progress 2025-02-19 07:53:26 -08:00