使用ModSecurity阻止IP

我们可以使用Apache模块mod_security将任何IP动态添加到黑名单(或白名单)。令人惊讶的是,我们在搜索互联网后找不到任何现有的解决方案,但是这种阻止任何IP的功能非常重要,因为与其他网站一样,我们每天也从很少的IP中收到大量不需要的HTTP请求基础。因此,我们继续实施并实施了阻止此类IP的解决方案,很高兴与您共享该解决方案。

通常在Linux中,iptables用于阻止任何不需要的IP或IP范围。下面提供了一些iptables用于阻止IP的示例用法。

# Blocks the specified IP
iptables -A INPUT -s 0.0.0.1 -j DROP

# Blocks the specified IP range
iptables -A INPUT -m iprange --src-range 0.0.0.0-0.0.0.255 -j DROP

# Same as above, but using CIDR notaion
iptables -A INPUT -s 0.0.0.0/24 -j DROP12345678复制代码类型:[html]

iptables是最方便的方法,如果计算机直接连接到Internet而不在前面安装代理或负载平衡器,则可以使用。但是在hudku.com上,我们的网站作为AWSElasticBeanstalk应用程序运行,并在Linux上运行Apache,因此我们在前面具有ElasticLoadBalancer。因此,我们获得的IP始终是负载均衡器的IP,仅在HTTP标头“X-Forwarded-For”中,我们才能获得发出请求的客户端的IP。iptables只能与IP一起使用,我们不能使其使用HTTP标头中的值。

因此,我们不得不寻找替代解决方案,因此我们决定使用实施该设施mod_security。通过使用提供的“集合”来实现该逻辑mod_security。收藏只不过是一个HashMap。IP地址是密钥,值是整数。如果值为1,则将其解释为列入白名单的IP;如果值为2,则将IP视为列入黑名单。如果密钥不存在,则IP不在白名单或黑名单中,因此可以正常处理。

如果我们在白名单中找到IP,则不会进行进一步的检查,并且请求会得到兑现。

如果我们在黑名单中找到IP,则会删除该连接并将其记录在modsecurity日志文件中。

要将IP添加到黑名单,我们访问应用程序的特定URL,并将IP作为参数传递。就像www.example.com/ip/blacklist?ip=0.0.0.1万维网。example.com/ip/blacklist?ip=0.0.0.1一样简单。同样,将IP列入白名单,请访问www.example.com/ip/whitelist?ip=0.0.0.2万维网。example.com/ip/whitelist?ip=0.0.0.2。要同时从域名列表和黑名单中删除IP,该命令为www.example.com/ip/remove?ip=0.0.0.3,该命令将从集合(映射)中删除该IP(如果存在)。万维网。example.com/ip/remove?ip=0.0.0.3将从集合(地图)中删除IP(如果存在)。

然后,最重要的是确保仅当从当前计算机(即本地主机)发出这些命令时才遵守这些命令。

当mod_security安装时,它会创建一个名为“目录modsecurity.d”并加载全部文件“的.conf”扩展出现在该目录中。

有了上述所有信息,现在我们可以看一下modsecurity.d目录中存在的my_rules.conf文件中包含的源代码。

#
# Adding / Removing an ip to Dynamic Whitelist & Blacklist - allowed only for localhost
#

# Remove from Dynamic Whitelist & Blacklist - remove allowed variable
SecRule REQUEST_FILENAME "^/ip/remove$"
"chain,phase:1,t:none,deny,nolog,status:200"
 SecRule REMOTE_ADDR "^127.0.0.1$" "chain,t:none"
 SecRule ARGS:ip "^\b(\d{1,3}\.\d{1,3}\.\d{1,3}\.\d{1,3})\b"
 "t:none,initcol:ip=%{args.ip},setvar:!ip.allowed"
#
# Add to Dynamic Whitelist - allowed value is 1
SecRule REQUEST_FILENAME "^/ip/whitelist$"
"chain,phase:1,t:none,deny,nolog,status:200"
 SecRule REMOTE_ADDR "^127.0.0.1$" "chain,t:none"
 SecRule ARGS:ip "^\b(\d{1,3}\.\d{1,3}\.\d{1,3}\.\d{1,3})\b"
 "t:none,initcol:ip=%{args.ip},setvar:ip.allowed=1"
#
# Add to Dynamic Blacklist - allowed value is 2
SecRule REQUEST_FILENAME "^/ip/blacklist$"
"chain,phase:1,t:none,deny,nolog,status:200"
 SecRule REMOTE_ADDR "^127.0.0.1$" "chain,t:none"
 SecRule ARGS:ip "^\b(\d{1,3}\.\d{1,3}\.\d{1,3}\.\d{1,3})\b"
 "t:none,initcol:ip=%{args.ip},setvar:ip.allowed=2"

# Allow any request from localhost
SecRule REMOTE_ADDR "^127.0.0.1$"
"phase:1,t:none,allow,nolog,ctl:ruleEngine=off"

#
# Initialize IP Collection using the IP address obtained from x-forwarded-for or remote_addr
#
SecRule REQUEST_HEADERS:x-forwarded-for "^\b(\d{1,3}\.\d{1,3}\.\d{1,3}\.\d{1,3})\b"
"phase:1,t:none,pass,nolog,capture,setvar:tx.client_ip=%{tx.1}"
SecRule &TX:CLIENT_IP "@eq 0"
"phase:1,t:none,pass,nolog,setvar:tx.client_ip=%{remote_addr}"
SecRule &TX:CLIENT_IP "!@eq 0"
"phase:1,t:none,pass,nolog,initcol:ip=%{tx.client_ip}"

#
# Process Dynamic Whitelist & Blacklist
#
# Allow if IP is present in Dynamic Whitelist
SecRule IP:ALLOWED "@eq 1" "phase:1,t:none,allow,nolog,ctl:ruleEngine=off"
#
# Drop if IP is present in Dynamic Blacklist
SecRule IP:ALLOWED "@eq 2" "phase:1,t:none,drop,log,logdata:'Dynamic Blacklist'"1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253复制代码类型:[html]

第一段代码处理“删除”请求,以从白名单和黑名单中删除IP。第二行是进行重要检查的地方,以确保仅当从本地主机(127.0.0.1)发出所有这些请求时,才兑现所有这些请求。然后,在第三行中,从集合中删除IP。集合的名称为“ip”,而我们使用的变量或计数器的名称为“allowed”。

同样,下一个块处理包含在白名单中的请求,下一个块处理黑名单。所有这些块首先初始化集合“ip”,然后设置变量“allowed”的值。

然后,我们进行简单的检查,以允许所有来自本地主机的请求,而无需应用任何其他规则。

下一节实际上是初始化modsecurity集合。我们首先从HTTP标头中提取IP

X-Forwarded-For并将其存储在中TX:CLIENT_IP。该集合“TX”属于modsecurity并且通常可用。

如果X-Forwarded-For不包含任何IP,则我们尝试使用remote_addr变量中可用的值。

下一行ip使用mod_security运算符“initcol”初始化名称为“”的集合,并提供当前IP地址。

在最后一个块中,第一行检查变量“allowed”的值。如果为1,则它是列入白名单的IP,因此可以通过关闭规则引擎而继续进行HTTP请求,而无需任何进一步检查。

最后一行检查它是否是列入黑名单的IP。如果是这样,则断开连接并记录信息。

这是将IP添加到黑名单,白名单或从这两个列表中删除的示例用法。我们使用Linuxcurl命令来访问URL,我们只对使用“http_code”选项可以获得的HTTP响应代码感兴趣。

# Blacklist few IPs
curl -s -o /dev/null -I -w "%{http_code}" localhost/ip/blacklist?ip=0.0.0.1
curl -s -o /dev/null -I -w "%{http_code}" localhost/ip/blacklist?ip=0.0.0.2
curl -s -o /dev/null -I -w "%{http_code}" localhost/ip/blacklist?ip=0.0.0.3

# Whitelist few IPs
curl -s -o /dev/null -I -w "%{http_code}" localhost/ip/whitelist?ip=0.0.1.1
curl -s -o /dev/null -I -w "%{http_code}" localhost/ip/whitelist?ip=0.0.1.2
curl -s -o /dev/null -I -w "%{http_code}" localhost/ip/whitelist?ip=0.0.1.3

# Remove IP from both the lists if present
curl -s -o /dev/null -I -w "%{http_code}" localhost/ip/remove?ip=127.0.0.1123456789101112复制代码类型:[html]

即使在重新启动后,对白名单或黑名单所做的更改仍会保留,因为我们正在使用的永久集合mod_security。它将数据存储在指令SecDataDir中指定的目录中。但是,如果我们需要在数据库中维护该列表,则可以在执行curl命令之前或之后让一些bash脚本来完成此工作。

那就是所有的人。现在,我们可以使用来成功阻止任意数量的IP地址mod_security。我们可以动态地做到这一点,而不必每次都重新启动ApacheWeb服务器。

(0)

相关推荐