Trusted Proxies with Cloudflare - my solution

Been struggling to figure out how to deal with the v2.5 changes to reverse_proxy while using Cloudflare as a cloud proxy service and figured I’d share what’s working for me in hopes that others may find it useful.

in my Caddyfile, i make use of import directive to reference a file:

        reverse_proxy IP:PORT {
                import /authdb/cloudflare-proxies
        }

i run Caddy in a docker container, so i have the /authdb/ volume mounted to the container. on the host itself, i set a cron job to run this script every 30 minutes:

#!/bin/bash

CLOUDFLARE_IPSV4="https://www.cloudflare.com/ips-v4"

FILE_IPV4="/authdb/cloudflare-proxies"

if [ -f "$FILE_IPV4" ] ; then
    rm "$FILE_IPV4"
fi

if [ -f /usr/bin/curl ]; then
        HTTP_STATUS=$(curl -sw '%{http_code}' -o $FILE_IPV4 $CLOUDFLARE_IPSV4)
        if [ "$HTTP_STATUS" -ne 200 ]; then
                echo "FAILED. Reason: unable to download IPv4 list [Status code: $HTTP_STATUS]"
                exit 1
        fi
else
        echo "FAILED. Reason: curl wasn't found on this system."
        exit 1
fi

sed -i ':a;N;$!ba;s/\n/ /g' $FILE_IPV4

sed -i '1s/^/trusted_proxies /' $FILE_IPV4

exit 0

Now, whenever I re-build my Caddy container, the “cloudflare-proxies” file is mounted with the container and the host updates that file every half hour.

Hopefully someone finds this helpful.

2 Likes

Please note that this alone is incomplete, because Cloudflare does not sanitize the X-Forwarded-For header by default, so even with this, you’re potentially vulnerable to remote IP spoofing. So you must configure Cloudflare to remove the X-Forwarded-For header, then write the header again with the source IP address, to make sure it doesn’t have untrusted values.

There’s instructions here in Authelia’s docs (not yet live on their site, so the source on Github will have to do for now):

5 Likes

Hi! Sorry to hijack this thread but is there any alternative to performing this import every time the reverse_proxy directive is used. It could also be done with a snippet and an arg but I wanted to ask if you know of any other way to have some sort of global trusted_proxies now that realip doesnt seem to work.

1 Like

There’s no global way.

Yes, you can use import with snippets.

3 Likes

GitHub - WeidiDeng/caddy-cloudflare-ip is needed

trusted_proxies cloudflare {
    interval 12h
    timeout 15s
}