tl;dr – What are the dangers of giving Apache a shell in /etc/passwd?
I'm working on getting mod_evasive set up with Apache to fight DOS attempts. I use the DOSSystemCommand
to run a script that adds the offending IP address to a BANNED chain in iptables.
I've found that the only way that I can get this process to work is if I change Apache's shell from /sbin/nologin
to /bin/bash
. But it's really only one part of the script that fails by not having the shell changed. Here's the DOSSystemCommand
line and the script that it runs:
DOSSystemCommand "/usr/bin/sudo /bin/bash /var/www/html/ban_ip.sh %s"
and the script … (note I'm just in testing.. which is why I have verbose output and short banning periods)
#!/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
So with Apache having a shell of /sbin/nologin
, It'll add the IPTABLES rules and it'll create the at
jobs, but when I get an email with the result of the at jobs, it states that the User is currently unavailable
, so the iptables rules are never deleted. If I give Apache /bin/bash as its shell, the iptables rules are added, the at jobs are created, and the iptables deletion work as expected at their designated time.
So my question is: In what way am I putting my server at risk by giving the Apache user a shell?
Best Answer
The relevant code is at line 224 of mod_evasive.c:
Now, let's check
man 3 system
:We can see, then, that the command specified is being run within a shell. Admittedly, the
system(3)
documentation is confusing on this point, but we can certainly see what is happening and make the appropriate inferences—it's being run in the user's default shell, not simply/bin/sh
.The correct solution is relatively straightforward: simply replace the
system(3)
call with afork(2)
and anexecve(2)
(or something substantially similar). If you'd rather not do that, you can also write a very small, restrictive shell to lock things down appropriately.Coincidentally, this question triggered me to double-check, and you'll be pleased to know that a user with the ability to write an .htaccess file can't take over your box solely by virtue of mod_evasive being installed (
RSRC_CONF
is the correct setting, so kudos to the author of mod_evasive on that point). However, given how you've described your configuration, there's an excellent chance that, at minimum, any user with the ability to run code as Apache (e.g., barringmod_su*
or the like, anyone who can run PHP, Perl, CGI, etc.), can ban you out of your own server using IPTables.