2023-11-19T17:40:58.285299727-tqgw.svg

Caddy2 是一个开源的现代化的 Web 服务器,它以简单易用、高度可定制和自动化的特性而闻名。Caddy2 提供了很多强大的功能,如自动 HTTPS、HTTP/3、反向代理、日志、认证、插件化等,并且使用 Go 语言编写。

自建防挨打Caddy2镜像

Dockerfile

FROM caddy:2.7.5-builder-alpine AS builder

RUN xcaddy build \
    --with github.com/RussellLuo/caddy-ext/ratelimit

FROM caddy:2.7.5-alpine

COPY --from=builder /usr/bin/caddy /usr/bin/caddy

制作扩展镜像

 docker build -t caddy ./

限流扩展:http://github.com/RussellLuo/caddy-ext/ratelimit

以上为官方自建加扩展的方法。

docker-compse

  caddy:
    image: caddy
    container_name: caddy
    restart: unless-stopped
    network_mode: host
    #ports:
    #  - '443:443'
    #  - '80:80'
    #  - '2019:2019'
    volumes:
      - /data/caddy/data:/data
      - /data/caddy/Caddyfile:/etc/caddy/Caddyfile

翻车记录1:2019端口不知道什么原因宿主机怎么都访问不到,无奈将网络改成了host模式。

2019端口无法被访问到,原因:caddy启动后开启127.0.0.1:2019端口,无法被宿主机访问到,修改配置后正常访问。

翻车记录二:remote.ip 只能取到docker网关的IP,这样导致所有客户端IP的请求变成一个IP,所有客户端使用一个限流IP是不正确的,最快的修复方式是网络使用host模式。

配置文件

文件路径:/data/caddy/Caddyfile

(security_headers) {
    header * {
        # enable HSTS
        # https://cheatsheetseries.owasp.org/cheatsheets/HTTP_Headers_Cheat_Sheet.html#strict-transport-security-hsts
        # NOTE: Read carefully how this header works before using it.
        # If the HSTS header is misconfigured or if there is a problem with
        # the SSL/TLS certificate being used, legitimate users might be unable
        # to access the website. For example, if the HSTS header is set to a
        # very long duration and the SSL/TLS certificate expires or is revoked,
        # legitimate users might be unable to access the website until
        # the HSTS header duration has expired.
        # The recommended value for the max-age is 2 year (63072000 seconds).
        # But we are using 1 hour (3600 seconds) for testing purposes
        # and ensure that the website is working properly before setting
        # to two years.

        Strict-Transport-Security "max-age=3600; includeSubDomains; preload"

        # disable clients from sniffing the media type
        # https://cheatsheetseries.owasp.org/cheatsheets/HTTP_Headers_Cheat_Sheet.html#x-content-type-options
        X-Content-Type-Options "nosniff"

        # clickjacking protection
        # https://cheatsheetseries.owasp.org/cheatsheets/HTTP_Headers_Cheat_Sheet.html#x-frame-options
        X-Frame-Options "DENY"

        # xss protection
        # https://cheatsheetseries.owasp.org/cheatsheets/HTTP_Headers_Cheat_Sheet.html#x-xss-protection
        X-XSS-Protection "1; mode=block"

        # Remove -Server header, which is an information leak
        # Remove Caddy from Headers
        -Server

        # keep referrer data off of HTTP connections
        # https://cheatsheetseries.owasp.org/cheatsheets/HTTP_Headers_Cheat_Sheet.html#referrer-policy
        Referrer-Policy strict-origin-when-cross-origin
    }
}

{
    #设置端口为0.0.0.0:2019,使端口可以被宿主机访问到。
    admin :2019
    #开启prometheus监控指标
    servers {
        metrics
    }
}

xxx.xxx.com:443 {
    import security_headers
    route /* {
        #允许IP一秒钟访问10次,超过返回401
        rate_limit {remote.ip} 10r/s 10000 401
        reverse_proxy /* 192.168.0.2:80
        reverse_proxy /* 192.168.0.3:80
    }
    log {
        output file /data/caddy/logs/access.log {
            roll_size     100MiB
            roll_keep     30
            roll_keep_for 24h
        }
        format json {
            time_format "iso8601"
        }
    }
}

限流语法

rate_limit [<matcher>] <key> <rate> [<zone_size> [<reject_status>]]

Parameters:

  • <key>: The variable used to differentiate one client from another. Currently supported variables (Caddy shorthand placeholders):

    • {path.<var>}

    • {query.<var>}

    • {header.<VAR>}

    • {cookie.<var>}

    • {body.<var>} (requires the requestbodyvar extension)

    • {remote.host} (ignores the X-Forwarded-For header)

    • {remote.port}

    • {remote.ip} (prefers the first IP in the X-Forwarded-For header)

    • {remote.host_prefix.<bits>} (CIDR block version of {remote.host})

    • {remote.ip_prefix.<bits>} (CIDR block version of {remote.ip})

  • <rate>: The request rate limit (per key value) specified in requests per second (r/s) or requests per minute (r/m).

  • <zone_size>: The size (i.e. the number of key values) of the LRU zone that keeps states of these key values. Defaults to 10,000.

  • <reject_status>: The HTTP status code of the response when a client exceeds the rate limit. Defaults to 429 (Too Many Requests).

详见文档:https://github.com/RussellLuo/caddy-ext/tree/master/ratelimit

黑白名单控制

白名单

test.example.com {
    @ip_whitelist {
        remote_ip 192.168.1.9 172.16.0.0/12
    }

    route @ip_whitelist {
        file_server browse
    }

    respond "Blocked" 403
}

黑名单

test.example.com {
    @ip_blacklist {
        remote_ip 192.168.1.9 172.16.0.0/12
    }

    route @ip_blacklist {
        respond "Blocked" 403
    }

    file_server browse
}

复杂点带auth认证

@ip_blacklist {
    remote_ip 192.168.1.9 172.16.0.0/12
}

route {
    respond @ip_blacklist "Blocked" 403
    basicauth * {
        Bob JDJhJDEwJEVCNmdaNEg2Ti5iejRMYkF3MFZhZ3VtV3E1SzBWZEZ5Q3VWc0tzOEJwZE9TaFlZdEVkDhX
    }
    file_server browse
}

监控配置

curl localhost:2019/metrics

访问本地2019端口地址,返回prometheus监控指标数据说明配置成功

prometheus.yml

 - job_name: 'caddy'
    static_configs:
    - targets: ['IP:2019']

告警规则

暂无

grafana模版

https://grafana.com/grafana/dashboards/14280-caddy-exporter/

相关文档

https://grafana.com/docs/grafana-cloud/monitor-infrastructure/integrations/integration-reference/integration-caddy/

https://caddyserver.com/docs/caddyfile/directives/metrics

https://github.com/caddyserver/caddy

https://hub.docker.com/_/caddy