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?
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.Why does apache need to run this script? It looks like you are elevating apache to root, and assigning it a shell when you could just run the script as root.
Giving apache sudo access is a lot like locking all the doors and windows of a building... but also installing an overhead door for a shipping dock and leaving it wide open. (A user will in theory only have access to certain things in the shipping bay... but they have none the less gained entry to the building and can begin prying for further entry points.
Giving the apache user a shell to go with said sudo access is a lot like leaving a key cutter in said shipping bay. With enough luck an attacker can make the keys (gain access/privileges) he/she needs.
https://unix.stackexchange.com/questions/78985/deleting-users-with-nologin-shell As per the above question: the /bin/nologin shell prevents anyone from logging in as the user in question (see: console,ssh,su,etc).
You can also take a look at : https://security.stackexchange.com/questions/5707/recommendations-for-changing-the-default-shell-for-service-accounts -- a discussion of the security of nologin vs /dev/null as the shell.