【问题标题】:Can I access /dev/urandom with open_basedir in effect?我可以使用有效的 open_basedir 访问 /dev/urandom 吗?
【发布时间】:2012-04-28 12:25:19
【问题描述】:

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

遇到 PHP 错误
严重性:警告
消息:is_readable() [function.is-readable]: open_basedir 限制生效。文件(/dev/urandom)不在允许范围内 路径:(/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;
}

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

【问题讨论】:

    标签: php codeigniter phpass


    【解决方案1】:

    你有一些选择:

    1 - 从真正的 RNG 下载转储(this one 提供基于放射性衰变的转储)并使用它,但请确保您不要一直读取相同的 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 或 vhost 配置中没有例外。

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

    注意

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

    【讨论】:

    • 非常好的解释。
    • 献给2020年读书的人;你可以使用random_bytes()
    【解决方案2】:

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

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

    【讨论】:

    • 其实你是在隐藏问题而不是解决问题。
    【解决方案3】:

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

    【讨论】:

      【解决方案4】:
      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_crypto php nginx stream_socket_enable_crypto 未捕获的异常:无法开源设备 php nginx RAND_BYTES stream_socket_enable_crypto stream_socket_enable_crypto(): SSL

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 2019-07-03
        • 1970-01-01
        • 2011-11-03
        • 2017-11-17
        • 1970-01-01
        • 2013-11-01
        • 1970-01-01
        • 1970-01-01
        相关资源
        最近更新 更多