As what user are you running the iptables
command? If you run iptables
as a non-root user, it will print an error message to stderr
and return an error code, but when you write:
exec('/usr/sbin/iptables --insert INPUT --source example.com --jump DROP', $return);
You are (a) only capturing stdout
and (b) you're not checking the error code. That code runs just fine for me if I run it from the command line as root
. E.g, if in iptables.php
I have this content:
<?php
exec('iptables --insert INPUT --source example.com --jump DROP', $output, $retval);
echo "return code: $retval\n";
echo "output:\n";
print_r($output);
?>
I get as output:
return code: 0
output:
Array
(
)
And I see the rule has been created:
# iptables -S INPUT
-P INPUT ACCEPT
-A INPUT -s 93.184.216.34/32 -j DROP
But if I run the same thing as a non-root user:
$ php iptables.php
iptables v1.8.8 (nf_tables): Could not fetch rule set generation id: Permission denied (you must be root)
return code: 4
output:
Array
(
)
Note that the error message was printed directly on the console and was not cpatured by PHP, so we see an empty output array -- but we do see an error return code. Depending on how you're running the code, you may not be able to see the error message (if you're running this via a web server, the error message may show up in the server error logs).