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
#!/bin/bash
function validate_ip()
{ ... code here ...}
if validate_ip $1; then
/usr/sbin/iptables -I INPUT -s $1 -j DROP
echo 'blocked';
else
echo 'bad IP $1';
fi
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?
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:
#!/bin/sh
[ "$(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
# ⋮
この記事はインターネットから収集されたものであり、転載の際にはソースを示してください。
侵害の場合は、連絡してください[email protected]
コメントを追加