Mod_remoteip does not just log original IP, it changes how apache interprets the IP entirely

I use .htaccess to only allow traffic from Cloudflare to my Cloudflare enabled domains.

It works, yay.

But now my logs are showing the proxied IP.

Un-yay.

We thought the mod_remoteip mod would help. But it literally changes how centos see’s the ip, and now access to my sites, with this .htaccess mod is blocked. Because now the ips are unhidden, and .htaccess says ONLY allow Cloudflare ip’s.

These sites are getting ddosed, through Cloudflare, and I can’t see their IP, to try and block them. I only see the Cloudflare ip.

Ideas?

This sounds like you did not update your LogFormat Directive to use the Client IP address of the request and are still logging the Remote hostname instead. When HostnameLookups is set to Off, which is the default, Remote hostname logs the IP address, which will be the Cloudflare proxy IP.

See step 3 in Restoring original visitor IPs. The Apache documentation on Custom Log Formats for mod_log_config is a helpful reference, too.

1 Like

@epic.network Thank you for a quick response.

But I don’t think that changes the fact that this mod is changing how apache interprets the IP entirely. Or am I mistaken? Where as I don’t want apache to ONLY see the origin IP, I ONLY want apache to just log the origin ip. But this mod is not making that possible from what I can tell.

That’s not been my experience. I have access restrictions that allow HTTP basic authentication to be bypassed from specific locations, defined by IP addresses, on sites that are behind Cloudflare. I have mod_remoteip configured to recognize Clouflare IPs as the trusted proxy addresses. The apache server correctly distinguishes the client location and only prompts for authentication when accessed from outside of the trusted IPs. When I view apache access logs on my proxied sites, I see the visitor’s actual IP.

It doesn’t just work on its own. It requires changes to your server logging directives in addition to configuring mod_remoteip. My previous reply included links to the relevant documentation so you can check all of your sever configs to make sure all of the required changes have been completed. Verifying those settings is where I would start if I was trying to solve this on a client’s system.

1 Like

For anyone having this issue, I found out you can update the apache logging format, or use this custom php script to see the origin IP, without having to use the mod_remoteip mod.

The apache logformat update is this.

%h %l %u %t \"%r\" %>s %b \"%{Referer}i\" \"%{User-Agent}i\" \"%{Cf-Connecting-Ip}i\"

I created this PHP script to log the origin IP, and request URL to a non public log. For use within wordpress, or extract the code for general php use.

This logs get and post requests.

Put this in your function.php within your child theme

wp_enqueue_scripts( 'custom_logs' );

function custom_logs($message) { 
    if(is_array($message)) { 
        $message = json_encode($message); 
    } 
    $file = fopen("../farequests.txt","a"); 
    $bytes = fwrite($file, "\n" . date('Y-m-d h:i:s') . " : " . $message); 
    fclose($file); 
	return $bytes;
}

$actual_link = (isset($_SERVER['HTTPS']) && $_SERVER['HTTPS'] === 'on' ? "https" : "http") . "://$_SERVER[HTTP_HOST]$_SERVER[REQUEST_URI]";
foreach (getallheaders() as $name => $value) {
	if ($name == "Cf-Connecting-Ip") {
		$cur_hd = "ORIGIN IP: $value";
		custom_logs($cur_hd);
	}
}

if ($_SERVER["REQUEST_METHOD"] == "GET") {
    $get = "GET: ".$actual_link."\n";
    custom_logs($get);
}

if ($_SERVER["REQUEST_METHOD"] == "POST") {
   $word = '';
    foreach($_POST as $key=>$value) {
        $word.="$key=$value"." " ;
    }    
    $word.= "URL: ".$actual_link;
    custom_logs("POST: ".$word."\n");
}

This will log lines such as this,

2022-06-28 03:06:11 : ORIGIN IP: 1.1.1.1 REQUEST: https://domain.com/?wp_scrape_key=blah

For apache/cpanel, It gets placed in /home/domainname/LOGFILENAME.txt

1 Like

not a great way to do it, do this instead:

  1. Turn on “Authenticated Origin Pulls” for all your domains in the dashboard (safe to turn on even if you haven’t set it up server-side yet), in SSL/TLS → Origin Server

  2. Download Cloudflare’s authenticated_origin_pull_ca.pem and put it on your server

  3. Add to global Apache config:
    SSLCACertificateFile /etc/apache2/authenticated_origin_pull_ca.pem

  4. Add to all your Cloudflare-only vhosts: SSLVerifyClient require

  5. Restart apache

2 Likes

I use iptables to restrict port 80/443 connections to Cloudflare IPs on hosts that only serve content through the Cloudflare proxy. I do like the AOP strategy, though, especially since you can configure it in a vhost directive instead of globally if you have some vhosts on the server that are not using Cloudflare.

1 Like

@user4358 Thanks for the advice. Can you tell me the pros and cons of this solution you provided, vs the .htaccess solution?

Also, this certificate, I have to download for every Cloudflare site, right? Which means I’d have like 70 certificates.

Requiring a client certificate will shutdown non-Cloudflare connections immediately during the SSL handshake phase, with no need to read your htaccess file from disk. htaccess is notorious for increasing disk activity and thus lowering server performance. Blocking through htaccess is still letting the traffic in and answering it, just answering it with an error page instead of the requested content, so it doesn’t necessarily reduce load on your server. You also won’t have to worry about blocking legitimate traffic every time Cloudflare adds a new IP range.

Possible cons? Since the bad connections attempts are killed in OpenSSL before reaching “proper” Apache, they don’t show up in Apache logs. This can be good or bad, since logging does consume resources. It might be possible to log them somehow but I haven’t bothered trying.

Just one, download the .pem from here: Set up Authenticated Origin Pulls · Cloudflare SSL/TLS docs

(hence why I said to put it in your global config instead of your vhost config)

2 Likes

Even in the vhost config, you can still use the same path to a single certificate file. One important thing to take into consideration is that @user4358 and I are both likely operating under the assumption that you control the entire server and are not in a shared hosting scenario.

If you all sites on the server behind Cloudflare, updating the global config is definitely the superior choice.

1 Like

Yes I do manage the entire server. But not all of them are behind Cloudflare. So vhosts sounds like the better option.

Thanks!

I successfully implemented this on two VPS hosts today, one using each method. It was as diificult as you might expect: not at all.:smile:

Enjoy and good luck!

1 Like

This topic was automatically closed 3 days after the last reply. New replies are no longer allowed.