PHP无法从NFS共享中读取会话


PHP cannot read sessions from NFS share

我将PHP会话文件存储在NFS共享上。问题是,PHP总是创建一个空的会话文件,但不能读/写它,所以为每个页面重新加载一个新文件创建。

如果我将会话存储路径移动到本地文件夹,会话将正常保存。另外,我正在运行具有相同配置的另一个环境,它工作得很好。

在PHP有这个问题的同一服务器上,我能够在会话保存的相同目录中创建/写/读文件(与root,非root和www-data用户进行测试)。

我使用PHP 5.5.12, Apache 2.4.9和NFS v3在Ubuntu 12.04 LTS

我的php . ini中

session.save_handler = files
session.save_path = "2;/mnt/cache/sessions"
session.use_cookies = 1
session.use_only_cookies = 0
session.name = PHPSESSID
session.auto_start = 0
session.cookie_lifetime = 2592000
session.cookie_path = /
session.cookie_domain =
session.cookie_httponly =
session.serialize_handler = php
session.gc_probability = 1
session.gc_divisor = 1000
session.gc_maxlifetime = 2592000
session.bug_compat_42 = Off
session.bug_compat_warn = Off
session.referer_check =
session.entropy_length = 0
session.cache_limiter = nocache
session.cache_expire = 180
session.use_trans_sid = 0
session.hash_function = 0
session.hash_bits_per_character = 5
我的挂载

nfs-srv.local:/export/cache   /mnt/cache   nfs    rw,hard,intr  0  0

我/etc/exports nfs-srv.local

/export/cache 10.1.10.0/24(rw,nohide,insecure,no_subtree_check,async,all_squash,anonuid=33,anongid=33)
会话文件

ls /mnt/cache/sessions/ -l
drwxrwxrwx 34 nobody nogroup 4096 May 16 10:33 0
drwxrwxrwx 34 nobody nogroup 4096 May 16 10:33 1
drwxrwxrwx 34 nobody nogroup 4096 May 16 10:33 2
...
ls /mnt/cache/sessions/m -l
drwxrwxrwx 2 nobody nogroup 4096 May 16 10:33 0
drwxrwxrwx 2 nobody nogroup 4096 May 16 12:18 1
drwxrwxrwx 2 nobody nogroup 4096 May 16 10:33 2
drwxrwxrwx 2 nobody nogroup 4096 May 16 10:33 3
drwxrwxrwx 2 nobody nogroup 4096 May 16 12:16 4
drwxrwxrwx 2 nobody nogroup 4096 May 16 12:14 5
...
ls /mnt/cache/sessions/m/5 -l
-rw------- 1 nobody nogroup 0 May 16 12:14 sess_m5ifehvhkjdisp7dgtiuu601e2

我想我已经找到了这个问题的根本原因,当我从PHP 5.5.10升级到5.6.5时也遇到了这个问题。

PHP 5.5.12的更新日志中列出了以下错误修复:

当会话。Save_path是一个每个人都可以写入的目录(像在Debian上),即使不可能找到的id对于已经存在的会话,本地攻击者可以直接创建一个新的会话文件使用恶意会话数据,chmod为666并访问任何web应用程序使用他选择的会话ID托管在系统上。然后是web应用程序打开会话文件并将其视为已创建的文件。我的解决办法:Fstat()会话,检查创建文件的uid。如果它是既不是getuid()的结果,也不是uid 0,忽略现有文件。

简而言之,如果它们发现新创建的会话文件不属于运行Apache的用户帐户或root帐户,它们将停止写入会话数据。这是相当荒谬的,因为NFS在不同级别实现其安全性,但通常使用远程 UID/GID映射部署,并且经常被压缩。因此,Apache用户在创建文件的微秒内就不再拥有文件了。这意味着,从PHP 5.5.12起(或5.4.28包含相同的'fix'),在大多数常规NFS服务器上存储会话数据变得不可能。

当使用idmapd服务时,所有映射都首先通过/etc/nsswitch.conf查找用户名/组名来执行。如果您的NFS机器实际上没有可访问的用户名/组名,idmapd将不会完成映射。

在本例中,似乎在NFS客户机和NFS服务器上都需要一个www-data用户。如果您不想编辑本地/etc/passwd /etc/group文件,以确保麻烦的服务器有一个www-data条目,您可以配置ldap或nis系统通过/etc/nsswitch.conf来管理用户/组域。