如何阻止向特定域发出请求的 IP?

如何阻止向特定域发出请求的 IP?

我有一个启用了 CSF 和 ModSecurity 的服务器。

我想设置一个规则或配置,自动阻止(在指定的时间内)任何向特定子域发出传入请求的 IP。在本例中,它是“cpanel.DOMAIN.com”。由于“cpanel”是一个无效的子域(它不存在于该域中),我认为可以肯定地说这些是机器人发出的请求。这些请求可能每隔几秒钟就会多次出现,所以我想阻止这些机器人。

我希望以一种方式实现这一点,使 Web 服务器(在本例中为 LiteSpeed)不必处理请求。目前,它正在尝试查找请求的子域,然后生成 404 错误。我希望在发生这种情况之前阻止它。

我遇到的一个建议是,做类似的事情,需要在文件中添加以下内容/usr/local/csf/bin/csfpre.sh

#!/bin/sh
iptables -A INPUT -p tcp --match multiport --dport 80,443 -m string --string 'THEDOMAIN' --algo bm -j DROP

这是最好的(最有效的)方法吗?还是有更好的方法?“更好”和“最好”只是我希望请求对服务器资源的影响尽可能小。

非常感谢。

答案1

为禁域创建一个虚拟主机。它将需要自己的目录(可在多个禁域之间共享)。作为默认内容,使用此 index.php:

<?php
// contents of FORBIDDEN.YourDomain.com/index.php
// spits out one UDP packet at the web visitor's port 911
// the 911 packet is intended to be detected, processed and dropped with firewall rules
$remoteaddr = $_SERVER['REMOTE_ADDR'];
$sock = socket_create(AF_INET, SOCK_DGRAM, SOL_UDP);
socket_sendto($sock, "NOPE", 4, 0, $remoteaddr, 911);
socket_close($sock);

现在是防火墙规则。

(A)首先创建一个新的ipset(超时:1天=86400秒)

/usr/sbin/ipset create ipset_temp_blocklist \
    hash:ip \
        family inet \
        hashsize 4096 \
        maxelem 65536 \
        timeout 86400 \
        counters \
        comment

(B)然后创建一个新的 iptables 规则链

/usr/sbin/iptables -N ADD_TEMP_BAN

(可选)链式规则 1:记录有问题的数据包

/usr/sbin/iptables -A ADD_TEMP_BAN -j NFLOG --nflog-prefix "add-temp-ban="

链式规则 2:将违规者(‘911’ UDP 数据包的目的地)添加到阻止列表 ipset

/usr/sbin/iptables -A ADD_TEMP_BAN -j SET --add-set ipset_temp_blocklist dst

链式规则 3:链式规则结束:直接丢弃 UDP 数据包

/usr/sbin/iptables -A ADD_TEMP_BAN -j DROP

(C)现在,当我们看到传出的“911”UDP 数据包时,调用新的规则链

/usr/sbin/iptables -A OUTPUT -p udp -dport 911 -j ADD_TEMP_BAN

(D)现在使用阻止列表,添加一条规则以丢弃来自列出的 IP 地址的所有传入 Web 服务的数据包

/usr/sbin/iptables -A INPUT -i eth0 -p tcp -m multiport --dports 80,443 -m set --match-set ipset_temp_blocklist src -j DROP

请注意,最后一条规则执行以下操作:

  • 附加到 INPUT 规则链的末尾(您可能希望将其放在规则的前面)
  • 仅适用于接口“eth0”上的数据包(您可能更喜欢“全部”或其他接口)
  • 仅协议 tcp('-p all' 将阻止所有内容、ping 等)
  • 只有 TCP 数据包才会发往端口 80 和 443(如果使用的话,您可以添加 8080,等等)
  • 仅限来源在阻止列表中的数据包
  • 丢弃该数据包。

你可以像这样列出被阻止的 IP:

/usr/sbin/ipset list ipset_temp_blocklist 

    Name: ipset_temp_blocklist
    Type: hash:ip
    Revision: 4
    Header: family inet hashsize 1024 maxelem 65536 timeout 864000 counters
    Size in memory: 123880
    References: 2
    Number of entries: 1331
    Members:
    xx.35.112.155 timeout 528177 packets 4 bytes 240
    xx.199.52.104 timeout 681175 packets 4 bytes 240
    xx.230.7.65 timeout 490347 packets 4 bytes 240
    xx.63.11.235 timeout 782713 packets 5 bytes 300
    xx.159.102.65 timeout 351110 packets 1 bytes 40
    xx.206.244.232 timeout 837758 packets 4 bytes 240
    xx.162.105.161 timeout 490665 packets 3 bytes 180

并查看 iptables 链的活动,如下所示(数字为 [packets:bytes]):

/usr/sbin/iptables-save -c | grep -E "ADD_TEMP_BAN|ipset_temp_blocklist"

    :ADD_TEMP_BAN - [0:0]
    [1333:73200] -A OUTPUT -p udp -dport 911 -j ADD_TEMP_BAN
    [1333:73200] -A ADD_TEMP_BAN -j NFLOG --nflog-prefix  "add-temp-ban="
    [1333:73200] -A ADD_TEMP_BAN -j SET --add-set ipset_temp_blocklist dst
    [1333:73200] -A ADD_TEMP_BAN -j DROP
    [5187:305169] -A INPUT -i eth0 -p tcp -m multiport --dports 80,443 -m set --match-set ipset_temp_blocklist src -j DROP

依口味调整。

答案2

这种过滤会导致一些不良的副作用:

它不会彻底终止 TCP 连接 -> 客户端将尝试重新发送请求,最终超时。服务器端保持连接打开,直到达到超时。这可能导致 TCP 套接字耗尽并引发 DoS。

对于端口 80,它匹配任何 poayload 为 的数据包THEDOMAIN。客户端请求可能不直接包含此字符串,但如果包含,则很难调试该特定请求失败的原因。

对于端口 443,有可能THEDOMAIN在一段时间内某一部分通信流匹配。由于客户端 - 服务器连接的加密密钥是针对每个连接单独协商的,因此这种情况最终会发生。如果可以接受偶尔有效的请求失败,那么这不是问题。

您需要确保您的 DNS 中没有列出不需要的子域名。如果它在其他 DNS 中列出,唯一的干净方法是让您的 Web 服务器处理请求。

处理这些“额外”的请求并不需要太多资源。

相关内容