假设有一个php网站,我想根据网站代码执行在防火墙级别阻止一个ip。该站点在非 root 用户下运行。
我打算将 IP 从站点代码传递到脚本(只能写入 root),例如
#!/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
使用 suid 位。我想添加额外的 IP 验证以避免 XSS 和其他不好的事情(如果你愿意,可以考虑偏执),所以不想让网站直接调用 iptables。
该脚本不起作用,can't initialize iptables table 'filter': Permission denied (you must be root)
因为bash 删除 suid 位
有解决方法:允许sudo 中的 iptables但我认为它不安全。我没有时间/可能性来开发/购买可以完成任务的二进制文件。有人建议对脚本进行二进制包装,但我犹豫了,也许有更好的方法?
所以,问题是:如何允许非 root 应用程序以安全的方式阻止 iptables 防火墙中的 ip?
答案1
不要让 bash 脚本成为 suid root,而是通过 sudo 运行 bash 脚本。作为一个附带好处,这还可以让您轻松锁定谁可以以 root 身份运行您的脚本以及传递的参数。例如,您可以只允许:
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]
然后确保您的 PHP 脚本始终将每个 IP 地址八位字节的格式设置为三位数字。
如果让 PHP 调用 sudo 太困难(不应该这样!),您可以让脚本自己执行此操作,例如:
#!/bin/sh
[ "$(id -u)" -eq 0 ] || exec sudo -- "$0" "$@"
# rest of script here
(我不完全确定 iptables 会满意前导 0,如果不满意,您可以将它们去掉)。
PS:请在 shell 脚本中引用您的变量:
if validate_ip "$1"; then
/usr/sbin/iptables -I INPUT -s "$1" -j DROP
# ⋮