我有一台 FreeBSD 11 机器,在 chrooted 模式下运行最新的 Nginx 和 PHP-FPM。一切正常,直到我添加start_session();
了index.php
。
这时我收到以下错误:
Fatal error: Uncaught Exception: Cannot open source device in /index.php:5 Stack trace: #0 /index.php(5): session_start() #1 {main} Next Exception: Cannot open source device in /index.php:5 Stack trace: #0 /index.php(5): session_start() #1 {main} Next Exception: Cannot open source device in /index.php:5 Stack trace: #0 /index.php(5): session_start() #1 {main} Next Exception: Cannot open source device in /index.php:5 Stack trace: #0 /index.php(5): session_start() #1 {main} Next Error: Failed to create session ID: files (path: /home/project/customers/john/tmp) in /index.php:5 Stack trace: #0 /index.php(5): session_start() #1 {main} thrown in /index.php on line 5
请指教。
nginx.conf
server {
listen 443 ssl http2;
add_header Cache-Control no-cache;
ssl on;
ssl_certificate /home/project/ssl/project.chain;
ssl_certificate_key /home/project/ssl/project.key;
ssl_prefer_server_ciphers on;
server_name john.project.net;
error_log /home/project/logs/john-error.log;
access_log /home/project/logs/john-access.log;
root /home/project/customers/john;
index index.php;
location / { deny all; }
location = / { }
location = /index.php {
include fastcgi_params;
fastcgi_index index.php;
fastcgi_param SCRIPT_FILENAME $fastcgi_script_name;
fastcgi_pass unix:/var/run/php-fpm-project-john.sock;
try_files $uri =404;
}
location ~ \.(txt|css|map|jpg|png|gif|ico|htc|otf|eot|svg|ttf|woff|woff2|js|ogg)$ { }
}
php-fpm.conf
[project-john]
prefix = /home/project/customers/john
user = www
group = www
listen = /var/run/php-fpm-project-john.sock
listen.owner = www
listen.group = www
listen.mode = 0660
pm = dynamic
pm.max_children = 5
pm.start_servers = 2
pm.min_spare_servers = 1
pm.max_spare_servers = 3
chroot = $prefix
chdir = /
php_admin_value[session.save_path] = /home/project/customers/john/tmp ; Writable
index.php
<?php
ini_set('display_errors', 1);
echo "test";
session_start();
?>
答案1
您的php_admin_value[session.save_path]
必须是相对于 chroot 路径的。(chroot 之后,它只需显示为/tmp
)。现在它在进程根中寻找该值,这导致它寻找 的“真实路径” /home/project/customers/john/home/project/customers/john/tmp
,但该路径不太可能存在。
答案2
PHP 会话默认依赖它/dev/urandom
来生成随机 ID,这在 PHP-FPM chrooted 模式下当然是无法访问的。还有数百个其他操作系统依赖项,我的项目需要它们才能正常运行。
此时,我放弃了使用 PHP-FPM 的 chrooted 模式的任何可能的机会。
但是如果有人仍然感兴趣,您需要 mount:
/dev/urandom
to /home/project/customers/john/dev/urandom
。
https://www.vennedey.net/resources/3-Secure-webspaces-with-NGINX-PHP-FPM-chroots-and-Lets-Encrypt