Apache下PHP调用winexe出现NT_STATUS_CONNECTION_DISCONNECTED报错求解
问题根因
你遇到的samba_tevent: EPOLL_CTL_ADD failed (Operation not permitted)报错核心原因是Apache运行PHP时的www-data用户所处的沙箱安全限制,阻止了winexe依赖的samba tevent库调用epoll相关系统接口,命令行运行正常是因为登录用户不受Apache服务的安全规则限制。
可行解决方案
- 方案1:配置sudo提权运行winexe(最推荐,改动最小安全性高)
- 执行
visudo编辑sudo规则,添加如下一行:
www-data ALL=(ALL) NOPASSWD: /usr/bin/winexe- 修改PHP中调用的命令,添加sudo前缀:
<?php // 示例调用 $cmd = "sudo /usr/bin/winexe -U Administrador%xxxx -d 5 --interactive=0 //192.168.2.99 systeminfo"; $output = shell_exec($cmd); echo $output; ?> - 执行
- 方案2:放宽Apache systemd服务的沙箱限制
如果你不想用sudo,可修改Apache服务的systemd配置解除epoll调用限制:- 执行
systemctl edit apache2.service编辑自定义配置,添加如下内容:
[Service] RestrictSUIDSGID=no ProtectKernelTunables=no PrivateDevices=no SystemCallFilter=@default epoll_create epoll_ctl epoll_wait- 重载配置重启服务:
systemctl daemon-reload systemctl restart apache2 - 执行
- 方案3:使用proc_open明确处理标准输入输出
避免PHP继承Apache的文件描述符导致tevent库异常:<?php $descriptors = [ 0 => ["pipe", "r"], 1 => ["pipe", "w"], 2 => ["pipe", "w"] ]; $cmd = "sudo /usr/bin/winexe -U Administrador%xxxx -d 5 --interactive=0 //192.168.2.99 systeminfo"; $proc = proc_open($cmd, $descriptors, $pipes); fclose($pipes[0]); $stdout = stream_get_contents($pipes[1]); $stderr = stream_get_contents($pipes[2]); fclose($pipes[1]); fclose($pipes[2]); $exitCode = proc_close($proc); // 处理输出 var_dump($stdout, $stderr, $exitCode); ?> - 额外排查项
若上述方案无效,可临时关闭AppArmor(Ubuntu)/SELinux(CentOS)验证是否为安全规则拦截:- Ubuntu临时关闭AppArmor Apache规则:
aa-complain /usr/sbin/apache2 - CentOS临时关闭SELinux:
setenforce 0
验证正常后可添加对应规则,无需完全关闭安全组件。
- Ubuntu临时关闭AppArmor Apache规则:
内容的提问来源于stack exchange,提问作者user3227400
相关产品推荐
相关产品推荐

