Assuming there is a php website and I want to block an ip at the firewall level based on the site code execution. The site is run under non-root user.

I was going to pass IP from the site code to a script (writeable to root only) like

function validate_ip()
{ ... code here ...}
if validate_ip $1; then 
    /usr/sbin/iptables -I INPUT -s $1 -j DROP
    echo 'blocked'; 
    echo 'bad IP $1'; 

using suid bit. I want to add additional IP validation to avoid XSS and other bad things (consider it paranoia if you like), so do not want to allow the site to call iptables directly.

The script does not work can't initialize iptables table 'filter': Permission denied (you must be root) because bash drops suid bit

There is workaround: allow iptables in sudo but I don't think it's secure. I have no time/possibility to develop/buy a binary which will do the task. One suggested binary wrapper around script but I hesitate, perhaps there is a better way?

So, the question is: how can I allow non-root app to block ip in iptables firewall in a secure way?

1 Answer 1


Instead of making your bash script suid root, run your bash script through sudo. As a side benefit, this also lets you easily lock down who can run your script as root and also the arguments passed. You could, for example, only allow:

phpuser ALL=(root) NOPASSWD: /usr/local/sbin/your-script [0-9][0-9][0-9].[0-9][0-9][0-9].[0-9][0-9][0-9].[0-9][0-9][0-9]

then make sure your PHP script always formats each IP address octet as three digits.

If it's too hard to have PHP call sudo (which it shouldn't be!) you can have the script do it itself, with something like:


[ "$(id -u)" -eq 0 ] || exec sudo -- "$0" "$@"
# rest of script here

(I'm not entirely sure iptables will be happy with the leading 0s, if not you can strip them off).

PS: Please quote your variables in your shell script:

if validate_ip "$1"; then 
    /usr/sbin/iptables -I INPUT -s "$1" -j DROP
    # ⋮
  • I tried username ALL=(root) NOPASSWD: /usr/local...., then switched to user's shell and tried sudo /usr/local/script but sudo asked for password here. What am I doing wrong?
    – Putnik
    Commented Sep 22, 2017 at 13:12
  • @Putnik with the example I gave, you have to pad all the numbers
    – derobert
    Commented Sep 22, 2017 at 13:51

You must log in to answer this question.

Not the answer you're looking for? Browse other questions tagged .