我有一个 Ubuntu 16.04 Nginx 服务器环境,文档根目录下有几个 CMS (WordPress) 网站。
所有站点目录www-data
都递归地具有所有者和组。
根据我得到的一些安全咨询,这是有问题的,因为来自一个站点的数据可能会更改任何其他相邻站点(例如,安装在其中一个站点的 CMS 中的恶意模块)。
我认为解决方案是更改此命令,我总是在添加新站点后运行该命令(以及在更改所有者和组的更新后在 cron 中运行):
chown -R www-data:www-data /var/www/html/*
某些条件命令不仅将这些特征更改为www-data
站点目录的实际名称。
为了澄清,每个站点目录的所有者应该是domain.tld
并且组也应该是domain.tld
(我总是根据站点的domain.tld命名站点目录)。
这样的条件命令是什么?
注意:Nginx 用户和目录/var/www/html/
都将保留为www-data:www-data
.
G-Man 更新:
我还没有测试,但我认为如果你${domain}
作为变量的第一个参数传递($1
),这是很好的:
chown -R ${domain}:${domain} ${domain}/*
虽然我会保留它:
chown -R ${domain}:www-data ${domain}/*
当然,adduser ${domain} --disabled-password --disabled-login
如果没有完成的话,之前是需要的。
答案1
我可能错过了一些东西,但这看起来很简单:
$ cd /var/www/html
$ for dir in *
do
chown -R "$dir:$dir" "$dir"
done
如果您担心这些命令的正确性,可以插入以下单词echo
之前chown
,例如,
$ cd /var/www/html $ 表示 * 中的目录 做 回声chown -R "$dir:$dir" "$dir" 完毕
让它告诉你chown
它将要执行什么命令,而不需要实际执行它们。这个技巧适用于整个答案,事实上,适用于大多数 shell 脚本解决方案(即其他问题)。
如果你想用一行来做,
$ cd /var/www/html && for d in *; do chown -R "$d:$d" "$d"; done
我这样做是cd
为了避免复杂性另一个答案
拥抱了。如果你这样做
$ for dir in /var/www/html/*
thendir
将被设置为/var/www/html/domain1
、
/var/www/html/domain2
、/var/www/html/domain3
等,这对于操作目录来说很好,但不会为您提供 所需的用户名和组名chown
。另一个答案使用相当复杂(且不完全可靠)的
awk
过程将目录路径的最后一级(即目录名,也是用户名;例如,domain1
)与路径的其余部分分开。幸运的是,我们可以完全在 shell 中完成等效的操作(但更好一些),如下所示:
$ for dir in /var/www/html/*
do
owner="${dir##*/}"
chown -R "$owner:$owner" "$dir"
done
这${dir##*/}
是一种特殊形式参数扩展$dir
它获取最后一个/
(斜杠)字符 的值并删除所有内容(包括)。当然,这仅留下目录库姓名,即用户名,因此我们将其分配给owner
并在chown
。请注意,这段代码是符合 POSIX 标准
并且应该可以在任何符合 POSIX 标准的 shell 中工作;与本网站上的一些答案不同,它不依赖于 bash。
如果你想做这在一行中,
$ for d in /var/www/html/*; do o="${d##*/}"; chown -R "$o:$o" "$d"; done
当然,如果您只是担心不希望更改主 shell 的工作目录,那么您可以在子 shell 中执行第一个命令:
$ (cd /var/www/html && for d in *; do chown -R "$d:$d" "$d"; done)
不言而喻(但无论如何我都会这么说),这要求您在运行任何这些命令之前定义名为 、 、 等domain1
的domain2
用户(和组)。domain3
如果您有一个添加新站点的脚本,那么在运行chown
.如果您确实chown
使用不是定义的用户名的名称运行,它将给您一条invalid user
错误消息。