Getting a visitor's IP on a mirrored server

RJM62

Touchdown! Greaser!
Joined
Jun 15, 2007
Messages
13,157
Location
Upstate New York
Display Name

Display name:
Geek on the Hill
My present hosting is mirrored for redundancy. The mirroring works well, but I've noticed a side effect that I'm trying to work around.

The way the system works is that all traffic is routed first to the slave server. The slave queries the master and, if the master is online and healthy, forwards all requests to the master. If the master goes down, then the slave processes the requests itself until the master is back online.

Some of my applications (like the spam-filtering form) grab the visitor's IP address. But because of the way this server is set up, all I get is the IP of the slave server.

Now, I know that it's possible to grab the actual user's IP because my stats software and firewall do it. But when using my own PHP scripts, $_SERVER['REMOTE_ADDR'] returns the slave server's public IP address, and $_SERVER['HTTP_X_FORWARDED_FOR'] returns an empty result.

Anyone have any ideas?

-Rich
 
Would it be possible to grab the user's IP at the slave site before they are redirected to the master site and save the IP as a session variable. Then it's just a matter of pulling the session variable back into the script later.
 
Would it be possible to grab the user's IP at the slave site before they are redirected to the master site and save the IP as a session variable. Then it's just a matter of pulling the session variable back into the script later.

Probably, but the code would have to be inserted somewhere in the scripts that actually do the mirroring, because pretty much everything else is overwritten by the changes I make on the master server.

I didn't write the mirroring scripts, and I'm hesitant to poke around in them too much if I can avoid it.

Rich
 
The question is - what do you use the IP address for? There are so many firewalls/proxies/NAT devices between the typical end user and you that the source IP is practically useless for tracing purposes.

If you use the IP address for any sort of persistence/state information, consider having your application set a unique session cookie instead.
 
The question is - what do you use the IP address for? There are so many firewalls/proxies/NAT devices between the typical end user and you that the source IP is practically useless for tracing purposes.

If you use the IP address for any sort of persistence/state information, consider having your application set a unique session cookie instead.

In this case, for two reasons:

1. As one in a redundant series of tests to prove that the computer submitting form data is the same computer that loaded the form. This is trivial, as there are many other tests I can use to do that.

2. More important, but still not absolutely necessary: IPs that repeatedly attempted to send spam through my forms were added to a temporary list. Early on in the script, the remote IP would be compared to the IPs in that list, and matches immediately sent to the success page to save resources.

I know this sounds a bit strange. The idea is that spammy submissions also land on the success page; but the rest of the scripts never run, the mail is never sent, and the spammer (whether human or bot) has no easy way of knowing that his/its submission was discarded.

This is not really essential. The spam detection is redundant. It was just a nice extra that I'd like to add back if I can.

-Rich
 
A little thread creep, but here's a non-ip way I verify that the submitter actually loaded the form (using PHP):

On the form page:

PHP:
// this sets a random value and its hash so the next script knows the data was sent from the form
unset ($peekaboo);
unset($_SESSION['peekaboo']);
unset($_SESSION['show_me']);
$peekaboo = $_SESSION['peekaboo'] = rand(10000, 99999);
$_SESSION['show_me'] = md5($peekaboo);
On the processing page:

PHP:
// did user get here from form page?
$peekaboo = $_SESSION['peekaboo'];
$show_me = $_SESSION['show_me'];
$its_you = md5($peekaboo);
If I want to land the spammer on the success page:

PHP:
if ($show_me !== $its_you)
     {
     print "<meta http-equiv=\"refresh\" content=\"0;URL=sent.php\">";
     die;
}
If I merely want to tag it spammy:

PHP:
if ($show_me !== $its_you) { $is_legit=false; }

It's absurdly simple, but it seems to work pretty well at preventing spammers from bypassing the form.

-Rich
 
/creep

Like I said, I want the IP mainly so I can temporarily divert abusive IPs without wasting resources running the rest of the scripts. The firewall will catch and block them eventually, though, so it's really not imperative.

-Rich
 
In this case, for two reasons:

1. As one in a redundant series of tests to prove that the computer submitting form data is the same computer that loaded the form. This is trivial, as there are many other tests I can use to do that.

2. More important, but still not absolutely necessary: IPs that repeatedly attempted to send spam through my forms were added to a temporary list. Early on in the script, the remote IP would be compared to the IPs in that list, and matches immediately sent to the success page to save resources.

I know this sounds a bit strange. The idea is that spammy submissions also land on the success page; but the rest of the scripts never run, the mail is never sent, and the spammer (whether human or bot) has no easy way of knowing that his/its submission was discarded.

This is not really essential. The spam detection is redundant. It was just a nice extra that I'd like to add back if I can.

-Rich

I see, and that makes sense.
 
How are you forwarding the request? I'd suggest modifying the original request's HTTP header (for any requests you forward) and append an x-forwarded-for entry:

http://en.wikipedia.org/wiki/X-Forwarded-For

Actually, I already have X-Forwarded-For enabled in Apache, so it should sort those things out. And it returned an empty result in any case.

Trying to t/s this, however, I put up a test page consisting of nothing but

PHP:
<?php
session_start();
echo $_SERVER['REMOTE_ADDR'];
?>

and it returned my true IP. But in the apps, $_SERVER['REMOTE_ADDR'] was still returning the slave server's IP. Then just for kicks, I reference my test file via an include, and it returned my real IP. But if I moved the test file into the same directory as the script and ran it, it returned the slave server's IP.

So for whatever reason, it pulls the remote IP when the file is in the root, but not when in the same directory as the script it's included from. I have no idea why this should be, or if its just coincidence for that matter.

At least it gives me something to burn coffee over at night, though.

-Rich
 
Back
Top