在Web应用程序中,我想为每个www-data
用户创建一个文件夹,并在该文件夹上提供写入权限,并且只对该用户提供。
验证后我可以这样做:
mkdir($file->getPath().mt_rand(0,100000),0700);
这将在路径$file->getPath()
中创建一个具有随机名称的新目录,其中包含对所有者用户的所有权限。但它会为所有 www-data
用户授予权限。
如果我创建一个chroot jail,我必须为每个用户再次复制所有文件,因为我应该创建许多jails(一个用户)。
我对此感到疯狂,并没有找到解决方案。
答案 0 :(得分:4)
如果我理解你的问题,你的问题就从linux权限/用户框架的结构开始。因此,Apache进程拥有用户是在运行脚本时创建目录和文件的用户。
如果您需要用户分离脚本,例如:您的服务器上的不同(虚拟)主机有不同的目录,并且您不希望一个主机的脚本在同一个主机上处理不同主机的数据( apache)服务器,然后你应该使用'mpm_itk_module'而不是更常见的'mpm-prefork'apache。
使用此功能,您可以定义apache在执行任何脚本时使用的用户/组,例如只需通过此命令为httpd.conf中的每个虚拟主机条目创建目录:
<IfModule mpm_itk_module>
AssignUserId USER GROUP
</IfModule>
如果你真的想从一个脚本执行创建不同的目录,你需要root.root拥有apache进程,然后脚本需要按照你想要的方式为每个directoy设置权限和所有者。
但是,以root身份在网络服务器上运行最好的脚本永远不是一个好主意,因为你可能没有想到任何风险。
在我看来,vhosts的用户/权限分离似乎是一种更加节俭的方式。
另一点 - 仅限PHP - 是suPHP - &gt; http://www.suphp.org
编辑:
好的,我看了一下你的网站,即使我不会讲西班牙语,看起来你只有一个网站,通过这个网页为不同的用户提供服务。那么在Linux文件系统权限上需要用户分离?您可以通过应用程序限制所有内容,而无需文件系统用户。即使你给予,例如额外的ftp访问 - 限制它,例如使用proftpd,它为不同的用户提供了自己的chroot机制。
只有在无法控制执行内容的人时,才应该关心文件系统权限。这是多域主机上的常见问题,您可以使用我提到的mpm_itk_module解决这个问题。
也许你应该多描述一下你的情况?
编辑2:
如同在cament中建议的那样,如果你只使用apache让用户访问上传/操作文件,那么只需将文件放在(!)apache的documentroot树之外,然后创建简单的数据库以了解哪个文件是由哪个用户拥有:
user a | file parentdir/filename
这可能是一个简单的表格,你的php代码从数据库中为用户提供了一个列表,他可以查看/操作哪个文件,你的代码按照用户操作的意图完成工作。
只要您不让用户访问其他服务(ftp,ssh等)的文件,就根本不需要使用Linux用户权限。只需注意将文件放在服务器的文档之外,这样只有你的php代码才能通过服务器的apache用户的权限访问这些文件。
编辑3:
哈哈,在我读完你的类似帖子后,我终于得到了你的问题:(How can an Apache user write files when having permissions to do it?) 在这种情况下(在您的网页上有真正的匿名用户),您根本没有机会解决这个问题。每个访问者都是在没有身份验证的情况下处理的。正如我在上一次编辑中假设并在类似帖子中评论的那样:根本不需要处理linux文件权限。您的解决方案;): 当用户访问您的页面时,您需要在具有session-id的一个会话中执行文件操作。因此,您的代码需要处理访问者(会话ID)与他使用此会话ID上传的文件之间的关系。只要访问者在线,使用有效的会话ID就是最好的方法。再次 - 不需要文件系统权限....;)
第二种方法是使用之前建议的authed用户:创建一个带有用户/密码的db表来登录网页(不是服务器)和另一个保存用户/文件关系的表。在登录网页后,再次使用会话来允许用户访问/操作已上传的文件。
答案 1 :(得分:3)
我可以用mod_php运行apache。那么这意味着你的PHP实例在apache实例下工作并拥有apache USER和GROUP。您可以创建文件夹并可以更改此文件夹的所有者,但所有者必须是您系统中的用户(不是apache或相同的虚拟用户)。
但是您可以存储在每个目录文件中,例如“.permitions”,并将其放入文件虚拟所有者。接下来,您需要过滤每次写入(删除,重命名等)尝试此目录,并比较存储在.permitions文件中的虚拟用户和用户。
示例类(不完整,但它足以理解想法):
class UserDirs {
private $path='/home/vusers';
public function mkdir($user){
$d = $this->path.'/'.md5($user);
mkdir($d);
file_put_contents($d."/.owner",$user);
}
public function checkOwner($user, $dirname){
$f = $dirname."/.owner";
$virtual_owner = file_get_contents($f);
return $user === $virtual_owner;
}
}
$d = new UserDirs()
$d->mkdir("foo","bar");
echo $d->checkOwner("foo1","bar") === true ? "OK":"FAIL";
echo $d->checkOwner("foo","bar") === true ? "OK":"FAIL";
您可以封装此类中所需的所有内容以使用UserDirs并根据您的要求扩展类。
答案 2 :(得分:2)
您的用户没有系统帐户。创建这些帐户可能也不可行。因此,我建议通过Web UI管理所有这些。
继续按原样创建目录。权限很好。您的用户界面需要更改,以仅显示该用户的目录或文件。我假设您有一个与此页面关联的数据库。将用户名和随机生成的目录名与用户关联。如果有人试图转到直接路径并且他们不是与该目录关联的用户,请将其踢回登录屏幕。
为了说明,我创建了一个名为test
的帐户,并且可能是一个唯一的目录。如果我退出,我应该无法访问该目录,因为您的代码会看到
如果我以test2
登录并访问test
目录,您的代码应该会看到
您需要添加一个检查用户正在访问的目录的函数,并将其与用户关联的目录进行比较。如果他们两个匹配,请允许他们继续。如果它们不匹配,请重定向用户。