클라이언트 IP 주소 얻기 : REMOTE_ADDR, HTTP_X_FORWARDED_FOR, 그 밖에 무엇이 유용할까요?
이 두 변수를 모두 살펴 보는 것이 표준 관행임을 이해합니다. 물론 쉽게 스푸핑 될 수 있습니다. 얼마나 자주 이러한 값 (특히 HTTP_X_FORWARDED_FOR
)에 실제 정보가 포함되어 있고 단순히 뒤섞이거나 값이 제거되지 않을 것으로 예상 할 수 있는지 궁금합니다 .
이 물건에 대한 경험이나 통계가있는 사람이 있습니까?
클라이언트의 IP 주소를 가져 오는 데 유용 할 수있는 다른 것이 있습니까?
사이트의 특성에 따라 다릅니다.
저는 IP 추적이 중요한 약간의 소프트웨어를 작업하고 있으며, 파트너 사이트에서 사용하는 필드 내에서 요청의 약 20 %-40 %가 시간에 따라 탐지 가능하게 스푸핑 된 IP이거나 헤더가 비워진 것으로 추측합니다. 날과 그들이 어디에서 왔는지. 유기적 트래픽이 발생하는 사이트 (즉, 파트너를 통하지 않음)의 경우 좋은 IP 비율이 훨씬 더 높을 것으로 예상됩니다.
Kosi가 말했듯이 이것으로 무엇을하는지 조심하세요. IP는 순 방문자를 식별하는 신뢰할 수있는 방법이 아닙니다.
이외에 REMOTE_ADDR
와 HTTP_X_FORWARDED_FOR
같은 설정 될 수있는 몇 가지 다른 헤더가 있습니다 :
HTTP_CLIENT_IP
HTTP_X_FORWARDED_FOR
쉼표로 구분 된 IP 목록 일 수 있습니다.HTTP_X_FORWARDED
HTTP_X_CLUSTER_CLIENT_IP
HTTP_FORWARDED_FOR
HTTP_FORWARDED
다음 사이트의 코드가 유용하다는 것을 알았습니다.
http://www.grantburton.com/?p=97
Grant Burton의 PHP 코드를 HttpRequestBase에 대해 호출 가능한 ASP.Net 정적 메서드로 이식했습니다. 선택적으로 비공개 IP 범위를 건너 뜁니다.
public static class ClientIP
{
// based on http://www.grantburton.com/2008/11/30/fix-for-incorrect-ip-addresses-in-wordpress-comments/
public static string ClientIPFromRequest(this HttpRequestBase request, bool skipPrivate)
{
foreach (var item in s_HeaderItems)
{
var ipString = request.Headers[item.Key];
if (String.IsNullOrEmpty(ipString))
continue;
if (item.Split)
{
foreach (var ip in ipString.Split(','))
if (ValidIP(ip, skipPrivate))
return ip;
}
else
{
if (ValidIP(ipString, skipPrivate))
return ipString;
}
}
return request.UserHostAddress;
}
private static bool ValidIP(string ip, bool skipPrivate)
{
IPAddress ipAddr;
ip = ip == null ? String.Empty : ip.Trim();
if (0 == ip.Length
|| false == IPAddress.TryParse(ip, out ipAddr)
|| (ipAddr.AddressFamily != AddressFamily.InterNetwork
&& ipAddr.AddressFamily != AddressFamily.InterNetworkV6))
return false;
if (skipPrivate && ipAddr.AddressFamily == AddressFamily.InterNetwork)
{
var addr = IpRange.AddrToUInt64(ipAddr);
foreach (var range in s_PrivateRanges)
{
if (range.Encompasses(addr))
return false;
}
}
return true;
}
/// <summary>
/// Provides a simple class that understands how to parse and
/// compare IP addresses (IPV4) ranges.
/// </summary>
private sealed class IpRange
{
private readonly UInt64 _start;
private readonly UInt64 _end;
public IpRange(string startStr, string endStr)
{
_start = ParseToUInt64(startStr);
_end = ParseToUInt64(endStr);
}
public static UInt64 AddrToUInt64(IPAddress ip)
{
var ipBytes = ip.GetAddressBytes();
UInt64 value = 0;
foreach (var abyte in ipBytes)
{
value <<= 8; // shift
value += abyte;
}
return value;
}
public static UInt64 ParseToUInt64(string ipStr)
{
var ip = IPAddress.Parse(ipStr);
return AddrToUInt64(ip);
}
public bool Encompasses(UInt64 addrValue)
{
return _start <= addrValue && addrValue <= _end;
}
public bool Encompasses(IPAddress addr)
{
var value = AddrToUInt64(addr);
return Encompasses(value);
}
};
private static readonly IpRange[] s_PrivateRanges =
new IpRange[] {
new IpRange("0.0.0.0","2.255.255.255"),
new IpRange("10.0.0.0","10.255.255.255"),
new IpRange("127.0.0.0","127.255.255.255"),
new IpRange("169.254.0.0","169.254.255.255"),
new IpRange("172.16.0.0","172.31.255.255"),
new IpRange("192.0.2.0","192.0.2.255"),
new IpRange("192.168.0.0","192.168.255.255"),
new IpRange("255.255.255.0","255.255.255.255")
};
/// <summary>
/// Describes a header item (key) and if it is expected to be
/// a comma-delimited string
/// </summary>
private sealed class HeaderItem
{
public readonly string Key;
public readonly bool Split;
public HeaderItem(string key, bool split)
{
Key = key;
Split = split;
}
}
// order is in trust/use order top to bottom
private static readonly HeaderItem[] s_HeaderItems =
new HeaderItem[] {
new HeaderItem("HTTP_CLIENT_IP",false),
new HeaderItem("HTTP_X_FORWARDED_FOR",true),
new HeaderItem("HTTP_X_FORWARDED",false),
new HeaderItem("HTTP_X_CLUSTER_CLIENT_IP",false),
new HeaderItem("HTTP_FORWARDED_FOR",false),
new HeaderItem("HTTP_FORWARDED",false),
new HeaderItem("HTTP_VIA",false),
new HeaderItem("REMOTE_ADDR",false)
};
}
귀하의 질문에 대한 실제 답변은 없지만 :
일반적으로 클라이언트 IP 주소에 의존하는 것은 고유 한 방식으로 클라이언트를 식별하는 데 사용할 수 없기 때문에 제 생각에는 좋은 습관이 아닙니다.
도로상의 문제는 IP가 실제로 클라이언트와 일치하지 않는 시나리오가 상당히 많다는 것입니다.
- 프록시 / 웹 필터
- Anonymizer 네트워크 (여기에서도 기회 없음)
- NAT (내부 IP는 유용하지 않음)
- ...
평균적 으로 얼마나 많은 IP 주소가 신뢰할 수 있는지에 대한 통계는 제공 할 수 없지만 주어진 IP 주소가 실제 클라이언트 주소인지 여부를 알 수있는 것은 거의 불가능합니다.
IP + "User Agent" could be a better for unique visitor.
If you're behind a proxy, you should use X-Forwarded-For
: http://en.wikipedia.org/wiki/X-Forwarded-For
It is an IETF draft standard with wide support:
The X-Forwarded-For field is supported by most proxy servers, including Squid, Apache mod_proxy, Pound, HAProxy, Varnish cache, IronPort Web Security Appliance, AVANU WebMux, ArrayNetworks, Radware's AppDirector and Alteon ADC, ADC-VX, and ADC-VA, F5 Big-IP, Blue Coat ProxySG, Cisco Cache Engine, McAfee Web Gateway, Phion Airlock, Finjan's Vital Security, NetApp NetCache, jetNEXUS, Crescendo Networks' Maestro, Web Adjuster and Websense Web Security Gateway.
If not, here are a couple other common headers I've seen:
Call the Below Action Method from your JS file (To get the ipv4 ip address).
[HttpGet]
public string GetIP()
{
IPAddress[] ipv4Addresses = Array.FindAll(
Dns.GetHostEntry(string.Empty).AddressList,
a => a.AddressFamily == System.Net.Sockets.AddressFamily.InterNetwork);
return ipv4Addresses.ToString();
}
Check after keeping Breakpoint, and use as per your requirement. Its working fine for me.
'IT Share you' 카테고리의 다른 글
열 이름으로 Pandas 데이터 프레임 결합 (0) | 2020.12.11 |
---|---|
webpack-dev-server를 사용하여 노드 익스프레스 서버 실행 (0) | 2020.12.11 |
Windows 서비스 상태에 대한 로그 파일이 있습니까? (0) | 2020.12.11 |
일치가 재귀 적이 지 않도록 .gitignore에 무언가를 추가하는 방법은 무엇입니까? (0) | 2020.12.11 |
.NET 4.0의 Entity Framework와 LINQ to SQL의 차이점은 무엇입니까? (0) | 2020.12.11 |