- Introduced `IpWhitelistPlugin` (DOMAIN): Restricts access to specific IP addresses or CIDR ranges. - Added configuration options: `enabled`, `allowed_ips`, and `status_code`. - Updated `plugins.md` and `plugin-development.md` to document `IpWhitelistPlugin`. - Created fixtures for `services-with-ip-whitelist`. - Added extensive test cases for `IpWhitelistPlugin` to validate configuration and HAProxy output generation. - Ensured seamless integration into the plugin framework alongside other domain plugins.
11 KiB
| sidebar_position |
|---|
| 16 |
Using Plugins
EasyHAProxy supports a plugin system that extends HAProxy configuration with custom functionality. This guide explains how to use and configure plugins.
What are Plugins?
Plugins automatically run during the discovery cycle and can:
- Add HAProxy configuration directives
- Perform maintenance tasks
- Modify discovery data
- Integrate with external services
Plugin Types
Global Plugins
Execute once per discovery cycle regardless of how many domains are discovered.
Use cases:
- Cleanup tasks
- Global monitoring
- DNS updates
- Log management
Example: cleanup plugin
Domain Plugins
Execute once for each discovered domain/host.
Use cases:
- Domain-specific configuration
- IP restoration (Cloudflare)
- Path blocking
- Custom headers per domain
Examples: cloudflare, deny_pages
Built-in Plugins
Cloudflare Plugin (Domain)
Restores the original visitor IP address when requests come through Cloudflare's CDN.
Why use it: Cloudflare replaces the visitor's IP with its own. This plugin restores the original IP from the CF-Connecting-IP header.
Configuration options:
enabled- Enable/disable plugin (default:true)ip_list_path- Path to Cloudflare IP list (default:/etc/haproxy/cloudflare_ips.lst)
Enable via container label:
services:
myapp:
labels:
easyhaproxy.http.host: example.com
easyhaproxy.http.plugins: cloudflare
Custom IP list path:
labels:
easyhaproxy.http.plugins: cloudflare
easyhaproxy.http.plugin.cloudflare.ip_list_path: /custom/path/cf_ips.lst
HAProxy config generated:
# Cloudflare - Restore original visitor IP
acl from_cloudflare src -f /etc/haproxy/cloudflare_ips.lst
http-request set-header X-Forwarded-For %[req.hdr(CF-Connecting-IP)] if from_cloudflare
Required: Download Cloudflare IP list from Cloudflare documentation.
Cleanup Plugin (Global)
Performs cleanup tasks during each discovery cycle, such as removing old temporary files.
Why use it: Prevents disk space issues by automatically cleaning up temporary files created by EasyHAProxy.
Configuration options:
enabled- Enable/disable plugin (default:true)max_idle_time- Maximum age in seconds before deleting files (default:300)cleanup_temp_files- Enable temp file cleanup (default:true)
Enable via YAML:
# /etc/haproxy/static/config.yaml
plugins:
enabled: [cleanup]
config:
cleanup:
max_idle_time: 600
cleanup_temp_files: true
Enable via environment variable:
EASYHAPROXY_PLUGINS_ENABLED=cleanup
EASYHAPROXY_PLUGIN_CLEANUP_MAX_IDLE_TIME=600
Deny Pages Plugin (Domain)
Blocks access to specific paths for a domain, returning a configurable HTTP status code.
Why use it: Protect admin panels, internal APIs, or debugging endpoints from public access.
Configuration options:
enabled- Enable/disable plugin (default:true)paths- Comma-separated list of paths to block (e.g.,/admin,/private)status_code- HTTP status code to return (default:403)
Enable via container label:
services:
webapp:
labels:
easyhaproxy.http.host: example.com
easyhaproxy.http.plugins: deny_pages
easyhaproxy.http.plugin.deny_pages.paths: /admin,/private,/debug
easyhaproxy.http.plugin.deny_pages.status_code: 404
HAProxy config generated:
# Deny Pages - Block specific paths
acl denied_path path_beg /admin /private /debug
http-request deny deny_status 404 if denied_path
IP Whitelist Plugin (Domain)
Restricts access to a domain to only specific IP addresses or CIDR ranges.
Why use it: Restrict access to internal tools, admin panels, or staging environments to only trusted IP addresses.
Configuration options:
enabled- Enable/disable plugin (default:true)allowed_ips- Comma-separated list of IPs/CIDR ranges to allow (e.g.,192.168.1.0/24,10.0.0.1)status_code- HTTP status code to return for blocked IPs (default:403)
Enable via container label:
services:
admin:
labels:
easyhaproxy.http.host: admin.example.com
easyhaproxy.http.plugins: ip_whitelist
easyhaproxy.http.plugin.ip_whitelist.allowed_ips: 192.168.1.0/24,10.0.0.5
easyhaproxy.http.plugin.ip_whitelist.status_code: 403
HAProxy config generated:
# IP Whitelist - Only allow specific IPs
acl whitelisted_ip src 192.168.1.0/24 10.0.0.5
http-request deny deny_status 403 if !whitelisted_ip
Important: This blocks ALL IPs except those in the whitelist. Make sure to include your own IP!
Configuration Methods
Plugins can be configured using three methods, listed in order of precedence (highest to lowest):
1. Container Labels (Domain Plugins Only)
Enable and configure domain plugins for specific containers:
services:
webapp:
image: myapp:latest
labels:
easyhaproxy.http.host: example.com
easyhaproxy.http.port: 80
# Enable multiple plugins
easyhaproxy.http.plugins: cloudflare,deny_pages
# Configure deny_pages plugin
easyhaproxy.http.plugin.deny_pages.paths: /admin,/api/internal
easyhaproxy.http.plugin.deny_pages.status_code: 403
Label format:
- Enable plugins:
easyhaproxy.<definition>.plugins: plugin1,plugin2 - Configure plugin:
easyhaproxy.<definition>.plugin.<plugin_name>.<config_key>: value
Where <definition> is: http, https, tcp, etc.
2. Static YAML Configuration
Configure plugins globally in /etc/haproxy/static/config.yaml:
plugins:
# Global settings
abort_on_error: false # Log and continue on errors (recommended)
# Enable global plugins
enabled: [cleanup]
# Configure individual plugins
config:
cloudflare:
enabled: true
ip_list_path: /etc/haproxy/cloudflare_ips.lst
cleanup:
enabled: true
max_idle_time: 600
deny_pages:
enabled: false # Disable globally, enable per-container via labels
3. Environment Variables
Configure plugins via environment variables:
# Global settings
EASYHAPROXY_PLUGINS_ENABLED=cleanup
EASYHAPROXY_PLUGINS_ABORT_ON_ERROR=false
# Plugin-specific configuration
EASYHAPROXY_PLUGIN_CLEANUP_ENABLED=true
EASYHAPROXY_PLUGIN_CLEANUP_MAX_IDLE_TIME=600
EASYHAPROXY_PLUGIN_CLOUDFLARE_IP_LIST_PATH=/etc/haproxy/cloudflare_ips.lst
Variable format:
- Enable plugins:
EASYHAPROXY_PLUGINS_ENABLED=plugin1,plugin2 - Configure plugin:
EASYHAPROXY_PLUGIN_<PLUGIN_NAME>_<CONFIG_KEY>=value
Common Use Cases
Restrict Admin Panel to Office IPs
Protect admin panel by only allowing access from office network:
labels:
easyhaproxy.http.host: admin.example.com
easyhaproxy.http.plugins: ip_whitelist
easyhaproxy.http.plugin.ip_whitelist.allowed_ips: 203.0.113.0/24,198.51.100.42
Protect Admin Paths
Block access to WordPress admin and other sensitive paths:
labels:
easyhaproxy.http.host: wordpress.example.com
easyhaproxy.http.plugins: deny_pages
easyhaproxy.http.plugin.deny_pages.paths: /wp-admin,/wp-login.php,/.env
easyhaproxy.http.plugin.deny_pages.status_code: 404
Cloudflare IP Restoration
Restore original visitor IPs for applications behind Cloudflare:
labels:
easyhaproxy.http.host: myapp.com
easyhaproxy.http.plugins: cloudflare
Multiple Plugins Together
Combine multiple plugins for one domain:
labels:
easyhaproxy.http.host: secure-app.com
easyhaproxy.http.plugins: cloudflare,deny_pages
easyhaproxy.http.plugin.deny_pages.paths: /admin,/config
easyhaproxy.http.plugin.deny_pages.status_code: 403
Automatic Cleanup
Keep your system clean with automatic temp file removal:
# /etc/haproxy/static/config.yaml
plugins:
enabled: [cleanup]
config:
cleanup:
enabled: true
max_idle_time: 3600 # 1 hour
Error Handling
Log and Continue (Recommended)
By default, plugin errors are logged as warnings and discovery continues:
plugins:
abort_on_error: false # Default
When to use: Most situations. Ensures a failing plugin doesn't prevent HAProxy updates.
Behavior:
- Plugin errors logged as warnings
- Discovery cycle continues
- Other plugins still execute
- HAProxy config is generated without the failed plugin
Abort on Error
Stop discovery cycle if any plugin fails:
plugins:
abort_on_error: true
When to use: Critical plugins where failure should halt deployment.
Behavior:
- Plugin error stops discovery
- Previous HAProxy config remains active
- No configuration changes until issue is resolved
Troubleshooting
Enable Debug Logging
See detailed plugin execution information:
EASYHAPROXY_LOG_LEVEL=DEBUG
Look for:
INFO: Loaded builtin plugin: cloudflare (domain)
INFO: Loaded builtin plugin: cleanup (global)
DEBUG: Executing domain plugin: cloudflare for domain: example.com
DEBUG: Plugin cloudflare metadata: {'domain': 'example.com', 'ip_list_path': '/etc/haproxy/cloudflare_ips.lst'}
Plugin Not Loading
Check:
- Plugin file exists in
/etc/haproxy/plugins/or builtin directory - Python syntax is valid
- Plugin class inherits from
PluginInterface - Check logs for load errors
Plugin Not Executing
For domain plugins:
- Check container has label:
easyhaproxy.http.plugins: plugin_name - Verify plugin name is correct (case-sensitive)
- Enable debug logging
For global plugins:
- Check YAML config:
plugins.enabled: [plugin_name] - Or env var:
EASYHAPROXY_PLUGINS_ENABLED=plugin_name - Enable debug logging
Configuration Not Applied
Check precedence order:
- Container labels (highest)
- YAML configuration
- Environment variables (lowest)
Container labels override YAML and env vars.
Plugin Output Missing
Verify:
- Plugin is enabled (
enabled: true) - Plugin configuration is correct
- Plugin's
process()method returns validPluginResult - Check debug logs for plugin execution
Best Practices
- Start with log-and-continue mode - Use
abort_on_error: falseuntil you're confident plugins are stable - Use container labels for domain-specific config - Easier to manage per-service
- Use YAML/env for global config - Better for global plugins and defaults
- Enable debug logging during testing - Helps identify configuration issues
- Test plugin changes in staging first - Avoid production surprises
- Keep plugin configurations simple - Use defaults when possible
Limitations
- Plugins must be written in Python
- Domain plugins execute for each domain, so keep them lightweight
- Plugins cannot modify the Jinja2 template structure directly
- Plugin errors in abort mode prevent all configuration updates
Creating Custom Plugins
To create your own plugins, see the Plugin Developer Guide.
Further Reading
- Plugin Developer Guide - Create custom plugins
- Container Labels - Label configuration reference
- Environment Variables - Environment variable reference
- Static Configuration - YAML configuration reference