I am trying to configure mod_evasive in my CENTOS7 server (VPS) to prevent DDOS attacks.
I followed the steps mentioned in the following tutorial. (this link) Although I am not using IPTABLES, I am using firewalld instead.
In mod_evasive, the directive to execute a shell command when an IP is blacklisted is DOSSystemCommand
. But when an IP is blocked, the script I want to run which will submit the IP address to firewalld to block, is blocked by SeLinux. According to what I understood after looking at the audit.log is, SeLinux does not allow apache user to run a command as sudo. Even though this is allowed via the sudoers file.
(mod_evasive is working properly, I verified this my running the test script provided by mod_evasive. I also get the email when an IP is blocked)
Following are the specifics;
mod_evasive.conf file (only the DOSSystemCommand directive shown below)
DOSSystemCommand "sudo /var/www/mod_evasive/ban_ip_mod_evasive.sh"
I have also tried the below variation (with different users too, Ex. root user)
DOSSystemCommand "sudo -u apache '/var/www/mod_evasive/ban_ip_mod_evasive.sh %s'"
Sudoers file (only the part I have modified for this purpose [allow apache to run as sudo)
apache ALL=(ALL) NOPASSWD:ALL
Defaults:apache !requiretty
I have allowed apache to run as any user for all scripts, just for testing purposes. Initially I had restricted the command as follows
apache ALL=NOPASSWD: /usr/local/bin/myscripts/ban_ip.sh
Defaults:apache !requiretty
My ban_ip.sh file
#!/bin/sh
# IP that will be blocked, as detected by mod_evasive
IP=$1
sudo firewall-cmd --add-rich-rule 'rule family="ipv4" source address="`$IP" service name="https" reject'
I have verified that the configuration is working by running the following
sudo -u apache '/usr/local/bin/myscripts/ban_ip.sh 111.111.111.111'
The above command successfully adds the rule to firewalld.
This entire setup works when I disable SeLinux.
After I enable SeLinux the following errors appear in the audit.log
type=AVC msg=audit(1593067671.808:1363): avc: denied { setuid } for pid=3332 comm="sudo" capability=7 scontext=system_u:system_r:httpd_sys_script_t:s0 tcontext=system_u:system_r:httpd_sys_script_t:s0 tclass=capability permissive=0
Was caused by:
Missing type enforcement (TE) allow rule.
You can use audit2allow to generate a loadable module to allow this access.
type=AVC msg=audit(1593067671.808:1364): avc: denied { setgid } for pid=3332 comm="sudo" capability=6 scontext=system_u:system_r:httpd_sys_script_t:s0 tcontext=system_u:system_r:httpd_sys_script_t:s0 tclass=capability permissive=0
Was caused by:
Missing type enforcement (TE) allow rule.
You can use audit2allow to generate a loadable module to allow this access.
The following flags are set in SeLinux
httpd_mod_auth_pam
httpd_setrlimit
I am not sure why SeLinux blocks this, therefore I am skeptical to create a custom policy to allow this behavior as audit2allow suggests.
audit2allow output
#============= httpd_sys_script_t ==============
allow httpd_sys_script_t self:capability { setgid setuid };
#============= httpd_t ==============
allow httpd_t systemd_logind_t:dbus send_msg;
I feel mod_evasive would not help in stopping a DDOS if we can not block the IP rather than merely sending a 403 forbidden
response to the attacker. This will still consumer the server resources.
How can I solve this and what other alternatives I can implement to mitigate DDOS and enhance my VPS protection?
thanks for your help