Be careful of server configurations where for example on Rackspace, the _SERVER[ REMOTE_IP ] which is usually the users IP address, is actually a load bearing proxy server.
However the REMOTE_IP header is really the only non-spoofable header in terms of the users real ip.
HTTP_X_CLUSTER_CLIENT_IP and HTTP_X_FORWARDED_FOR ( to name a few ) for example can all be spoofed by an attacker/attack system.
Many of the CMS addon security plugins I have looked at that attempt to filter inputs using a cascade approach of potential headers then ban the IP address of bad requests, tend to stack most of the common client or proxy sent headers first, the REMOTE_ADDR being the last on the list, this for an attacker is trivial to bypass, so in effect the entire application then becomes pointless since a new client ip address can be potentially sent with each rogue request.
Banning the wrong IP address in a clustered configuration could result in your website becoming banned, and allowing spoofed IPs to be banned can allow an attacker to send a spoofed IP of the webserver or an upline proxy to the webserver which results in the same effect.
Or where whitelisted IPs are used, the attacker could also send the rogue requests with the whitelisted IP.
The best method I have come up with in these situations is:
Where there are other headers present other than the REMOTE_IP, rule number one is always filter them to make sure those headers actually contain an IP address, then yes use those to determine the users IP address, however disable ip banning ( if it is being employed ) in that instance, and just go with a 403 header and page die() call to block an actual rogue request rather than actually ban the ip address.
Afterall it is the rogue request you are wanting to prevent completing more than anything else. Banning IP addresses is more of an issue where an attacker is hammering your site via multiple anonymous proxy servers in order to create a denial of service.