When running the following script as user ec2-user, I get the error message iptables v1.4.18: can't initialize iptables table filter: Permission denied (you must be root)


# Offending IP as detected by mod_evasive
# Add the following firewall rule (block IP)

How can I run iptables as a non-root user to block a IP address?

NB: This script is usually called by mod_evasive

closed as off-topic by MadHatter, kasperd, Tom O'Connor Oct 13 '14 at 9:58

This question appears to be off-topic. The users who voted to close gave this specific reason:

  • "Questions must demonstrate a minimal understanding of the problem being solved. Try including attempted solutions, why they didn't work, and the expected results. See How can I ask better questions on Server Fault? for further guidance." – kasperd, Tom O'Connor
If this question can be reworded to fit the rules in the help center, please edit the question.

  • Be very careful with that, be sure that $IPTABLES var is the right absolute path to the binary. – Xavier Lucas Oct 12 '14 at 16:01
  • @XavierLucas: The path is correct: "IPTABLES="/sbin/iptables" – AlexR Oct 12 '14 at 16:04

Set the setuid bit on the script, so that it always runs as root.

chown root myscript
chmod u+s myscript
  • Hi Michael, when trying to run the script, I do get the error message: command not found. What permissions would I need to change? Any idea? – AlexR Oct 12 '14 at 16:02
  • What command is not found? – Michael Hampton Oct 12 '14 at 16:09
  • The script itself: When I enter the command in bash: "sudo ban_ip.sh", I do get: "sudo: ban_ip.sh: command not found". But the script file is there. – AlexR Oct 12 '14 at 16:11
  • @AlexR Why are you trying to sudo ? Also if it's not in your PATH you need to use the absolute path ./ban_ip.sh. – Xavier Lucas Oct 12 '14 at 16:17
  • @XavierLucas: With or without sudo: It does not work. I am in the same directory as the script when trying to execute it. – AlexR Oct 12 '14 at 16:19

Based on another comment you made here the issue you're experiencing is bash cannot find the script you are trying to run.

When you are running a script or command that isn't in one of the paths defined in your $PATH environment setting you need to provide the absolute or relative path for it. For example:

  • If the script is in /usr/local/bin you need to run /usr/local/bin/scriptname.sh.
  • If the script is in your home directory you need to run either /home/username/scriptname.sh or ~/scriptname.sh.
  • Alternatively you can change into that directory and call it with ./ like so: ./scriptname.sh

Also you can update your $PATH environment setting with the path to the script by modifying .bash_profile, .bashrc, or .profile, depending on what env file you're using.


Just add sudo before the command:

# Offending IP as detected by mod_evasive
# Add the following firewall rule (block IP)
  • 2
    using sudo to gain root privileges is not the same as accomplishing the task without root privileges... – Woodrow Douglass Mar 2 '16 at 12:44

If your script is:


and looks like this:

exec /sbin/iptables -I INPUT -s "$1" -j DROP

Then add a line to your /etc/sudoers file that looks something like:

www-data ALL=(root) NOPASSWD: /drop.sh

NB if Apache is running as a user besides www-data you'll need to use that username here. This lets the Apache user run your drop.sh

Then finally a wrapper for mod_evasive:

exec sudo /drop.sh "$@"
  • What's the point putting the script at the root of the filesystem ? Also, you should always use visudo wrapper instead of editing any sudoers file, that's why it's read-only by default. – Xavier Lucas Oct 12 '14 at 18:19
  • You can put files wherever you want, but then you need to explain that all the other paths need to change. – geocar Oct 12 '14 at 19:05

Not the answer you're looking for? Browse other questions tagged or ask your own question.