2

i have nginx, php7 and http_realip_module installed.

i have 1 server that serves 2 websites.

site 1 nginx config:

server {
    ...
    location ~ \.php$ {
        include snippets/fastcgi-php.conf;
        fastcgi_pass unix:/run/php/php7.0-fpm.sock;
        fastcgi_read_timeout 300;

        proxy_set_header REMOTE_ADDR $http_x_real_ip;
        proxy_set_header X-Forwarded-For $http_x_real_ip;
    }
}

this populates the client's IP address when i dump $_SERVER['REMOTE_ADDR"].

site 1 connects to site 2 using curl like a simply api.

$ch = curl_init();
curl_setopt($ch, CURLOPT_USERAGENT, $userAgent);
curl_setopt($ch, CURLOPT_RETURNTRANSFER, true);
curl_setopt($ch, CURLOPT_POST, true);
curl_setopt($ch, CURLOPT_POSTFIELDS, $fields_string);
curl_setopt($ch, CURLOPT_URL, $serverUrl);
curl_setopt($ch, CURLOPT_HTTPHEADER, array(
    "REMOTE_ADDR: ".$_SERVER['REMOTE_ADDR'], 
    "HTTP_X_FORWARDED_FOR: ".$_SERVER['REMOTE_ADDR'],
));
$result = curl_exec($ch);

site 2 nginx config:

server {
    ...
    location ~ \.php$ {
        include snippets/fastcgi-php.conf;
        fastcgi_pass unix:/run/php/php7.0-fpm.sock;
        fastcgi_read_timeout 300;

        set_real_ip_from 127.0.0.1;
        real_ip_header    X-Forwarded-For;
        real_ip_recursive on;

    }
}

i can see that the script on site 2 gets called, but when i check the $_SERVER['REMOTE_ADDR'] variable in PHP it comes up with the server's IP address rather than the client's ip address. is the nginx setup correct here?

how can i get this to work correctly?

Ourx
  • 109
  • 3
  • 15

1 Answers1

2

After some discussion and some trial/error below, we've found the best solution was to simply pass it through a $_GET parameter.

Try using a completely custom header:

curl_setopt($ch, CURLOPT_URL, $serverUrl . '?client_ip=' . $_SERVER['REMOTE_ADDR']);

Because you're simply forwarding this variable on, it's not really necessary to try and tailor it to a header.

After even further discussion, I found that nginx strips headers with underscores by default. Simply changing the underscores to dashes allows the end host to get the headers:

curl_setopt($ch, CURLOPT_HTTPHEADER, array( 
    "X-CLIENT-REMOTE-IP: " . $_SERVER['REMOTE_ADDR']
));
Community
  • 1
  • 1
Blue
  • 22,608
  • 7
  • 62
  • 92
  • doesnt seemed to have worked? as i look further at curl, it doesnt look to be sending an headers to the site2 php page. $_SERVER variable contain the X_CLIENT_REMOTE_IP variable? – Ourx Jul 31 '16 at 01:49
  • typo: $_SERVER variable -doesnt- contain the X_CLIENT_REMOTE_IP variable – Ourx Jul 31 '16 at 01:54
  • Humor me, and do: `print_r(apache_request_headers());`. Is it in there? – Blue Jul 31 '16 at 01:55
  • Uncaught Error: Call to undefined function apache_request_headers() – Ourx Jul 31 '16 at 02:03
  • Personally, I think you should just pass it in the url, and pull it out of `$_GET`. curl_setopt($ch, CURLOPT_URL, $serverUrl . '?client_ip=' . $_SERVER['REMOTE_ADDR']); – Blue Jul 31 '16 at 02:04
  • mm.. looks like a dirty way to do it though. had no problem with the code on apache, but the nginx config is where it is stuff up. – Ourx Jul 31 '16 at 02:08
  • idk, if I'd say dirty. You're trying to pass custom data from client to server. Because curl is doing the request, you're always going to get the IP from the server that initiated the curl request. nginx forwarding really doesn't have a whole lot to do here client ip wise. As long as you secure it, so that it can't be accessed remotely, you should be fine. – Blue Jul 31 '16 at 02:11
  • I'll update my answer and put the `$_GET` discussion. If it works for you, and you're satisfied, please mark it as answered, otherwise ping back here and I'll assist further. – Blue Jul 31 '16 at 02:14
  • Why wouldn't the curl headers be set and coming through to site2? Is there some nginx config that wont allow custom headers? – Ourx Jul 31 '16 at 02:24
  • Try `curl_setopt($ch, CURLOPT_HTTPHEADER, array( "X-CLIENT-REMOTE-IP: " . $_SERVER['REMOTE_ADDR'] ));` and see if it's in the array (Might show up server side with underscores). – Blue Jul 31 '16 at 02:29
  • yes changes the underscores to dashes and the variable comes through to the site2 page – Ourx Jul 31 '16 at 02:40