Put*_*nik 3 setuid permissions iptables
假设有一个 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
Run Code Online (Sandbox Code Playgroud)
使用 suid 位。我想添加额外的 IP 验证以避免 XSS 和其他坏事(如果你愿意,可以考虑它的偏执),所以不想让网站直接调用 iptables。
该脚本不起作用,can't initialize iptables table 'filter': Permission denied (you must be root)
因为bash 丢弃了 suid 位
有解决方法:在 sudo 中允许iptables,但我认为它不安全。我没有时间/不可能开发/购买可以完成任务的二进制文件。有人建议围绕脚本进行二进制包装,但我犹豫了,也许有更好的方法?
所以,问题是:如何允许非 root 应用程序以安全的方式阻止 iptables 防火墙中的 ip?
不是让你的 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]
Run Code Online (Sandbox Code Playgroud)
然后确保您的 PHP 脚本始终将每个 IP 地址八位字节格式化为三位数。
如果让 PHP 调用 sudo 太难(它不应该如此!),您可以让脚本自行完成,例如:
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]
Run Code Online (Sandbox Code Playgroud)
(我不完全确定 iptables 会对前导 0 感到满意,如果不是,您可以将它们去掉)。
PS:请在您的 shell 脚本中引用您的变量:
#!/bin/sh
[ "$(id -u)" -eq 0 ] || exec sudo -- "$0" "$@"
# rest of script here
Run Code Online (Sandbox Code Playgroud)