Popular Plugins #

The Caddy plugin ecosystem keeps growing rapidly along with the increasing operational system needs in modern production environments. Caddy is natively equipped with various robust features for serving static websites, doing load balancing, and managing automatic TLS encryption certificates. However, in complex real-world deployment scenarios, you’re often required to extend this web server’s capabilities: limiting request rates (rate limiting) to protect public APIs, integrating centralized OAuth/Single Sign-On (SSO) authentication systems, implementing page cache storage for performance improvements, and securing networks from cyber attacks using threat intelligence. Through its modular platform, Caddy lets you combine various trusted third-party plugins directly into one custom binary. We’ll do an in-depth analysis of the five most popular and crucial plugins often used in production environments, learn how their system architectures work, practice configuring them safely, and compose plugin eligibility evaluation criteria to maintain long-term operational system stability.

Analysis of the Caddy Plugin Ecosystem #

Before deciding to integrate third-party modules into your production Caddy binary, you must first understand how this ecosystem is managed. The Caddy team provides an official module directory on their website, where community developers can register their Go plugins.

Although this modularity provides freedom, adding third-party plugins to a web server binary brings security and stability risk consequences:

  1. Supply Chain Security Risk: Imported plugin source code runs with the same high privileges as the main Caddy process. If the plugin developer’s GitHub repository is hacked and malicious code is inserted, your web server can suffer sensitive data leaks.
  2. Binary Stability: Unlike standard Go modules strictly maintained by the Caddy core team, some community plugins may not be written with goroutine safety best practices or safe memory handling, potentially triggering memory leaks or binary crashes under high traffic loads.
  3. Version Compatibility: Minor updates to the Caddy codebase can sometimes change its internal API structure, causing old plugin compilation to fail if not actively updated by its maintainer.

Therefore, you must be selective and defensive in choosing plugins. We’ll discuss plugins that are time-tested, have a broad community base, and are actively maintained by prominent contributors in the Caddy ecosystem.


caddy-security: Centralized Authentication and Authorization Portal #

The caddy-security module (actively maintained by Paul Green) is one of the most powerful and comprehensive plugins in the Caddy ecosystem. This plugin acts as a unified access security gateway combining the Authentication Portal, Authorization Policy, Single Sign-On (SSO), Multi-Factor Authentication (MFA), and third-party identity integration (OAuth2/OIDC) features directly at your web server edge level.

With caddy-security, you no longer need to write login logic code, user registration forms, JWT token verification, or Google Authenticator verification in every backend microservice application. Caddy filters all incoming requests, verifies user identity, and only forwards legitimate requests to the backend.

1. Custom Binary Compilation #

# Compile Caddy with the caddy-security module
xcaddy build --with github.com/greenpau/caddy-security

2. Integrated Caddyfile Configuration Implementation #

Here’s a production configuration example for a login portal using GitHub OAuth2, complete with backend application access authorization policies:

# Global options block to define the centralized security system
{
    security {
        # 1. External Identity Provider Configuration (GitHub OAuth2)
        oauth identity provider github {
            realm github
            driver github
            client_id     {env.GITHUB_CLIENT_ID}
            client_secret {env.GITHUB_CLIENT_SECRET}
            scopes        user
        }
        
        # 2. Interactive Authentication Portal Configuration
        authentication portal myportal {
            crypto default token lifetime 3600 # JWT token validity: 1 hour
            
            cookie domain example.com # The cookie applies to all subdomains
            
            # Login portal interface link configuration
            ui {
                links {
                    "My Dashboard" /dashboard
                    "Logout" /auth/logout
                }
            }
            
            # Identity transformation: If login via GitHub succeeds,
            # automatically grant the 'authp/user' role
            transform user {
                match realm github
                action add role authp/user
            }
        }
        
        # 3. Authorization Policy for Internal Pages
        authorization policy admin_policy {
            set auth url https://auth.example.com/ # Redirect to the login portal if not authenticated
            allow roles authp/admin authp/user      # Only allow these roles
        }
    }
}

# Special subdomain for handling user login/authentication processes
auth.example.com {
    route {
        authenticate with myportal
    }
}

# Protected private backend application subdomain
app.example.com {
    route {
        # Validate user access permissions before the request goes to the backend upstream
        authorize with admin_policy
        
        # If validation passes, forward the request to the original backend application server
        reverse_proxy localhost:3000
    }
}

caddy-ratelimit: API and Layer 7 DDoS Protection #

The caddy-ratelimit module (developed by Matt Holt, Caddy’s original creator) is an essential module for limiting the rate of incoming requests to your web server. Rate limiting is very important for protecting APIs from abuse (like mass data theft via scraping), preventing brute force attacks on login forms, and mitigating application-level denial of service (Layer 7 DDoS) attacks.

This module uses an efficient in-memory Token Bucket algorithm. You can configure limits based on client IP addresses, custom request headers, or specific URL paths.

1. Custom Binary Compilation #

# Compile Caddy with the caddy-ratelimit module
xcaddy build --with github.com/mholt/caddy-ratelimit

2. Granular Rate Limiting Configuration in the Caddyfile #

# Example of API request rate limiting configuration
api.example.com {
    # Global Limit: Maximum 100 requests per 1 minute for every IP address
    rate_limit {
        zone api_zone {
            key    {remote_ip}
            window 1m
            events 100
        }
    }
    
    # Special Login Limit: Maximum 5 login attempts per 15 minutes
    rate_limit {
        zone login_zone {
            key    {remote_ip}
            window 15m
            events 5
        }
    }
    
    # Apply aggressive limiting specifically to the sensitive login endpoint
    handle /auth/login {
        rate_limit {
            zone login_zone
        }
        reverse_proxy localhost:8080
    }
    
    # Other general API routes use the global zone limit
    handle /* {
        reverse_proxy localhost:3000
    }
}

cache-handler: High-Performance HTTP Caching Layer #

The cache-handler module allows Caddy to act as a very efficient reverse proxy cache server, similar to the caching capabilities of Varnish or Nginx Microcaching.

By enabling caching on the Caddy side, Caddy stores response copies from the backend (e.g., compiled blog page database query results) into RAM or local disk. When a similar subsequent request arrives from another visitor, Caddy can directly return that response data from cache without contacting the backend server at all. This reduces database server load and speeds up page load times to under 10 milliseconds.

1. Custom Binary Compilation #

# Compile Caddy with the cache-handler module
xcaddy build --with github.com/caddyserver/cache-handler

2. Cache-Handler Configuration in the Caddyfile #

# Example of dynamic proxy caching implementation
example.com {
    # Define page caching rules
    cache {
        # Only cache GET and HEAD requests that are HTTP-safe
        allowed_http_verbs GET HEAD
        
        # Default cache Time to Live (TTL) if the backend doesn't provide one
        ttl 5m
        
        # Enable the Stale-While-Revalidate feature:
        # Caddy keeps serving expired cache to users for up to 1 minute
        # while simultaneously updating that cache from the backend in the background.
        stale 1m
        
        # Custom response header to verify cache status (HIT / MISS) in client browsers
        header_success "X-Cache-Status" "HIT"
    }
    
    reverse_proxy localhost:3000
}

caddy-l4: Layer 4 Proxying (TCP/UDP Proxying) #

By default, Caddy is an HTTP/HTTPS server (Layer 7). However, with the caddy-l4 plugin, you can turn Caddy into a versatile load balancer and proxy for low-level network traffic (Layer 4 TCP and UDP).

This is very useful when you want to use Caddy as the main gateway for routing non-web traffic, such as:

  • Routing PostgreSQL (port 5432) or MySQL (port 3306) database connections to backend replica clusters.
  • Providing TLS termination for DNS over TLS (DoT) servers or MQTT IoT servers.
  • Managing incoming ports for centralized game servers.

1. Custom Binary Compilation #

# Compile Caddy with the caddy-l4 module
xcaddy build --with github.com/mholt/caddy-l4

2. TCP/UDP Proxying Configuration in the Caddyfile #

Note that Layer 4 configuration is defined inside the global options block ({ ... }) because this module runs outside Caddy’s normal HTTP virtual host handling flow:

# Example of database proxying and Layer 4 TLS termination
{
    # Main block for non-HTTP Layer 4 configuration
    layer4 {
        # 1. Plain PostgreSQL Database TCP Proxying
        0.0.0.0:5432 {
            route {
                proxy {
                    upstream postgres-node1:5432
                    upstream postgres-node2:5432
                }
            }
        }
        
        # 2. Receiving encrypted TLS TCP connections (TLS Termination)
        # then sending the clean binary to the internal non-TLS service
        0.0.0.0:9443 {
            route {
                # Caddy handles the TLS handshake and certificate validation here
                tls
                
                # Forward the raw binary data to the internal backend
                proxy {
                    upstream localhost:9000
                }
            }
        }
    }
}

crowdsec-caddy-bouncer: Threat Intelligence Integration #

crowdsec-caddy-bouncer is a modern security plugin integrating Caddy with the CrowdSec engine. CrowdSec acts as a community-based intrusion detection system (IDS) monitoring your server activity logs to detect suspicious behavior (like port scanning, brute force, or malicious bot activity).

The CrowdSec bouncer in Caddy periodically downloads the problematic IP blocklist from your local CrowdSec server (LAPI). Every time a request arrives from an IP address on that blacklist, Caddy blocks it at the front gate before processing the request to your backend application.

1. Custom Binary Compilation #

# Compile Caddy with the CrowdSec HTTP bouncer
xcaddy build --with github.com/hslatman/caddy-crowdsec-bouncer/http

2. CrowdSec Bouncer Configuration in the Caddyfile #

# Global CrowdSec bouncer configuration
{
    crowdsec {
        # The CrowdSec Local API address running on your server
        api_url    http://localhost:8080
        
        # The bouncer authentication API key obtained from: crowdsec-cli bouncers add
        api_key    {env.CROWDSEC_API_KEY}
        
        # Periodic blacklist IP synchronization interval (every 10 seconds)
        ticker_interval 10s
    }
}

# Apply automatic blocking on our production website
example.com {
    # Enable the CrowdSec bouncer to filter requests
    crowdsec
    
    reverse_proxy localhost:3000
}

Module Feature and Suitability Comparison #

To make choosing the right module for your operational infrastructure needs easier, here’s a comparison table of the five popular plugins we’ve discussed:

Module NameModule CategoryCPU/RAM Resource ConsumptionSetup ComplexityProduction Usage Scale
caddy-securityAuthentication & AuthorizationMediumHighVery Suitable for Corporate SSO & SaaS
caddy-ratelimitL7 Security & API GuardLowLowMandatory for All Public APIs
cache-handlerPerformance OptimizationHigh (RAM)MediumVery Suitable for CMS & Landing Pages
caddy-l4Protocol Routing (L4)Very LowMediumSuitable for Database & IoT Gateways
crowdsec-bouncerNetwork SecurityLowMediumVery Suitable for Public Internet Servers

Plugin Selection and Evaluation Guide in Production #

Before adding any plugin to your company’s main production system, you must do a defensive curation process. Use the evaluation checklist below to assess a plugin’s eligibility before deploying it:

PRODUCTION PLUGIN EVALUATION CHECKLIST:

SECURITY:
  □ Does the plugin creator have a trusted reputation in the community?
  □ Is there a history of unhandled security vulnerabilities?
  □ Is the Go plugin source code clean of 'unsafe' functions or unclear dependencies?
  □ Can API tokens/keys be stored in environment variables (not hardcoded)?

STABILITY & MAINTENANCE:
  □ When was the last commit date in the Git repository? (Beware if > 1 year without activity)
  □ Are there automated tests (Unit Tests) with good coverage percentages?
  □ Are user-reported issues/bugs actively answered by maintainers?
  □ Is the plugin proven compatible with the latest Caddy minor versions?

OPERATIONAL:
  □ Has the plugin's latency impact been tested in a staging environment?
  □ Does the plugin support structured logging compatible with Caddy's JSON format?
  □ Is there complete documentation about recovery options if the plugin fails to function?

To help visualize how HTTP request data flows through various integrated plugin modules before reaching the core application handling, look at the flowchart below:

flowchart TD
    A["Request Arrives from Client\n(TCP Connection)"] --> B{"1. Is it an HTTP request?"}
    
    B -->|No| C["caddy-l4 Module (Layer 4)\n(Routing database/TCP streams)"]
    B -->|Yes| D["2. crowdsec-bouncer Module\n(Check the IP blacklist in memory)"]
    
    D --> D1{"Is the IP on the blacklist?"}
    D1 -- "Yes" --> D2["Block the Request\n(Reject connection / 403 status)"]
    D1 -- "No" --> E["3. caddy-security Module\n(Validate cookies / JWT tokens)"]
    
    E --> E1{"Is the request authenticated?"}
    E1 -- "No" --> E2["Redirect the Client to the Login Portal\n(OAuth2 GitHub/Google)"]
    E1 -- "Yes" --> F["4. caddy-ratelimit Module\n(Check the IP quota limit)"]
    
    F --> F1{"Has the quota limit been exceeded?"}
    F1 -- "Yes" --> F2["Temporarily Block\n(Return HTTP 429 status)"]
    F1 -- "No" --> G["5. cache-handler Module\n(Check the local page cache)"]
    
    G --> G1{"Is there a cache HIT?"}
    G1 -- "Yes" --> G2["Return the response from RAM Cache\n(Fast response time < 10ms)"]
    G1 -- "No" --> H["6. Caddy Core HTTP Handler\n(reverse_proxy to backend / file_server)"]
    
    H --> I["7. New Response Written & Stored to Cache"]
    I --> J["Done"]
    G2 --> J

The visual transformation above shows how Caddy can act as a comprehensive security gateway, separating operational security logic from your backend application’s business logic.


Summary #

  • Open Ecosystem: The Caddy ecosystem lets the community extend web server features through hundreds of custom plugins ready for modular compilation.
  • SSO Auth Portal: The caddy-security plugin eliminates writing login code in backends by handling OAuth2/JWT authentication directly at the Caddy front gate.
  • DDoS Protection: Use caddy-ratelimit to prevent login brute-force and API scraping limits based on a combination of IP addresses and endpoint URLs.
  • Server Optimization: The cache-handler module dramatically improves web performance by serving static content from RAM without touching backend servers.
  • TCP/UDP Proxying: Leverage caddy-l4 if you want Caddy to manage non-HTTP traffic distribution like PostgreSQL database ports or MQTT.
  • Threat Intelligence: Install crowdsec-caddy-bouncer to proactively block community-based cyber attacks before malicious packets enter the server.
  • Defensive Evaluation: Always audit the quality and maintenance activity of third-party plugin repositories before deciding to deploy them to production.

← Previous: xcaddy   Next: Caddy DNS →

About | Author | Content Scope | Editorial Policy | Privacy Policy | Disclaimer | Contact