如何只允许特定IP查看网页?
我正在尝试让 PHP 脚本工作,它将人的 IP 与文本文件进行比较(每行一个 IP)。如果该人的 IP 不在文本文件中,那么他会被重定向到 returned.html。我知道我可以使用 .htaccess 来实现此目的,但 IP 列表可能会变得非常非常长。
这是我到目前为止所拥有的代码:
<?php
$ipArray = file('ip.txt');
unset($allowed);
foreach ($ipArray as $ipTest) if (substr_count($_SERVER['REMOTE_ADDR'],trim($ipTest)) != "0") $allowed = true;
if ($allowed != true) {
header('location: /declined.html'); // the banned display page
die();
}
?>
我希望能够在我只想看到某些IP的每个页面中调用此脚本,这就是我试图调用它的内容:
<? include('ip_allow.php'); ?>
当我在中调用PHP脚本时当我的 IP 不在 ip.txt 中时,HTML 页面不会将我重定向到 /declined.html!我该如何解决这个问题?再说一遍,我的问题不是如何使用 .htaccess,而是如何修复我的脚本!谢谢。
I'm trying to get a PHP script to work where it compares the IP of the person against a text file(one IP per line). If the person's IP is not in the text file, then he gets redirected to declined.html. I know I could use .htaccess for this but the IP list could get really, really long.
This is the code that I have so far:
<?php
$ipArray = file('ip.txt');
unset($allowed);
foreach ($ipArray as $ipTest) if (substr_count($_SERVER['REMOTE_ADDR'],trim($ipTest)) != "0") $allowed = true;
if ($allowed != true) {
header('location: /declined.html'); // the banned display page
die();
}
?>
I want to be able to call this script in every page that I only want certain IP's to see, this is what I'm trying to call it with:
<? include('ip_allow.php'); ?>
When I call the PHP script in the HTML page when my IP is NOT in ip.txt, it does not redirect me to /declined.html! How can I fix this? Again, my question is not how to use .htaccess, but how to fix my script! Thanks.
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(4)
对于 IP 过滤,最好在处理链中尽早进行。按优先顺序排列:
您很可能无权访问路由器或防火墙级别,但您可以使用 Apache 的 mod_rewrite 来使用外部文件创建动态块。按如下方式设置您的“启用的 IP”文件:
它基本上是“键值”,其中键是 IP 地址
然后您的 mod_rewrite 规则(我已对它们进行编号以供参考)
它们的工作方式如下:
所有这些的相关 Apache 文档位于此处。
For IP filtering, it's best to do it as early as possible in the processing chain. In order of preference:
Most likely you don't have access to the router or firewall levels, but you CAN use Apache's mod_rewrite to have a dynamic block using an external file. Set up your "enabled IPs" file as follows:
It's basically "key value", where the key is the IP address
Then your mod_rewrite rules (I've numbered them for reference)
They work as follows:
Relevant Apache docs for all this are here.
如果您将配置直接放入 Apache 配置中,则不会因
.htaccess
查找而降低速度 - 但这意味着每当列表被修改时您都需要重新加载 Apache 配置。 (尽管Marc的回答很好地避免了这种情况。)mod_authz_host.c
针对中等快速搜索进行了优化。如果您每次执行时都在脚本中读取文本文件,那么您的速度已经比 Apache 慢了好几倍。 Apache 读取配置一次,将 IP 地址转换为二进制格式一次,然后可以使用非常快的整数算术来确定是否允许主机。
此外,它已经调试完毕并且可以运行。部署它所花费的时间比在当前代码中查找错误所花费的时间要少 - 即使这样,您当前的代码也会 - 在每个访问控制请求上 - 重新读取(并重新解析为数组)IP 地址的文本描述,将来自远程对等点的 IP 地址转换为文本版本,然后对整个数组执行非常慢的基于文本的比较。
如果速度确实很重要,那么您应该研究通过系统防火墙进行访问控制。
iptables
具有优化的例程,可在允许或拒绝的主机列表中查找匹配的 IP 地址,并且不会浪费任何时间执行任何协议分析。当然,这是一种更重的“全有或全无”方法,如果某些内容可供所有人使用,则需要在侦听端口之间对内容进行烦人的分离。If you place your configuration in your Apache configuration directly, it won't incur the speed penalties of
.htaccess
lookups -- but that would mean you'd need to reload the Apache configuration whenever the list is modified. (Though Marc's answer avoids this very nicely.)The
mod_authz_host.c
is optimized for moderately fast searching. If you're reading a text file in your script every execution, you're already several times slower than Apache. Apache reads the configuration once, converts the IP addresses to a binary format once, and can then use very fast integer arithmetic to determine if hosts are allowed or not.Furthermore, it's already debugged and working. It'd take you less time to deploy it than it would to find the bug in your current code -- and even then, your current code would -- on every access-controlled request -- re-read (and re-parse into an array) the textual description of IP addresses, convert the IP address from the remote peer into a text version, and then perform a very slow text-based comparison over the entire array.
If speed is of real importance, then you should investigate doing the access control via your system firewall.
iptables
has optimized routines to find matching IP addresses among a list of allowed or denied hosts and won't waste any time performing any protocol analysis. Of course, this is a much heavier all-or-nothing approach that would require an annoying separation of content among listening ports if some content is available for all.我猜你的文件位于错误的目录中,或者 PHP 无法工作或其他一些更基本的配置问题,因为我测试了你的代码,它对我来说工作得很好。
I would guess you have files in the wrong directory, or PHP not working or some other more basic configuration issue, since I tested your code and it works fine for me.
file()
命令在每行末尾包含\n
字符,因此每行实际上类似于0.0.0.0\n
每次都返回 false。使用这个:
另外只是在标题行中指出,
Location
应以大写字母开头,并且您应指定文件的完整 URI:The
file()
command includes the\n
character at the end of each line, so each line is actually something like0.0.0.0\n
which is returning false every time.Use this:
Also just to point out in your header line,
Location
should start with a capital letter and you should specify a full URI to the file: