• Welcome to the Chevereto User Community!

    Here, users from all over the world come together to learn, share, and collaborate on everything related to Chevereto. It's a place to exchange ideas, ask questions, and help improve the software.

    Please keep in mind:

    • This community is user-driven. Always be polite and respectful to others.
    • Support development by purchasing a Chevereto license, which also gives you priority support.
    • Go further by joining the Community Subscription for even faster response times and to help sustain this space
  • Chevereto Support CLST

    Support response

    Support checklist

    • Got a Something went wrong message? Read this guide and provide the actual error. Do not skip this.
    • Confirm that the server meets the System Requirements
    • Check for any available Hotfix - your issue could be already reported/fixed
    • Read documentation - It will be required to Debug and understand Errors for a faster support response

Cloudflare in front of a reverse proxy (load balance) will always return the proxy IP, not client.

Status
Not open for further replies.

SlowShip

Chevereto Member
Hello,

After having looked into the source code closely. I think the script ignore Cloudflare settings, and if it sees HTTP_CF_CONNECTING_IP, it will automatically equal REMOTE_ADDR and ignore the X-REAL-IP or X-FORWARDED-FOR header from the load balancer (in my particular case, I append both header from nginx)

Reproducible step:
0. Of course, having a working chevereto up and running.
1. Setup a nginx reverse proxy (or load balance).
2. Make sure the reverse proxy return the true IP of the client while connecting through it (a small php that return REMOTE_ADDR will confirm this)
3. Put everything behind Cloudflare (or enable Cloudflare)
4. Upload something, the app will return the reverse proxy /loadbalance IP instead of the true REMOTE_ADDR

Can you re-write the script so that it will be return value like X-REAL-IP or X-FORWARDED-FOR (if exist) and not just HTTP_CF_CONNECTING_IP ?
Even better yet, have a setting so that we can disable this behavior as a proper webserver config wouldn't need chevereto to intervene like this and will just return REMOTE_ADDR
 
You are right, the script used to rely on basic conditionals to overwrite REMOTE_ADDR:

Code:
// Fix CloudFlare REMOTE_ADDR
if (isset($_SERVER['HTTP_CF_CONNECTING_IP'])) {
    $_SERVER['REMOTE_ADDR'] = $_SERVER['HTTP_CF_CONNECTING_IP'];
}
^ This one turns REMOTE_ADDR = HTTP_CF_CONNECTING_IP

Code:
    // Cloudflare REMOTE_ADDR workaround
    if (Settings::get('cloudflare') or isset($_SERVER['HTTP_CF_CONNECTING_IP'])) {
        if (isset($_SERVER['HTTP_CF_CONNECTING_IP'])) {
            $_SERVER['REMOTE_ADDR'] = $_SERVER['HTTP_CF_CONNECTING_IP'];
        }
    }
^ This one does the same thing.

If you comment the codes above, you should get the real IP under your setup.

Since long ago the system now uses G\get_client_ip() to return the real IP. That function looks like this:

Code:
    function get_client_ip()
    {
        $client_ip = !empty($_SERVER['REMOTE_ADDR']) ? $_SERVER['REMOTE_ADDR'] : (!empty($_ENV['REMOTE_ADDR']) ? $_ENV['REMOTE_ADDR'] : null);

        if (array_key_exists('HTTP_CF_CONNECTING_IP', $_SERVER) && $_SERVER['HTTP_CF_CONNECTING_IP'] == $_SERVER['REMOTE_ADDR']) {
            return $_SERVER['HTTP_CF_CONNECTING_IP'];
        }

        if (isset($_SERVER['HTTP_X_FORWARDED_FOR'])) {
            $entries = preg_split('/[\s,]/', $_SERVER['HTTP_X_FORWARDED_FOR'], -1, PREG_SPLIT_NO_EMPTY);

            reset($entries);

            foreach ($entries as $entry) {
                $entry = trim($entry);
                if (preg_match('/^([0-9]+\.[0-9]+\.[0-9]+\.[0-9]+)/', $entry, $ip_list)) {
                    $private_ip = array(
                          '/^0\./',
                          '/^127\.0\.0\.1/',
                          '/^192\.168\..*/',
                          '/^172\.((1[6-9])|(2[0-9])|(3[0-1]))\..*/',
                          '/^10\..*/');

                    $found_ip = preg_replace($private_ip, $client_ip, $ip_list[1]);
                    if ($client_ip != $found_ip) { //  and !isset($_SERVER['HTTP_CF_CONNECTING_IP']
                        $client_ip = $found_ip;
                        break;
                    }
                }
            }
        }

        return $client_ip;
    }

^ This one addresses the HTTP_X_FORWARDED_FOR, but since the other code changed REMOTE_ADDR, the rest of the code never gets executed.

I will patch this in the next revision.
 
Last edited:
Status
Not open for further replies.
Back
Top