介绍
你如何阻止大量的IP address
从你的web应用/服务器。 显然,这可以很容易地在做PHP
或任何编程语言
$ipList = []; // array list or from database
if (in_array(getIP(), $ipList)) {
// Log IP & Access information
header("https://www.google.com.ng/search?q=fool"); // redirect
exit(); // exit
}
或使用htaccess
order allow,deny
deny from 123.45.6.7
deny from 012.34.5.
# .... the list continues
allow from all
问题
- 我试图阻止整个
100k plus individual IPs
不subnets
- 我试图避免用户使用PHP来阻止此类IP之前
- 100000+超过1.5MB,这是很多,如果在被加载信息
htaccess
所有的时间 - IP的数据库还在不断增加......他们将倪动态添加更多的价值
- 要在设置禁令
iptables
为100000+仅仅是荒谬(可能是错误的)
馊主意
order allow,deny
deny from database <-------- Not sure if this is possible
allow from all
题
- 是否有可能为
htaccess
获得来自数据库(Redis的,Crunchbase,蒙戈,MySQL或甚至sqlite的)名单...任何 - 是否有一个明显的解决方案来管理生产这类问题
- 我知道最好的解决办法是
Block the IPs at the firewall level
有什么办法务实地添加/删除IP到防火墙
最后
我的方法可能是完全错误的......我要的是一个明显的解决方案,因为垃圾邮件和僵尸网络都在增加...
请这有没有关系DOS
攻击它的一个简单... get lost response
更新
Answer 1:
东西,你可以尝试饲养的IP地址的列表要在阻止文本文件,或者将其转换成DBM哈希文件 ,然后使用mod_rewrite的RewriteMap
。 你必须在你的服务器/虚拟主机配置来设置此。 你不能初始化htaccess文件的地图 。
RewriteEngine On
RewriteMap deny_ips txt:/path/to/deny_ips.txt
RewriteCond ${deny_ips:%{REMOTE_ADDR}|0} !=0
RewriteRule ^ - [L,F]
该/path/to/deny_ips.txt文件看起来是这样的:
12.34.56.78 1
11.22.33.44 1
etc.
从本质上讲,是要拒绝的IP,然后一个“1”的空间。 在这个文本文件中的任何IP将导致服务器返回一个403禁止 。 为了加快速度一点,你可以使用httxt2dbm
生成一个散列DBM,然后你定义的映射为这样:
RewriteMap deny_ips dbm:/path/to/deny_ips.dbm
我不知道对性能的影响是什么,使用mod_rewrite这样有很多IP地址,但是在Apache 2.2快速基准测试在linux下的3GHz的i686的运行,在列表中对102418 5个IP地址之间的差别可以忽略不计。 根据AB公司的产量,他们几乎相同。
解决具体的问题:
是否有可能为htaccess的获得来自数据库(Redis的,Crunchbase,蒙戈,MySQL或甚至sqlite的)名单...任何
使用重写地图,你可以使用“ PRG ”地图类型的映射类型运行外部程序。 然后,你可以写一个Perl,PHP等脚本跟一个数据库,以便查找IP地址。 还要注意的是“注意”中列出的注意事项。 然后你会使用这个地图像使用任何其他地图( RewriteCond ${deny_ips:%{REMOTE_ADDR}|0} !=0
)。 这本质上创造的所有请求的瓶颈。 不是说给数据库的最佳解决方案。
在Apache的2.4虽然,有CAD / fastdbd地图类型,它允许你通过创建查询mod_dbd 。 这是一个更好的选择和mod_dbd模块管理与数据库的连接,池连接等,所以在地图的定义将看起来是这样的:
RewriteMap deny_ips "fastdbd:SELECT active FROM deny_ips WHERE source = %s"
假设你有一个表“deny_ips” 2列的 “ 源 ”(IP地址)和(对于闲置活性1,0)“ 活性的 ”。
是否有一个明显的解决方案来管理生产这类问题
如果你是存储数据库中的所有阻塞IP地址,它的管理数据库表的内容的问题。 如果您使用的是DBM地图类型,我知道至少有Perl有一个DBI管理DBM文件,所以你可以用它来从拒绝列表中添加/删除IP项。 我从来没有使用它之前,所以我真的不能说太多了。 管理一个纯文本文件将是一个棘手很多,特别是如果你打算删除条目,而不是只追加到它。 使用数据库和Apache 2.4的mod_dbd之外,我不认为任何解决方案都开箱或生产准备的。 这将需要定制工作。
我知道最好的解决办法是块中的IP地址在防火墙级别有什么办法务实地添加/删除IP到防火墙
iptables的,有一个Perl接口是被标记为测试版,但我从来没有使用过。 有libiptc如何 ,但根据网络过滤器的常见问题 :
是否有添加/删除规则的C / C ++ API?
不幸的是还:第
现在,你可能会想“但libiptc如何呢?”。 正如已经指出的邮件列表(一个或多个)无数次,libiptc如何从来就不是作为一个公共接口。 我们不保证稳定的接口,并计划在Linux包过滤的下一个化身删除它。 libiptc如何是太低层合理反正使用。
我们都知道,有一个基本的缺乏这样的API,并且我们正在改善这种情况的工作。 在此之前,建议使用任一系统()或打开一个管道进入的标准输入的iptables-恢复。 后者会给你一个方法更好的性能。
所以,我不知道libiptc如何解决如何可行的是,如果没有API的稳定性。
Answer 2:
另一个角度
你好。 可以检查地址被阻断或不经由访问在两个数据块的两个字节每个8KB长。 是的,我是认真的......请耐心等待,因为它需要一点点时间去解释它。
理论
IP地址是一个地址,实际上是一个4字节数。
现在的问题是,如果我们使其地址位的位置?
答案:好吧好吧,我们将有
2^32 = 4 Giga Bits
的寻址空间,这将需要
4Gb/8 = 512 Mega Bytes
分配。 哎哟! 不过不用担心,我们不打算在ipverse阻止一切,512MB是夸张。
这可以打开我们的解决方案的路径。
在小人国案例
想想其中存在那么地址是像0.1或42.42高达255.255唯一的IP地址从0到65535小人国的世界。
现在这个世界的王要阻止几个L-IP(小人国IP)地址。
首先他建立是256 * 256位虚拟的2D位图,占用了:
64 K Bits = 8 K Bytes.
他决定阻止他讨厌,因为他是国王那个讨厌的“革命”的网站,地址是56.28例如。
Address = (56 * 256) + 28 = 14364.(bit position in whole map)
Byte in map = floor(14364 / 8) = 1795.
Bit position= 14364 % 8 = 4.(modulus)
他打开地图文件,访问第一千七百九十五字节,并将第4位(由| 16),然后写回标记站点受阻。
当他看到剧本的56.28,但它同样的计算,并期待在位,如果它被设置,块地址。
现在,这则故事的寓意是什么? 那么我们可以用这个小人结构。
实践
真实世界案例
我们可以在小人国的情况下适用于现实世界的一个“当你需要使用它”的方法,因为分配512MB的文件是不是一个好的选择。
想命名为这样的条目BLOCKS数据库表:
IpHead(key): unsigned 16 bit integer,
Map : 8KB BLOB(fixed size),
EntryCount : unsigned 16 bit integer.
而与下面指定基数结构只是一个进入另一个表
Map : 8KB BLOB(fixed size).
现在让我们说你有一个输入地址56.28.10.2
脚本访问基表和获取地图。
它查找高阶 IP号码56.28:
Address = (56 * 256) + 28 = 14364.(bit position in whole map)
Byte in map = floor(14364 / 8) = 1795.
Bit position= 14364 % 8 = 4.(modulus)
看起来在地图字节1795第4位。
如果位未设置没有进一步的操作,则不需要这意味着有在范围内56.28.0.0没有阻止的IP地址 - 56.28.255.255。
如果设置了位,则该脚本访问块表。
高阶IP数分别为56.28这就给14364,使该脚本查询块表与索引IpHead = 14364.获取记录。 该记录应存在的,因为它被标记为基地。
脚本执行计算较低阶的IP地址
Address = (10 * 256) + 2 = 2562.(bit position in whole map)
Byte in map = floor(2562 / 8) = 320.
Bit position= 2562 % 8 = 2.(modulus)
然后它检查是否地址是由寻找字段地图的字节320的位2阻挡。
任务完成!
Q1:为什么我们使用基地所有,我们可以直接查询块与14364。
A1:是的,我们可以,但基础地图查找会更快然后BTREE搜索任何数据库服务器。
Q2:什么是块表的EntryCount领域?
A2:这是挡在地图领域的同时记录IP地址的数量。 因此,如果我们疏通IP的和EntryCount达到0,阻止记录变得不必要。 它可以被擦除和底图的相应位将被取消设置。
恕我直言,这种做法将是快如闪电。 也为BLOB分配8K每条记录。 由于数据库服务器保持单独的文件与4K,8K文件系统或斑点,4K分页的倍数将快速反应。
在情况下阻止的地址过于分散
那么这是一个问题,这将使得数据库块表不必要地增长。
但是,对于这样的情况下的替代方法是使用一个256 * 256 * 256位的立方体是16777216位长,相当于2097152个字节= 2MB。
对于我们前面的例子较大的IP解析是:
(56 * 65536)+(28 * 256)+10
因此,基地将成为一个2MB的文件,而不是一个数据库表的记录,这将打开(FOPEN等)和位将通过寻求解决(如FSEEK, 从来没有读过整个文件内容,不必要的),然后用以下结构访问块表:
IpHead(key): unsigned 32 bit integer, (only 24 bit is used)
Map : 32 unsigned 8 bit integers(char maybe),(256 bit fixed)
EntryCount : unsigned 8 bit integer.
下面是位平面-位平面(8K 8K)版本的块检查PHP的示例代码:
边注:该脚本可以进一步通过消除几个电话等进行优化。但这样写的保持很容易理解。
<?
define('BLOCK_ON_ERROR', true); // WARNING if true errors block everyone
$shost = 'hosturl';
$suser = 'username';
$spass = 'password';
$sdbip = 'database';
$slink = null;
$slink = mysqli_connect($shost, $suser, $spass, $sdbip);
if (! $slink) {
$blocked = BLOCK_ON_ERROR;
} else {
$blocked = isBlocked();
mysqli_close($slink); // clean, tidy...
}
if ($blocked) {
// do what ever you want when blocked
} else {
// do what ever you want when not blocked
}
exit(0);
function getUserIp() {
$st = array(
'HTTP_CLIENT_IP',
'REMOTE_ADDR',
'HTTP_X_FORWARDED_FOR'
);
foreach ( $st as $v )
if (! empty($_SERVER[$v]))
return ($_SERVER[$v]);
return ("");
}
function ipToArray($ip) {
$ip = explode('.', $ip);
foreach ( $ip as $k => $v )
$ip[$k] = intval($v);
return ($ip);
}
function calculateBitPos($IpH, $IpL) {
$BitAdr = ($IpH * 256) + $IpL;
$BytAdr = floor($BitAdr / 8);
$BitOfs = $BitAdr % 8;
$BitMask = 1;
$BitMask = $BitMask << $BitOfs;
return (array(
'bytePos' => $BytAdr,
'bitMask' => $BitMask
));
}
function getBaseMap($link) {
$q = 'SELECT * FROM BASE WHERE id = 0';
$r = mysqli_query($link, $q);
if (! $r)
return (null);
$m = mysqli_fetch_assoc($r);
mysqli_free_result($r);
return ($m['map']);
}
function getBlocksMap($link, $IpHead) {
$q = "SELECT * FROM BLOCKS WHERE IpHead = $IpHead";
$r = mysqli_query($link, $q);
if (! $r)
return (null);
$m = mysqli_fetch_assoc($r);
mysqli_free_result($r);
return ($m['map']);
}
function isBlocked() {
global $slink;
$ip = getUserIp();
if($ip == "")
return (BLOCK_ON_ERROR);
$ip = ipToArray($ip);
// here you can embed preliminary checks like ip[0] = 10 exit(0)
// for unblocking or blocking address range 10 or 192 or 127 etc....
// Look at base table base record.
// map is a php string, which in fact is a good byte array
$map = getBaseMap($slink);
if (! $map)
return (BLOCK_ON_ERROR);
$p = calculateBitPos($ip[0], $ip[1]);
$c = ord($map[$p['bytePos']]);
if (($c & $p['bitMask']) == 0)
return (false); // No address blocked
// Look at blocks table related record
$map = getBlocksMap($slink, $p[0]);
if (! $map)
return (BLOCK_ON_ERROR);
$p = calculateBitPos($ip[2], $ip[3]);
$c = ord($map[$p['bytePos']]);
return (($c & $p['bitMask']) != 0);
}
?>
我希望这有帮助。
如果对某些细节问题,我会很乐意回答。
Answer 3:
你需要使用外部防火墙,要做到这一点,而不是在PHP。 我建议pfSense或PF 。 我以前也使用过它,它是非常容易使用,非常直观,而且非常强大。 这是最好的SYS-管理员的选择。 我在FreeBSD上运行它,但它在OpenBSD的伟大工程,以及。 我是一个Linux的家伙,所以它的痛苦,我说这一点,但不要试图在Linux上运行它。 BSD是容易的,你可以很快搞清楚。
为pfSense一个真棒功能是配置使用脚本和限制到一个网络接口的配置访问(以便只在LAN上的东西可以配置它)的能力。 它也有一对夫妇的ID10T级别的功能,让你不小心切断了自己的访问。
你也应该知道,很多垃圾邮件发送者的IP可以快速使用像开关的Tor 。 为了解决这个问题,你应该在你的块列表包括(可从不同的地方这个列表),已知TOR出口节点的地址。
Answer 4:
达到使用iptables和IPSET WWW服务器之前,阻碍交通。
抓住INPUT链假设你的Web服务器的过滤表中列入黑名单的IP流量是在同一台机器上。 如果一台路由器的IP阻止你将要FORWARD链。
首先创建IPSET:
ipset create ip_blacklist hash:ip
IP地址可以通过添加:
ipset add ip_blacklist xxx.xxx.xxx.xxx
该IPSET匹配规则添加到你的iptables(丢弃所有的包匹配IPSET):
iptables --table filter --insert INPUT --match set --match-set ip_blacklist src -j DROP
这将WWW服务器之前停止列入黑名单的流量。
编辑:我有机会来查找默认的最大尺寸,它是65536,所以你将需要调整这个支持100000+条目:
ipset create ip_blacklist hash:ip maxelem 120000
您也可以调整散列大小:
ipset create ip_blacklist hash:ip maxelem 120000 hashsize 16384
(必须是2的幂)
我的经验是IPSET查找有我的系统(〜45000项)的影响可以忽略。 有一些在网上测试用例。 内存的设置是一个限制因素。
Answer 5:
通过代码如果你想办法添加/删除看一看的DenyHosts 。 您既可以通过保持代码的IP列表或修补源从任何你想要的位置读取。
Answer 6:
没有与网络过滤器的调用IPSET一个项目,所以你可以添加或删除IP的服务,您只需要创建这个列表的规则
http://ipset.netfilter.org/
Answer 7:
如果您阻止的IP地址,你真的应该在防火墙级别(你不想从不受欢迎的IP地址的用户得到很远,进入你的系统)这样做。 因此,我建议编写查询数据库,并相应地修改您的防火墙配置文件bash脚本(假定你想它利用存储在Web数据库的IP地址解决方案 - 有很好可能是一个更好的地方来存储这些信息)。
编辑:如果你想的IP地址在PHP层添加到黑名单中,作为@Populus建议,这里是如何在PHP中使用系统调用的手册: http://php.net/manual/en/function.system .PHP
在这里,你会需要的,如果你使用iptables来使用的IP地址添加到黑名单中的命令: http://www.cyberciti.biz/faq/linux-iptables-drop/
Answer 8:
我知道一种方法
它由PHP。 如您在非常beginig这个问题的提及。
$ipList = []; // array list or from database
if (in_array(getIP(), $ipList)) {
// Log IP & Access information
header("https://www.google.com.ng/search?q=fool"); // redirect
exit(); // exit
}
我看了你写的东西。 但只是等待一分钟。
为什么你想要做this.is不是这种情况,为什么important.but。
我的意思是你为什么要避免访问,因为它的速度阻止只是因为或因为自己这么辛苦的PHP调用中的所有页面的功能? 如果避免访问PHP is.avoiding主题,看看内容有一些IP的唯一原因。
所以我有一个想法,你I.suggest这种方式。
使用一个切入点。
我有这个解决方案工作。
先用一个简单的htaccess你发送到一个页面调用入口点的所有请求。(喜欢的index.php)
用一个简单的重写规则,我就给你。 所以当用户请求
mysite.com/some/path/page.php or anything
htaccess的将执行类似下面的不改变网址。 因此用户不会感到任何东西。
mysite.com/index.php?r=some/path/page.php
所以每个请求成了不同的$ _GET [“R”] PARAMS一个请求。 所以埃维要求,我们将已执行的index.php。 现在我们可以做财产以后像这样的index.php
$ipList = []; // array list or from database
if (in_array(getIP(), $ipList)) {
// Log IP & Access information
header("https://www.google.com.ng/search?q=fool"); // redirect
exit(); // exit
}
//if after this execute means the IP is not banned
//now we can include file that $_GET['r'] points to
include $_GET['r'];
其所以simple.and其真正的一个是这样complicated.but主要的想法是一样的。 你怎么看?
Answer 9:
看来,我们中的大多数同意在防火墙级别阻止 。
你可以有一个监听到你的网站的IPS阻止,并生成一个脚本程序:
ip = getNextIpToBlock()
an = increment_unique_alphanum_generator()
script = generate_script(ip, an)
脚本会是这个样子(其中,[一]是字母数字值和[IP]是你的IP块):
en [enter]
*password* [enter]
conf t [enter]
access-list [an] deny ip [ip] 0.0.0.0 any [enter]
access-group [an] in interface outside [enter]
然后加载这个脚本到另一个程序执行远程Telnet或SSH调用您的FW CLI。
不要忘了注销,也许你复制运行配置每100 IPS启动配置。
我不知道,但你可能想现在什么是防火墙的局限性就知道了。
最好,
Answer 10:
不要在你的名单上的IP地理查询。 我自己的经验表明,大多数恶意(即垃圾邮件)连接都源于中国。 如果您发现相同的是这样的你,和你无特殊需要服务于中国,看看你是否能有效地在防火墙级别阻止了整个国家。
Answer 11:
恕我直言,有几个角度从这个问题可以考虑
- 你有一个非常大的一套独特的IP地址来阻止。 你越早阻止他们自己的服务器,你会浪费他们的较少的处理能力上。 您可以添加/通过从PHP相应的系统调用删除您的防火墙的IP。
考虑到上面的选项,唯一相关的问题是:
- 难道他们经常光顾? =>如果是,则溶液(1)是最好的选择。
- 你的防火墙能有效地处理呢? =>如果没有,你可能要考虑的其他解决方案。
该.htaccess
将是我的第二选择。
文章来源: How to Block 100,000+ Individual IP addresses