我可以在有效的open_basedir的情况下访问 /dev/urandom 吗?


Can I access /dev/urandom with open_basedir in effect?

我想在Codeigniter中使用phpass-0.3,但由于open_basedir而出现以下错误:

遇到
PHP 错误严重性:警告
消息: is_readable(( [function.is 可读]: open_basedir 限制生效。文件(/dev/urandom( 不在允许的范围内 path(s(: (/home/phginep:/usr/lib/php:/usr/local/lib/php:/tmp(
文件名:phpass-0.3/PasswordHash.php
行号:51

以下代码:

function get_random_bytes($count)
{
    $output = '';
    if (is_readable('/dev/urandom') &&    //Line Number: 51
        ($fh = @fopen('/dev/urandom', 'rb'))) {
        $output = fread($fh, $count);
        fclose($fh);
    }
    if (strlen($output) < $count) {
        $output = '';
        for ($i = 0; $i < $count; $i += 16) {
            $this->random_state =
                md5(microtime() . $this->random_state);
            $output .=
                pack('H*', md5($this->random_state));
        }
        $output = substr($output, 0, $count);
    }
    return $output;
}

我能做些什么来解决这个问题吗?

这里有一些选择:

1 - 从真正的 RNG 下载转储(这个提供基于放射性衰变的转储(并使用它,只要确保您不会继续读取相同的 nn 字节。有点笨拙,但是一种选择。

2 - 让 PHP 代表它执行从/dev/urandom读取的内容(UGLY(

3 - 依靠mt_rand()(也很丑陋,但我已经看到这样做了(:

 for ($i = 0; $i < $count / 8; $i++) {
   $output .= dechex(mt_rand(0, 0x7fffffff));
 }

不幸的是,所有选项都是笨拙和丑陋的。最好的办法是确保您不必处理open_basedir。尽管如此,这种特殊的烦恼还是可以解决的。

最后 - 不太可能与您的主人一起飞行,但也许值得一试:

您可以要求主机在主目录中提供urandom,以便您阅读。告诉他们您需要访问 urandom 以生成随机数,以便为用户提供更好的安全性,然后要求他们运行:

mknod urandom c 1 9

在您的主目录中。我刚刚在我自己的服务器上尝试过,它可以工作(但 root 需要为您完成(。没有实际的理由阻止您使用系统的伪随机数生成器,您可以使用 PHP 以外的任何东西来做。这实际上是他们让您访问urandom的最简单方法,因为它不需要在 PHP 或虚拟主机配置中为您例外。

禁止访问/dev/random是一件合理的事情,因为/dev/random必须由可用的(新(系统熵补充,并且如果用尽,可能会导致重要的事情在读取时阻塞,这在低流量服务器上经常发生。但是,/dev/urandom保证永远不会阻塞,因为它只是在耗尽后重用内部熵池,这就是为什么它是一个质量较低的来源。

注意

我并不是说open_basedir的想法不好,但它也破坏了好的代码。经典的chroot要好得多,但更难,这就是为什么你遇到open_basedir比真正的chroot要多得多。至少,任何程序都应该能够访问服务器上的nullzerourandom设备。

phpass 正在尝试访问 /dev/urandom ,这在您的php.ini中是不允许的若要解决此问题,必须禁止显示警告。为此,只需在is_readable之前添加@,如下所示:

...
@is_readable('/dev/urandom')
...

看起来您在共享主机主机上,并且他们已经将 PHP 配置为仅允许您访问帐户中的文件和目录(这是有道理的(。如果是这种情况,您无能为力,因为共享主机不允许更改以允许您访问该资源。如果您有专用服务器或VPS,则可以更改PHP配置(php.ini(以允许访问该资源。

cd /nginx/chroot/
touch random
touch urandom
mount --bind /dev/random /nginx/chroot/dev/random
mount --bind /dev/urandom /nginx/chroot/dev/urandom

我的 phpmailer 现在已经在 nginx chroot centOS 7 中工作

PHP nginx RAND_BYTES stream_socket_enable_cryptoPHP nginx stream_socket_enable_crypto未捕获的异常:无法打开源设备PHP nginx RAND_BYTES stream_socket_enable_cryptostream_socket_enable_crypto((: SSL