如何阻止100,000单个IP地址(How to Block 100,000+ Individual

2019-07-22 18:59发布

介绍

你如何阻止大量的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 IPssubnets
  • 我试图避免用户使用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

更新

  • 防火墙: 思科PIX 515UR

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:

恕我直言,有几个角度从这个问题可以考虑

  1. 你有一个非常大的一套独特的IP地址来阻止。 你越早阻止他们自己的服务器,你会浪费他们的较少的处理能力上。 您可以添加/通过从PHP相应的系统调用删除您的防火墙的IP。

考虑到上面的选项,唯一相关的问题是:

  • 难道他们经常光顾? =>如果是,则溶液(1)是最好的选择。
  • 你的防火墙能有效地处理呢? =>如果没有,你可能要考虑的其他解决方案。

.htaccess将是我的第二选择。



文章来源: How to Block 100,000+ Individual IP addresses