手动编译PHP8.4调用session_start()时触发无法打开/dev/urandom的致命错误排查与解决
最近在Ubuntu 14.04上手动编译了PHP8.4.0-dev(因为系统已停止支持,没有可用的PPA包),一开始phpinfo()页面显示一切正常,但当我在脚本头部加上session_start()时,直接抛出了致命错误:
Fatal error: Uncaught Random\RandomException: Cannot open /dev/urandom: No such file or directory in /xxx.php
我第一时间在终端测试了head /dev/urandom,能正常输出随机内容,说明文件确实存在;用ls -l /dev/urandom查看权限,显示是crw-rw-rw-,理论上任何用户都能访问,这就让人困惑了。
环境信息
先给大家列一下我的环境细节:
- 服务器硬件:RK3288 armv7l cortex-A17 四核,搭配2GB DDR3内存
- 操作系统:Ubuntu 14.04 LTS,内核版本3.10.0
- Web服务器:Apache 2.4.7 + PHP-FPM FastCGI
- PHP版本:8.4.0-dev
- PHP编译时的配置命令:
'./configure' '--prefix=/usr/local/php/' '--enable-debug' \ '--enable-fpm' '--with-config-file-path=/usr/local/php/etc/' \ '--enable-json' '--enable-mbregex' '--enable-mbregex-backtrack' \ '--disable-opcache' '--with-curl' '--with-freetype' \ '--enable-gd' '--with-jpeg' '--with-gettext' '--with-kerberos' \ '--with-libdir=lib64' '--with-libxml' '--with-mysqli' \ '--with-openssl' '--with-pdo-mysql' '--with-pdo-sqlite' \ '--with-pear' '--with-mhash' '--with-ldap-sasl' '--with-xsl' \ '--with-zlib' '--with-zip' '-with-bz2' '--with-iconv' \ '--enable-pdo' '--enable-ftp' '--enable-bcmath' '--enable-mbstring' \ '--disable-pcntl' '--enable-shmop' '--enable-soap' \ '--enable-sockets' '--enable-xml' '--enable-sysvsem' '--enable-cli' \ '--enable-intl' '--enable-calendar' '--enable-static' \ '--enable-mysqlnd' 'OPENSSL_CFLAGS=-I/usr/local/openssl/include' \ 'OPENSSL_LIBS=-L/usr/local/openssl/lib -lssl -lcrypto' \ 'JPEG_CFLAGS=-I/usr/lib/arm-linux-gnueabihf/' \ 'JPEG_LIBS=-L/usr/lib/arm-linux-gnueabihf/ -ljpeg' \ 'FREETYPE2_CFLAGS=-I/usr/include/freetype2' \ 'FREETYPE2_LIBS=-L/usr/lib/arm-linux-gnueabihf/ -lfreetype' \ 'ICU_CFLAGS=-I/usr/include/arm-linux-gnueabihf/' \ 'ICU_LIBS=-L/usr/lib/arm-linux-gnueabihf/ -licui18n \ -licuuc -licudata -licuio -licule -liculx -licutu' \ 'ONIG_CFLAGS=-I/usr/include' 'ONIG_LIBS=-L/usr/lib -lonig' \ 'LIBZIP_CFLAGS=-I/usr/local/include/' \ 'LIBZIP_LIBS=-L/usr/local/lib/ -lzip'
编译前我已经手动解决了所有依赖缺失的问题,确保configure没有报错。
排查与解决过程
一开始完全不知道从哪里入手,后来看到@symcbean的提示:PHP代码可能运行在chroot环境、AppArmor配置或者systemd文件系统命名空间里。
顺着这个思路,我检查了PHP-FPM的配置文件,发现确实设置了chroot参数。取消这个参数后,访问PHP脚本时又出现了“No input file specified”的错误。
我尝试修改Apache配置,想用ProxyFCGISetEnvIf "true" PHP_ADMIN_VALUE "open_basedir=..."来指定路径,但我的Apache版本不支持这个指令,直接抛出了“Invalid command”的错误。
最后我换了个思路,修改Apache的ProxyPassMatch规则:
把原来的:
ProxyPassMatch ^/(.*\.php(/.*)?)$ fcgi://127.0.0.1:9000/
替换成:
ProxyPassMatch ^/(.*\.php(/.*)?)$ fcgi://127.0.0.1:9000/path/to/webroot/$1
替换完成后,所有问题都解决了!
总结
给大家提个醒:如果PHP出现类似“No such file or directory”的错误,优先检查是否给PHP设置了chroot环境,这大概率是问题的根源。
备注:内容来源于stack exchange,提问作者NeNe

