Caddy With Zabbix, Gitea, Wazuh, and Readeck

I thought I’d share my Caddy reverse proxy configuration for some of my internal services here. If you want to know more about how I’m using Caddy as an internal CA, you can check out my previous post. In my HomeLab setup, Caddy acts as a reverse proxy, providing its own internal CA for the use of TLS certificates. You’ll find the default Caddy configuration file in /etc/caddy/Caddyfile.

Configuration

Explanation of the directives:
  • tls internal Enables HTTPS using Caddy’s internal, locally-trusted CA to produce certificates for this site.
  • reverse_proxy Forwards incoming requests to another server or service, so Caddy acts as an intermediary between the client and the backend server.
  • rewrite Modifies incoming requests (like URLs) before the server processes them.
  • header_down Set-Cookie Modifies the Set-Cookie headers in the server’s response to control cookies.

A DNS entry must of course be set for all defined internal names e.g.
zabbix.internal -> <caddy-webserver-ip-address>.
Here’s a post I wrote about using Pi-hole as a local DNS server.

Configuration for Zabbix

Previous access: http://192.168.0.29/zabbix
Access via Caddy: https://zabbix.internal

  • Caddyfile
    # Zabbix
    zabbix.internal {
          tls internal
          rewrite * /zabbix{uri}
          reverse_proxy 192.168.0.29 {
                  header_down Set-Cookie "/zabbix" "/"
          }
    }
    
Configuration for Gitea

Previous access: http://192.168.0.30:3000
Access via Caddy: https://gitea.internal

  • Caddyfile
    # Gitea
    gitea.internal {
          tls internal
          reverse_proxy 192.168.0.30:3000
    }
    
  • Gitea
    I also had to set SSH_DOMAIN, DOMAIN and ROOT_URL in the Gitea configuration /etc/gitea/app.ini.
    ...
    [server]
    ...
    SSH_DOMAIN = gitea.internal
    DOMAIN = gitea.internal
    ROOT_URL = https://gitea.internal
    ...
    
Configuration for Wazuh

Previous access: https://192.168.0.31/
Access via Caddy: https://wazuh.internal

  • Caddyfile
    # Wazuh
    wazuh.internal {
          tls internal
          reverse_proxy 192.168.0.31
    }
    
  • Wazuh Dashboard
    I also had to change server.port and server.ssl.enabled in the Opensearch dashboard configuration /etc/wazuh-dashboard/opensearch_dashboards.yml.
...
server.port: 80
...
server.ssl.enabled: false
...

After any changes are made to this file, the Wazuh dashboard must be restarted: systemctl restart wazuh-dashboard

Configuration for Readeck

Previous access: http://192.168.0.32/8000
Access via Caddy: https://readeck.internal

  • Caddyfile
    # Readeck
    readeck.internal {
          tls internal
          reverse_proxy 192.168.0.32:8000 {
                  header_up X-Real-IP {remote_host}
                  header_up Host {host}
          }
    }
    

    And I added the following to the [server] section of the Readeck configuration file: /etc/readeck/config.toml

    ...
    allowed_hosts = ["readeck.internal"] # Restrict access
    #trusted_proxies = ["192.168.0.28"] # Caddy reverse proxy IP - private IP range trusted per default
    #use_x_forwarded_proto = true # Forward client protocol - needed for Readeck < 0.16
    

    The Readeck service must be restarted to use the changed configuration: systemctl restart readeck

It’s also a good idea to restrict access to the servers or services from the default or productive network to Caddy and HTTPS only. You can do this by setting up local firewall rules or by putting the servers on a separate network and controlling access from there.

2024-12_Modified: Readeck 0.16 configuration changed.

Resources