PHP中shell_exec执行UCI防火墙规则命令无效果且无报错求助
PHP中shell_exec执行UCI防火墙规则无效果的排查与解决
核心排查方向及解决方法
权限缺失:PHP默认以
www-data(或apache、nginx)用户运行,这类普通用户没有修改防火墙配置的权限。解决方法是通过sudo授权:- 用
visudo编辑/etc/sudoers文件,添加一行:www-data ALL=(ALL) NOPASSWD: /usr/sbin/uci, /etc/init.d/firewall - 执行命令时加上
sudo前缀,比如:sudo /usr/sbin/uci add firewall rule
- 用
命令路径不完整:Web进程的环境变量PATH通常比SSH用户更有限,务必使用UCI的绝对路径(一般是
/usr/sbin/uci),避免仅写uci导致命令找不到。未提交配置并重启防火墙:UCI修改规则后,必须执行两步才能生效,SSH操作时可能习惯了,但PHP里要明确加入:
sudo /usr/sbin/uci commit firewall sudo /etc/init.d/firewall restart错误输出未完全捕获:即使加了
2>&1,也要确保整个命令链的错误都被捕获。可以把所有命令拼接成一个字符串并输出结果,比如:$cmd = 'sudo /usr/sbin/uci add firewall rule 2>&1 && ' . 'sudo /usr/sbin/uci set firewall.@rule[-1].src=wan 2>&1 && ' . 'sudo /usr/sbin/uci set firewall.@rule[-1].proto=tcp 2>&1 && ' . 'sudo /usr/sbin/uci commit firewall 2>&1 && ' . 'sudo /etc/init.d/firewall restart 2>&1'; $output = shell_exec($cmd); var_dump($output);通过
var_dump查看输出,就能定位具体错误(比如权限不足、参数错误)。安全模块限制:如果系统开启了SELinux或AppArmor,可能会拦截Web进程执行系统命令。可以临时关闭SELinux测试:
sudo setenforce 0,如果规则生效,再配置SELinux策略放行相关操作。
内容的提问来源于stack exchange,提问作者StealthRT
相关产品推荐
相关产品推荐

