我正在努力使用Apache设置mod_evasive以对抗DOS尝试.我使用DOSSystemCommand运行一个脚本,将违规的IP地址添加到iptables中的BANNED链.
我发现我可以让这个过程发挥作用的唯一方法是将Apache的shell从/ sbin / nologin更改为/ bin / bash.但实际上只有脚本的一部分因没有更改shell而失败.这是DOSSystemCommand行及其运行的脚本:
DOSSystemCommand "/usr/bin/sudo /bin/bash /var/www/html/ban_ip.sh %s"
和脚本…(注意我只是在测试..这就是为什么我有详细的输出和短禁止期)
#!/bin/bash IP=$1 IPTABLES=/sbin/iptables sudo $IPTABLES -I BANNED -p tcp -s $IP --dport 443 -j DROP sudo $IPTABLES -I BANNED -p tcp -s $IP --dport 80 -j DROP echo sudo $IPTABLES -v -D BANNED -p tcp -s $IP --dport 80 -j DROP | at -m now + 1 minutes echo sudo $IPTABLES -v -D BANNED -p tcp -s $IP --dport 443 -j DROP | at -m now + 2 minutes echo rm -fv /tmp/dos-$IP | at -m now + 2 minutes
因此,如果Apache具有/ sbin / nologin的shell,它将添加IPTABLES规则并且它将创建at作业,但是当我收到带有at作业结果的电子邮件时,它会声明用户当前不可用,所以永远不会删除iptables规则.如果我将Apache / bin / bash作为其shell,则添加iptables规则,创建at作业,并且iptables删除在指定时间按预期工作.
所以我的问题是:通过给Apache用户一个shell,我以什么方式使我的服务器面临风险?
if (sys_command != NULL) { snprintf(filename,sizeof(filename),sys_command,text_add); system(filename); }
现在,让我们检查man 3系统:
DESCRIPTION system() executes a command specified in command by calling /bin/sh -c command,and returns after the command has been completed. During execution of the command,SIGCHLD will be blocked,and SIGINT and SIGQUIT will be ignored.
然后,我们可以看到指定的命令正在shell中运行.不可否认,系统(3)文档在这一点上令人困惑,但我们当然可以看到正在发生的事情并做出适当的推论 – 它是在用户的默认shell中运行,而不仅仅是/ bin / sh.
正确的解决方案相对简单:只需用fork(2)和execve(2)(或类似的东西)替换system(3)调用.如果您不想这样做,您还可以编写一个非常小的限制性shell来适当地锁定内容.
巧合的是,这个问题引发了我的仔细检查,你会很高兴地知道有能力编写.htaccess文件的用户不能仅仅因为安装了mod_evasive而接管你的盒子(RSRC_CONF是正确的)设置,所以在那一点上对mod_evasive的作者赞不绝口).但是,考虑到你如何描述你的配置,至少有任何能够以Apache身份运行代码的用户(例如,禁止mod_su *之类的,任何可以运行PHP,Perl,CGI的人,等),可以使用IPTables禁止您使用自己的服务器.