PHP: 文件写入权限
PHP: file write permissions
因为这个我一直在敲我的头很长一段时间...
我正在尝试在我的虚拟服务器(CentOS 7、apache http 服务器、php 5.4.3)上安装 MyBB 论坛,但我 运行 遇到文件权限问题。 MyBB需要两个文件可写,其中一个是config.php
,第二个是settings.php
,它们都在目录inc
.
我将两个文件的权限设置为 666。我写了一个简单的测试 php 页面,模仿 MyBB 测试写入能力的方式:
<?php
echo('config: ');
$configwritable = @fopen('forum/inc/config.php', 'w');
if ($configwritable) {
echo('yes');
} else {
echo('no');
}
echo('<br/>');
echo('settings: ');
$configwritable = @fopen('forum/inc/settings.php', 'w');
if ($configwritable) {
echo('yes');
} else {
echo('no');
}
?>
页面输出为
config: no
settings: yes
但是如果我列出文件,它们会像这样显示
root@localhost# ls -l forum/inc/config.php forum/inc/settings.php
-rw-rw-rw-. 1 krkavec krkavec 0 2. říj 22.49 forum/inc/config.php
-rw-rw-rw-. 1 krkavec krkavec 0 2. říj 22.51 forum/inc/settings.php
怎么可能?这两个文件属于同一个用户,属于同一个组,具有相同的大小(零),在同一个目录中,具有相同的权限,具有几乎相同的修改时间(相差两分钟)以及几乎所有其他东西,除了他们的名字是一样的。
为了让事情变得更奇怪,我尝试再次删除和创建文件,观看:
1:删除两个文件
root@localhost# rm -f forum/inc/config.php forum/inc/settings.php
和页面输出:
config: no
settings: no
没关系,因为 inc
目录不应该是可写的。
2:创建settings.php
root@localhost# F=forum/inc/settings.php ; touch $F ; chown krkavec:krkavec $F ; chmod 666 $F
root@localhost# ls -l forum/inc/settings.php forum/inc/config.php
ls: cannot access forum/inc/config.php: No such file or directory
-rw-rw-rw-. 1 krkavec krkavec 0 2. říj 23.15 forum/inc/settings.php
和页面输出:
config: no
settings: yes
这完全没问题,符合预期 - 文件在那里并且具有可写权限。
3: 创建 config.php
root@localhost# F=forum/inc/config.php ; touch $F ; chown krkavec:krkavec $F ; chmod 666 $F
root@localhost# ls -l forum/inc/settings.php forum/inc/config.php
-rw-rw-rw-. 1 krkavec krkavec 0 2. říj 23.23 forum/inc/config.php
-rw-rw-rw-. 1 krkavec krkavec 0 2. říj 23.15 forum/inc/settings.php
和页面输出:
config: no
settings: yes
砰!我完全希望配置是可写的。
非常感谢任何帮助。
编辑: 我根据Marc B和drew010的建议修改了测试页面
<?php
error_reporting(E_ALL);
ini_set('display_errors', 1);
echo('config var_dump: ');
var_dump(stat('forum/inc/config.php'));
echo('<br/>config: ');
$configwritable = fopen('forum/inc/config.php', 'w');
if ($configwritable) {
echo('yes');
} else {
echo('no');
}
echo('<br/>');
echo('settings var_dump: ');
var_dump(stat('forum/inc/settings.php'));
echo('<br/>settings: ');
$configwritable2 = fopen('forum/inc/settings.php', 'w');
if ($configwritable2) {
echo('yes');
} else {
echo('no');
}
?>
页面的输出(两个文件都存在)是:
config var_dump: array(26) { [0]=> int(64768) [1]=> int(19155212) [2]=> int(33206) [3]=> int(1) [4]=> int(1000) [5]=> int(1000) [6]=> int(0) [7]=> int(0) [8]=> int(1443821772) [9]=> int(1443821772) [10]=> int(1443821772) [11]=> int(4096) [12]=> int(0) ["dev"]=> int(64768) ["ino"]=> int(19155212) ["mode"]=> int(33206) ["nlink"]=> int(1) ["uid"]=> int(1000) ["gid"]=> int(1000) ["rdev"]=> int(0) ["size"]=> int(0) ["atime"]=> int(1443821772) ["mtime"]=> int(1443821772) ["ctime"]=> int(1443821772) ["blksize"]=> int(4096) ["blocks"]=> int(0) }
config:
Warning: fopen(forum/inc/config.php): failed to open stream: Permission denied in /var/www/html/test.php on line 8
no
settings var_dump: array(26) { [0]=> int(64768) [1]=> int(19155069) [2]=> int(33206) [3]=> int(1) [4]=> int(1000) [5]=> int(1000) [6]=> int(0) [7]=> int(0) [8]=> int(1443821763) [9]=> int(1443823158) [10]=> int(1443823158) [11]=> int(4096) [12]=> int(0) ["dev"]=> int(64768) ["ino"]=> int(19155069) ["mode"]=> int(33206) ["nlink"]=> int(1) ["uid"]=> int(1000) ["gid"]=> int(1000) ["rdev"]=> int(0) ["size"]=> int(0) ["atime"]=> int(1443821763) ["mtime"]=> int(1443823158) ["ctime"]=> int(1443823158) ["blksize"]=> int(4096) ["blocks"]=> int(0) }
settings: yes
出于某种未知的神奇原因,当我将 settings.php
重命名为 config.php
然后创建新的 settings.php
并适当设置权限时,两个文件都是可写的。
但是,我不知道为什么必须重命名该文件。结果与问题中描述的步骤 3 之后的结果相同,只是它有效。
非常欢迎任何建议为什么要完成这顶帽子及其背后的原因。
EDIT:这是由 SELinux 安全上下文阻止 apache 写入文件引起的。 运行 chcon -t httpd_sys_rw_content_t config.php
解决了问题。
因为这个我一直在敲我的头很长一段时间...
我正在尝试在我的虚拟服务器(CentOS 7、apache http 服务器、php 5.4.3)上安装 MyBB 论坛,但我 运行 遇到文件权限问题。 MyBB需要两个文件可写,其中一个是config.php
,第二个是settings.php
,它们都在目录inc
.
我将两个文件的权限设置为 666。我写了一个简单的测试 php 页面,模仿 MyBB 测试写入能力的方式:
<?php
echo('config: ');
$configwritable = @fopen('forum/inc/config.php', 'w');
if ($configwritable) {
echo('yes');
} else {
echo('no');
}
echo('<br/>');
echo('settings: ');
$configwritable = @fopen('forum/inc/settings.php', 'w');
if ($configwritable) {
echo('yes');
} else {
echo('no');
}
?>
页面输出为
config: no
settings: yes
但是如果我列出文件,它们会像这样显示
root@localhost# ls -l forum/inc/config.php forum/inc/settings.php
-rw-rw-rw-. 1 krkavec krkavec 0 2. říj 22.49 forum/inc/config.php
-rw-rw-rw-. 1 krkavec krkavec 0 2. říj 22.51 forum/inc/settings.php
怎么可能?这两个文件属于同一个用户,属于同一个组,具有相同的大小(零),在同一个目录中,具有相同的权限,具有几乎相同的修改时间(相差两分钟)以及几乎所有其他东西,除了他们的名字是一样的。
为了让事情变得更奇怪,我尝试再次删除和创建文件,观看:
1:删除两个文件
root@localhost# rm -f forum/inc/config.php forum/inc/settings.php
和页面输出:
config: no
settings: no
没关系,因为 inc
目录不应该是可写的。
2:创建settings.php
root@localhost# F=forum/inc/settings.php ; touch $F ; chown krkavec:krkavec $F ; chmod 666 $F
root@localhost# ls -l forum/inc/settings.php forum/inc/config.php
ls: cannot access forum/inc/config.php: No such file or directory
-rw-rw-rw-. 1 krkavec krkavec 0 2. říj 23.15 forum/inc/settings.php
和页面输出:
config: no
settings: yes
这完全没问题,符合预期 - 文件在那里并且具有可写权限。
3: 创建 config.php
root@localhost# F=forum/inc/config.php ; touch $F ; chown krkavec:krkavec $F ; chmod 666 $F
root@localhost# ls -l forum/inc/settings.php forum/inc/config.php
-rw-rw-rw-. 1 krkavec krkavec 0 2. říj 23.23 forum/inc/config.php
-rw-rw-rw-. 1 krkavec krkavec 0 2. říj 23.15 forum/inc/settings.php
和页面输出:
config: no
settings: yes
砰!我完全希望配置是可写的。
非常感谢任何帮助。
编辑: 我根据Marc B和drew010的建议修改了测试页面
<?php
error_reporting(E_ALL);
ini_set('display_errors', 1);
echo('config var_dump: ');
var_dump(stat('forum/inc/config.php'));
echo('<br/>config: ');
$configwritable = fopen('forum/inc/config.php', 'w');
if ($configwritable) {
echo('yes');
} else {
echo('no');
}
echo('<br/>');
echo('settings var_dump: ');
var_dump(stat('forum/inc/settings.php'));
echo('<br/>settings: ');
$configwritable2 = fopen('forum/inc/settings.php', 'w');
if ($configwritable2) {
echo('yes');
} else {
echo('no');
}
?>
页面的输出(两个文件都存在)是:
config var_dump: array(26) { [0]=> int(64768) [1]=> int(19155212) [2]=> int(33206) [3]=> int(1) [4]=> int(1000) [5]=> int(1000) [6]=> int(0) [7]=> int(0) [8]=> int(1443821772) [9]=> int(1443821772) [10]=> int(1443821772) [11]=> int(4096) [12]=> int(0) ["dev"]=> int(64768) ["ino"]=> int(19155212) ["mode"]=> int(33206) ["nlink"]=> int(1) ["uid"]=> int(1000) ["gid"]=> int(1000) ["rdev"]=> int(0) ["size"]=> int(0) ["atime"]=> int(1443821772) ["mtime"]=> int(1443821772) ["ctime"]=> int(1443821772) ["blksize"]=> int(4096) ["blocks"]=> int(0) }
config:
Warning: fopen(forum/inc/config.php): failed to open stream: Permission denied in /var/www/html/test.php on line 8
no
settings var_dump: array(26) { [0]=> int(64768) [1]=> int(19155069) [2]=> int(33206) [3]=> int(1) [4]=> int(1000) [5]=> int(1000) [6]=> int(0) [7]=> int(0) [8]=> int(1443821763) [9]=> int(1443823158) [10]=> int(1443823158) [11]=> int(4096) [12]=> int(0) ["dev"]=> int(64768) ["ino"]=> int(19155069) ["mode"]=> int(33206) ["nlink"]=> int(1) ["uid"]=> int(1000) ["gid"]=> int(1000) ["rdev"]=> int(0) ["size"]=> int(0) ["atime"]=> int(1443821763) ["mtime"]=> int(1443823158) ["ctime"]=> int(1443823158) ["blksize"]=> int(4096) ["blocks"]=> int(0) }
settings: yes
出于某种未知的神奇原因,当我将 settings.php
重命名为 config.php
然后创建新的 settings.php
并适当设置权限时,两个文件都是可写的。
但是,我不知道为什么必须重命名该文件。结果与问题中描述的步骤 3 之后的结果相同,只是它有效。
非常欢迎任何建议为什么要完成这顶帽子及其背后的原因。
EDIT:这是由 SELinux 安全上下文阻止 apache 写入文件引起的。 运行 chcon -t httpd_sys_rw_content_t config.php
解决了问题。