通过 PHP 检测带有代理服务器的客户端
声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow
原文地址: http://stackoverflow.com/questions/858357/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me):
StackOverFlow
Detect clients with Proxy Servers via PHP
提问by MichaelICE
I'm looking for a method, or a way to detect clients using any type of proxy server viewing my web site. I'm using PHP/Apache... what's the best way to do this? Any proxy server would need to be detected, not specifically one or the other.
我正在寻找一种方法,或者一种使用任何类型的代理服务器查看我的网站来检测客户端的方法。我正在使用 PHP/Apache ......什么是最好的方法来做到这一点?任何代理服务器都需要被检测到,而不是特定的一个或另一个。
Edit
编辑
I am more interested in the anonymous proxies... as the normal ones are easily detected by looking for HTTP_X_FORWARDED_FOR.
我对匿名代理更感兴趣......因为通过查找HTTP_X_FORWARDED_FOR.
Another Edit
另一个编辑
Try this:
尝试这个:
1) go to http://kproxy.com(or any other free anonymous proxy site)
1)去http://kproxy.com(或任何其他免费的匿名代理网站)
2) visit: http://www.worldofwarcraft.com
2)访问:http: //www.worldofwarcraft.com
3) they are able to block somehow, as the page errors out with "Error loading stylesheet: A network error occurred loading an XSLT stylesheet:http://kproxy.com/new-hp/layout/layout.xsl"
3)他们能够以某种方式阻止,因为页面错误显示“错误加载样式表:加载 XSLT 样式表时发生网络错误:http: //kproxy.com/new-hp/layout/layout.xsl”
I want to do something similar to prevent proxies.
我想做类似的事情来防止代理。
采纳答案by TomHastjarjanto
You can't detect that unless they pass on special headers which explictly mention it like X-Forwarded-For or something.
你无法检测到,除非他们传递特殊的标头,这些标头明确地提到它,比如 X-Forwarded-For 或其他东西。
As far as I know you have to use a blacklist. Users who use putty portforwarding, VPN or other more sophisticated methods are undetactable as they behave exactly like normal users.
据我所知,您必须使用黑名单。使用 putty 端口转发、VPN 或其他更复杂方法的用户是不可攻击的,因为他们的行为与普通用户完全一样。
回答by X-Ray
Use the following 2 solutions in PHP. // method 1 = quick but does not work with anonymous proxies
在 PHP 中使用以下 2 个解决方案。// 方法 1 = 快速但不适用于匿名代理
$proxy_headers = array(
'HTTP_VIA',
'HTTP_X_FORWARDED_FOR',
'HTTP_FORWARDED_FOR',
'HTTP_X_FORWARDED',
'HTTP_FORWARDED',
'HTTP_CLIENT_IP',
'HTTP_FORWARDED_FOR_IP',
'VIA',
'X_FORWARDED_FOR',
'FORWARDED_FOR',
'X_FORWARDED',
'FORWARDED',
'CLIENT_IP',
'FORWARDED_FOR_IP',
'HTTP_PROXY_CONNECTION'
);
foreach($proxy_headers as $x){
if (isset($_SERVER[$x])) die("You are using a proxy!");
}
// Method 2 = portscan back to the origin IP at the normal proxy ports used.
// 方法 2 = portscan 回到使用的普通代理端口的原始 IP。
$ports = array(8080,80,81,1080,6588,8000,3128,553,554,4480);
foreach($ports as $port) {
if (@fsockopen($_SERVER['REMOTE_ADDR'], $port, $errno, $errstr, 30)) {
die("You are using a proxy!");
}
}
回答by Kornel
Metasploituses lots of different techniques to force client's system to make direct connection (vulnerabilities/misfeatures in Flash, Java, QuickTime, MS Office, custom DNS server).
Metasploit使用许多不同的技术来强制客户端的系统进行直接连接(Flash、Java、QuickTime、MS Office、自定义 DNS 服务器中的漏洞/错误功能)。
Alternatively, if you can't get client's browser to launch metasploit, you could try to look for open proxies (port scanning) and known Tor exit nodes.
或者,如果您无法让客户端的浏览器启动 metasploit,您可以尝试查找开放代理(端口扫描)和已知的 Tor 出口节点。
But please don't assume that proxies are evil and need to be blocked – there are plenty of legitimate proxies and some users have to use them.
但请不要假设代理是邪恶的,需要被阻止——有很多合法的代理,有些用户必须使用它们。
If you have trouble with spam or other abusive traffic then just blocking of proxies won't help much. You should look for specific solutions that address core of the problem (spam filters, IDS) rather than assuming anonymous = guilty.
如果您遇到垃圾邮件或其他滥用流量的问题,那么仅阻止代理将无济于事。您应该寻找解决问题核心(垃圾邮件过滤器、IDS)的特定解决方案,而不是假设匿名 = 有罪。
回答by S W
There are various paid / free solutions. Most of them looks at the client IP trying to connect to determine if they're on a proxy or not.
有各种付费/免费解决方案。他们中的大多数人查看尝试连接的客户端 IP 以确定它们是否在代理上。
Paid:
Maxmind- They focus on fraud detection and have a sub-category for proxy detection. Note that this is now considered as a "legacy" service.
付费:
Maxmind- 他们专注于欺诈检测,并有一个用于代理检测的子类别。请注意,这现在被视为“传统”服务。
Free:
W I T C H- Able to detect OpenVPN by looking at MSS values that are uniquely identifiable. The code is available on github.
免费:
WITCH- 能够通过查看唯一可识别的 MSS 值来检测 OpenVPN。代码可在 github 上找到。
GetIpIntel- Proxy / VPN detection using machine learning, queries via API.
GetIpIntel- 使用机器学习的代理 / VPN 检测,通过 API 查询。
There are a few more free options listed on security stack exchange.
安全堆栈交换上列出了更多免费选项。
回答by Fabrizio
Old topic, but I might have figured something out.
老话题,但我可能已经想通了。
It is live on my site and I think it might work for most cases.
它在我的网站上直播,我认为它可能适用于大多数情况。
My problem was that banned user were coming back to my site and re-registering with a new email address using one of the many proxies that you can find. What I have done is a simple jQuery call on the registration/login form:
我的问题是被禁止的用户返回我的网站并使用您可以找到的众多代理之一使用新的电子邮件地址重新注册。我所做的是在注册/登录表单上进行简单的 jQuery 调用:
<form id="login_form" method="post" action="/#fake_login_url">
stuff you need for the form
</form>
<script>
$('#login_form').attr('action','real_login_form');
</script>
回答by guerda
Everything that the client passes to the server can be self-configured. You cannot trust anything, except for an IP address. So you cannot check the header data, if it's a proxy or a normal client.
By the way: It's the intention of a proxy not to show being a proxy :)
客户端传递给服务器的所有内容都可以自行配置。除了 IP 地址之外,您不能信任任何东西。因此,如果它是代理或普通客户端,则无法检查标头数据。
顺便说一句:代理的意图是不显示为代理:)
For sure, you could take the requester's IP address and send a http request you would send to a proxy. If it reacts, it may be a proxy otherwise, it's a normal client. This method would be very expensive and not reliable. If the proxy your server requested was behind a firewall, you would get no answer and think that it is a normal client.
当然,您可以获取请求者的 IP 地址并发送您将发送给代理的 http 请求。如果它有反应,它可能是一个代理,否则它是一个普通的客户端。这种方法将非常昂贵且不可靠。如果您的服务器请求的代理位于防火墙后面,您将得不到答复并认为它是一个普通客户端。
回答by araqnid
I think that what's happening here is some client-side JavaScript is trying to load something, and that can "see" that the page is being viewed inside a frame. That might be a more fruitful avenue to explore- as other answers have indicated, proxies intentionally make it hard to determine just from the server alone.
我认为这里发生的事情是一些客户端 JavaScript 正在尝试加载某些内容,并且可以“看到”正在框架内查看页面。这可能是一个更有成效的探索途径 - 正如其他答案所表明的那样,代理故意使仅从服务器上确定变得困难。
回答by Peter
Even if it's an old question, I've had to check for proxy and unfortunatly none of the answers give good result.
即使这是一个老问题,我也不得不检查代理,不幸的是没有一个答案给出好的结果。
After searching, I've found a better method. In order to understand this way of doing, just create a small page with this code:
经过搜索,我找到了一个更好的方法。为了理解这种方式,只需使用以下代码创建一个小页面:
<?php
foreach ($_SERVER as $key => $val)
{
echo $key."<br>\n";
}
?>
Run it direclty from your server. You'll see all keys from the header your server is sending. Then run the same script through a Proxy. You'll see (depending on the Proxy) 3 possible results:
从您的服务器直接运行它。您将看到服务器发送的标头中的所有密钥。然后通过代理运行相同的脚本。您将看到(取决于代理)3 种可能的结果:
- the Proxy add news keys/values
- the Proxy don't send all the original keys/values so some are missing.
- the Proxy send exactly the same keys/values but not in same order
- the Proxy send exactly the same keys/values, in same order
- 代理添加新闻键/值
- 代理不会发送所有原始键/值,因此缺少一些。
- 代理发送完全相同的键/值,但顺序不同
- 代理以相同的顺序发送完全相同的键/值
The 4th case can happen but others are the most frequent. So you just have to create an array with the key/value from your server (based on the result when you run the script without a Proxy) and compare the keys/values from $_SERVER. If you don't have exacty the same keys/values (less, more or in other order) you can assume the page came from a Proxy.
第 4 种情况可能发生,但其他情况最常见。因此,您只需要使用来自您的服务器的键/值创建一个数组(基于您在没有代理的情况下运行脚本时的结果)并比较来自 $_SERVER 的键/值。如果您没有完全相同的键/值(更少、更多或其他顺序),您可以假设该页面来自代理。
Notice I agree with those saying in some cases Proxy can be use in a "legal".
请注意,我同意在某些情况下可以在“合法”中使用代理的说法。
回答by Mcclures
i feel like answering an 8 year old thread is useless, but i will answer anyways for future reference.
I dont know about proxies, but most VPN's (if you go to them) will bring some sort of error page. if you did something like...
我觉得回答一个 8 岁的帖子没用,但无论如何我都会回答以供将来参考。
我不知道代理,但大多数 VPN(如果你去他们)会带来某种错误页面。如果你做了类似...
$cont = file_get_contents($_SERVER["REMOTE_ADDR"]); //the users ip
$errormsg = "nginx";
if(strpos($cont, $errormsg)){
die("No VPN's or Proxies Allowed");
}
this is very basic, you could get an array of the error messages and do it that way.
This will not work if the user has portforwarded their 80 port, but i dont see why the common person would do this.
这是非常基本的,您可以获得一系列错误消息并以这种方式执行。
如果用户转发了他们的 80 端口,这将不起作用,但我不明白为什么普通人会这样做。
回答by Tamás Pap
I'm using the following, but I'm not sure if it is working every time. It's just an idea :)
我正在使用以下内容,但我不确定它是否每次都有效。这只是一个想法:)
<?php
$host = gethostbyaddr($_SERVER['REMOTE_ADDR']);
if ($host != $_SERVER['REMOTE_ADDR']) die('Proxy detected.');
?>

