問題:
用Laravel的$request->getClientIp()方法獲取IP荣赶,
本機nginx proxy 獲取到的是docker網(wǎng)絡的Ip地址苗傅,類似172.17.0.1之流(docker創(chuàng)建的網(wǎng)絡,本機的IP不是127.0.0.1)
另外一臺機器用nginx proxy 獲取到的是機器本身的外網(wǎng)IP
都無法獲取客戶的真實訪問IP
原因:
查看laravel的getClientIp方法源碼
public function getClientIps()
{
$clientIps = array();
$ip = $this->server->get('REMOTE_ADDR');
if (!$this->isFromTrustedProxy()) {
return array($ip);
}
$hasTrustedForwardedHeader = self::$trustedHeaders[self::HEADER_FORWARDED] && $this->headers->has(self::$trustedHeaders[self::HEADER_FORWARDED]);
$hasTrustedClientIpHeader = self::$trustedHeaders[self::HEADER_CLIENT_IP] && $this->headers->has(self::$trustedHeaders[self::HEADER_CLIENT_IP]);
if ($hasTrustedForwardedHeader) {
$forwardedHeader = $this->headers->get(self::$trustedHeaders[self::HEADER_FORWARDED]);
preg_match_all('{(for)=("?\[?)([a-z0-9\.:_\-/]*)}', $forwardedHeader, $matches);
$forwardedClientIps = $matches[3];
$forwardedClientIps = $this->normalizeAndFilterClientIps($forwardedClientIps, $ip);
$clientIps = $forwardedClientIps;
}
if ($hasTrustedClientIpHeader) {
$xForwardedForClientIps = array_map('trim', explode(',', $this->headers->get(self::$trustedHeaders[self::HEADER_CLIENT_IP])));
$xForwardedForClientIps = $this->normalizeAndFilterClientIps($xForwardedForClientIps, $ip);
$clientIps = $xForwardedForClientIps;
}
if ($hasTrustedForwardedHeader && $hasTrustedClientIpHeader && $forwardedClientIps !== $xForwardedForClientIps) {
throw new ConflictingHeadersException('The request has both a trusted Forwarded header and a trusted Client IP header, conflicting with each other with regards to the originating IP addresses of the request. This is the result of a misconfiguration. You should either configure your proxy only to send one of these headers, or configure Symfony to distrust one of them.');
}
if (!$hasTrustedForwardedHeader && !$hasTrustedClientIpHeader) {
return $this->normalizeAndFilterClientIps(array(), $ip);
}
return $clientIps;
}
1. remote_addr的值在經(jīng)過proxy后變成了進行proxy的機器的ip探遵,不再是客戶真實的ip了;
2. isFromTrustedProxy判斷了proxy的remote_addr番挺,要把remote_addr寫入白名單;
3. 經(jīng)過proxy的ip獲取的是X-Forwarded-For的值;
解決辦法:
- nginx設置X-Forwarded-For
server {
listen 80;
server_name www.XXXXX.cn;
location / {
proxy_pass http://XX.XX.XX.XX;
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
}
}
- laravel添加TrustedProxy
通過Request::setTrustedProxies()方法設置姆坚;傳入ip數(shù)組
可以是掩碼的格式,例如:
[
"172.17.0.1/16",
"156.132.44.23"
]