PHP socket_connect() 权限被拒绝

4

好的,我有一个良好的运行PHP服务器,并使用我编写的以下函数打开了一个AF_UNIX套接字。函数调用如下:

$IPC_connector = socket_create_IPC('/tmp/connection');


function socket_create_IPC($FILE)
{
    #Create a AF_UNIX socket
    if(!($socket = socket_create(AF_UNIX, SOCK_STREAM, 0)))
    {
        $errorcode = socket_last_error();
        $errormsg = socket_strerror($errorcode);

        die("Couldn't create socket: [$errorcode] $errormsg \n");
    }

    #Bind
    if( !socket_bind($socket, $FILE) )
    {
        $errorcode = socket_last_error();
        $errormsg = socket_strerror($errorcode);

        die("Could not bind socket : [$errorcode] $errormsg \n");
    }

    if(socket_listen($socket) === false) 
    {
        die("socket_listen() failed: reason: " . socket_strerror(socket_last_error($socket)) . "\n");
    }

    socket_set_nonblock($socket);

    return $socket;
}

然后我写了一个客户端来连接到这个服务器,就像这样。
if(!($IPC = socket_create(AF_UNIX, SOCK_STREAM, 0)))
{
    $errorcode = socket_last_error();
    $errormsg = socket_strerror($errorcode);

    die("Error:Couldn't create socket - [$errorcode] $errormsg \n");
}
echo "socket_create(): ".socket_strerror(socket_last_error($IPC))."\n";

if(!(socket_connect($IPC, '/tmp/connection')))
    echo "socket_connect() failed, reason: ".socket_strerror(socket_last_error($IPC))."\n";

客户端实际上是通过一个来自网页的AJAX请求进行调用的,它应该连接到服务器,获取一些数据,然后将这些数据返回给网页。AJAX请求是在JavaScript中进行的。我已经测试了客户端/服务器连接而没有使用AJAX请求,并且它可以正常工作,但是一旦我尝试通过网页使用AJAX请求,客户端就会从脚本中的echo语句返回“socket_connect()失败,原因:权限被拒绝”。也许有一些小问题我忽略了吗?我假设Ajax是通过httpd(apache)调用的。我确定这可能是某种文件权限问题,但我无法确定具体是什么引起了这个问题。 我迄今为止尝试过的事情: 确保php.ini中的safe_mode关闭, 尝试“setsebool -P httpd_can_network_connect on”以尝试防止SElinux, 还尝试了“setenforce 0”,但也没有任何影响。 我尝试将/tmp和所有子目录的文件权限更改为777,但没有成功。 我已经想不出更多的主意了,也许有人曾经遇到过这个问题, 我还看了这个文件,这是我的服务器正在创建的文件->
[root@ip-000-000-000-000 tmp]# ls -lZa connection
srwxr-xr-x. root root unconfined_u:object_r:user_tmp_t:s0 connection

如果有人对我使用的AJAX调用感兴趣,可以参考以下内容:

function communication (IP, MechanismID, CommandName) {
    $.post('php/connectDisconnect.php', {
        IP : IP,
        MechanismID : MechanismID,
        CommandName : CommandName
        }, 
        function(data) {
            if(data.search("Error") != -1)
                alert(data);
    });
}

其中connectDisconnect.php是上面提到的客户端。


目前没有时间阅读完整的问题,但首先想到的是同源限制。(如果我完全错了,我会稍后删除这个评论。) - TecBrat
@TecBrat --我看了一下《同源策略》,但我不太确定它是否适用于这里,我可能非常错误,但似乎该策略是用于从网络上的其他地方获取数据。我的问题是连接在同一服务器上运行的两个php脚本?-- 但是,打字让我找到了答案,所以我非常感谢你。 - Drew Mangus
就像我之前说的,我匆忙回答并没有读完整个问题,但我很高兴它还是帮助你找到了一个好的答案。 - TecBrat
1个回答

0
事实证明,ajax调用是以apache用户身份运行的,并且从我的服务器创建的文件套接字属于root。我通过在调用socket_create()的服务器中添加这些几行代码来解决此问题。
#Deletes the old pipe in case the server crashed last time it closed and didn't use socket_close()
$command = "rm -f /tmp/connection";
exec($command);

#Creates the data pipe for the webpage to connect to
$IPC_connector = socket_create_IPC('/tmp/connection');

#Makes it to where the webpage can actually talk to the server
$command = "chown apache:apache /tmp/connection";
exec($command);

这对我来说是一个足够好的解决方法,但我想这可能不是正确的做法。如果有人有更好的建议或更好的实践经验,我很乐意听取。


作为给其他人的提示,只要在 SELinux 中设置 setenforce 0,就可以解决这个问题。我仍在努力解决 SELinux 的问题,以便获得此权限。 - Drew Mangus
我通过http://wiki.centos.org/HowTos/SELinux上的列表中的第7个使用audit2allow修复了这个问题。^_^ - Drew Mangus

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接