我有一个htaccess文件,其中有很多来自'拒绝来自'条目。其中大多数具有较低的八位字节。
为了尝试改善htaccess处理时间,对于未被禁止的IP,我试图实现一个php过滤器,它是从重写规则调用的。
我的htaccess重写规则:
RewriteCond %{REMOTE_ADDR} ^37\.115\. [OR]
RewriteCond %{REMOTE_ADDR} ^46\.118\.
RewriteRule (.*) check_banned.php?ip=%{REMOTE_ADDR}
... More rewrite rules
注意,没有' [L]'在重写规则的最后。如果IP没有被禁止,我希望htaccess继续处理规则。 当前的php文件:
$ip = strip_tags(trim($_GET['ip']));
// Read file with list of banned ips
$file = ban_list.txt;
$myfile = fopen($file, "r") or die("Unable to open file!");
$ban_list = fread($myfile, filesize($file));
fclose($myfile);
// Check if ip is in ban list
$pos = strpos($ban_list, $ip);
if($pos === false) $ip_found = false;
else $ip_found = true;
if($ip_found){
header('HTTP/1.0 403 Forbidden');
}
else {
// What to do if ip is not banned?
}
如果在禁令列表中找到了ip,这可以正常工作。但是,当ip没有被禁止时,我找不到处理这种情况的方法。我只是得到一个空白页面,标题为“200 ok'。
”另外,我正在考虑将(。*)传递给文件check_banned.php,将php代码转换为函数,如果没有禁止ip,它将返回字符串。不得不承认我还没试过这个。
RewriteRule (.*) check_banned.php?ip=%{REMOTE_ADDR}&str=$1
在php文件中:
$string = strip_tags(trim($_GET['str']));
if($ip_found){
header('HTTP/1.0 403 Forbidden');
}
else {
return $string;
}
更新: 感谢Mike Nickaloff,这里有一些调整。不幸的是,我有一个共享主机帐户,无法访问服务器设置。
我将php过滤器脚本的文件权限设置为600,过滤似乎仍然有效。这可以解决这些漏洞吗?
如果没有禁止ip,php脚本会读取请求的页面并回显它。如果它不必这样做会很好,并且只向.htaccess发送一条消息,表明它应该继续处理规则。
对check_banned.php的更改:
<?php
ob_start(); // suppress any output
$ip = strip_tags(trim($_SERVER["REMOTE_ADDR"]));
// Read file with list of banned ips
$file = ban_list.txt;
$myfile = fopen($file, "r") or die("Unable to open file!");
$ban_list = fread($myfile, filesize($file));
fclose($myfile);
// Check if ip is in ban list
$pos = strpos($ban_list, $ip);
if($pos === false) $ip_found = false;
else $ip_found = true;
if($ip_found){
ob_end_clean(); // Allow output
header('HTTP/1.0 403 Forbidden');
}
else{
// ip Was not found in ban list
$file = "";
$uri = "";
if(isset($_SERVER["REQUEST_URI"])){
$uri = strip_tags(trim($_SERVER["REQUEST_URI"]));
}
if($uri == "" || $uri == "/")
$file = $_SERVER['DOCUMENT_ROOT']."/index.php";
else $file = $_SERVER['DOCUMENT_ROOT'].$uri;
$myfile = fopen($file, "r") or die("Unable to open file!");
$file = fread($myfile, filesize($file));
fclose($myfile);
ob_end_clean(); // Allow output
echo $file;
}
?>
答案 0 :(得分:1)
这是你可以处理的一种方式:
通过加载正确的URL
让PHP加载请求的任何页面这仅在从服务器请求PHP脚本时才有效,因此必须稍微更改htaccess规则以仅匹配.php文件。 无论如何,匹配。*是一个坏主意,但这种方法并不是最安全的方法。您可能希望投资免费防火墙,如UFW,它允许您阻止整个服务器的IP地址,而不是基于每个请求。
使用防火墙是一种更有效,更安全的阻止IP地址的方法。
PHP充当防火墙的方法容易受到DDoS攻击和递归攻击。例如 - 如果有人请求页面check_ip.php会发生什么?它必须重定向到某个地方 - 所以它会重定向到check_ip.php,它会重定向到check_ip.php,它会重定向到check_ip.php - 所以长话短说,
请勿使用此方法 - 这是用于演示目的而不是替换防火墙。
理论上,如果我们确实使用了这种不安全的方法,我们将采用以下方法:
<。>在.htaccess中将其更改为 RewriteRule ^([\s\S]+)(.php|.phps)$ /check_banned.php [L]
... More rewrite rules
然后在check_banned.php中你可以这样做:
<?php
$ip = strip_tags(trim($_SERVER["REMOTE_ADDR"]));
// Read file with list of banned ips
$file = ban_list.txt;
$myfile = fopen($file, "r") or die("Unable to open file!");
$ban_list = fread($myfile, filesize($file));
fclose($myfile);
// Check if ip is in ban list
$pos = strpos($ban_list, $ip);
if($pos === false) $ip_found = false;
else $ip_found = true;
if($ip_found){
header('HTTP/1.0 403 Forbidden');
}
else {
// What to do if ip is not banned?
$sPage = $_SERVER["PATH_TRANSLATED"];
if (file_exists($sPage)) {
include_once($sPage);
}
}
?>
警告 - 请记住 - 请勿使用此方法,因为它易受攻击 -
编辑:为了响应OP上的编辑,这是一种在没有防火墙的情况下进行IP过滤的安全方法:
在文件 check_banned.php
中<?php
$ip = strip_tags(trim($_SERVER["REMOTE_ADDR"]));
// Read file with list of banned ips
$file = ban_list.txt;
$myfile = fopen($file, "r") or die("Unable to open file!");
$ban_list = fread($myfile, filesize($file));
fclose($myfile);
// Check if ip is in ban list
$pos = strpos($ban_list, $ip);
if($pos === false) $ip_found = false;
else $ip_found = true;
if($ip_found){
header('HTTP/1.0 403 Forbidden');
// here is the important change
die("script terminated because IP is in ban list");
}
else {
// if IP not banned, do nothing.
}
?>
然后,在您希望保护的每个PHP脚本的顶部,您可以在最顶端执行此操作:
<?php
include_once("check_banned.php");
?>
如果IP匹配禁止列表并且不进一步处理任何内容,这将基本上导致脚本使用“die”命令终止,然后如果他们的IP不在禁止列表中,它将继续加载页面。
我看过网站使用这种技术 - wordpress网站是一个框架的一个很好的例子,它使用类似的策略来执行每个请求的预处理。
我会远离mod_rewrite规则,除非它们真的有必要,因为如果你不小心它们可以打开一大堆漏洞。
答案 1 :(得分:0)
虽然您有相当数量的代码(并且可能已经开始),但我认为您走的正确。
我使用http://www.ip-approval.com提供了一种允许和/或阻止IP的方法,并且还可以选择将这些访问者重定向到不同的网页或网站。
请参阅:http://www.ip-approval.com/instructions
〜
在.htaccess文件中,我添加了:
php_value auto_prepend_file /check_banned.php
...将代码添加到网站的每个页面。如果您有folders / pages.html,可以将check_banned.php文件添加到该文件夹,或者添加:
php_value auto_prepend_file none
...到文件夹中的.htaccess文件,它不会被添加到该文件夹中。
所以,如果你想要php_value,auto_prepend_file可以正常工作
或强>
正如其他人所说,你可以在每个页面上添加以下内容:
<?php
include_once("check_banned.php");
?>