避免让 subversion 修改 Linux 文件权限。
Posted
技术标签:
【中文标题】避免让 subversion 修改 Linux 文件权限。【英文标题】:Avoid having subversion modify Linux file permissions. 【发布时间】:2011-08-22 15:06:10 【问题描述】:我的所有代码库都存储在一个 subversion 存储库中,我分散在负载平衡的 Apache Web 服务器中,从而可以轻松地检查代码、运行更新以及无缝地将开发中的代码投入生产。
我确信有一个很容易解决的不便之处(除了在每次结帐时执行脚本),就是在使用 subversion 更新或签出的文件上设置(返回)Linux 权限。我们的安全团队将Owner
和Group
设置在httpd.conf文件中,documentRoot
中的所有目录都获得700的权限,所有非可执行文件(例如*.php, *.smarty, *.png) 获得 600 的 Linux 权限,所有可执行文件获得 700(例如 *.sh、*.pl、*.py)。所有文件的所有者和组都必须设置为apache:apache
,才能被 httpd 服务读取,因为只有文件所有者被设置为通过权限访问。
每次我运行svn update
或svn co
时,即使文件可能未创建(即svn update
),我发现文件的所有权被设置为运行 svn 命令,通常情况下,文件权限被设置为不同于原来的权限(即更新前的 .htm 文件为 600,但在和svn update
之后,它被设置为 755,甚至第777章)。
绕过 subversion 更新文件权限和所有权的最简单方法是什么?在 svn 客户端或 Linux 服务器上可以做些什么来保留原始文件权限?我正在运行 RHEL5(现在在一些选定的实例上运行 6 个)。
【问题讨论】:
【参考方案1】:您可以在 Subversion 中的文件上存储属性(请参阅http://svnbook.red-bean.com/en/1.0/ch07s02.html)。您对 svn:executable 属性特别感兴趣,它将确保存储可执行权限。
不过,没有针对所有权限执行此操作的通用方法。 Subversion 也不存储所有权——它假定,如果你签出某些东西,你就拥有它。
【讨论】:
【参考方案2】:文件的所有者将被设置为运行 svn 命令的用户,因为它如何实现底层的 up 命令 - 它删除和替换更新的文件,这将导致所有权“更改”为相关用户。防止这种情况的唯一方法是实际执行 svn up 作为文件应该拥有的用户。如果您想确保它们归特定用户所有,请以该用户身份运行命令。
关于权限,svn 只服从账户的 umask 设置——可能是 066 之类的东西——为了确保文件不能被组和其他账户访问,你需要先发出 'umask 077'执行 svn up,这样可以确保文件只能由发出命令的用户帐户访问。
除非 .svn 目录是安全的,否则我会注意将颠覆数据部署到 Web 服务器的安全问题。
【讨论】:
+1 提醒人们注意 .svn 的潜在后果。好电话。 我遇到了同样的问题。在我使用svnkit(一个java svn)之前,没有这种行为,它能够保留文件的所有者......但它很慢......是什么让我改变了原来的svn版本。我错过了很多这个“功能”。 这不准确。您可以在目录上使用setgid
来强制将组作为所有者。我在这里回答了详细信息:***.com/a/42800354/2578286
您也可以使用目录的ACL默认权限来覆盖svn在co/up上设置的文件权限。例如看这个答案:unix.stackexchange.com/questions/396619/… 另外我发现临时目录上的默认ACL对svn创建的文件的权限设置有影响。【参考方案3】:
您可能会考虑做的一件事是将svn
二进制文件安装在您的路径之外,并在路径中放置一个替换脚本(位于并称为/usr/bin/svn
或其他任何内容)。脚本看起来像这样:
#!/bin/sh
# set umask, whatever else you need to do before svn commands
/opt/svn/svn $* # pass all arguments to the actual svn binary, stored outside the PATH
# run chmod, whatever else you need to do after svn commands
一个明显的缺点是您可能必须对传递给 svn 的参数进行一些解析,即您可以将相同的路径传递给您的 chmod,而不是为大多数 svn 命令运行 chmod,等等。
这里可能还有一些安全考虑。我不知道您的部署环境是什么样的,但您可能应该进一步调查一下。
【讨论】:
【参考方案4】:我写了一个小脚本来存储权限和所有者,执行你的 SVN 命令并恢复权限和所有者。 它可能不是防黑客的,但对于私人用途,它可以完成这项工作。
svnupdate.sh:
#!/usr/bin/env bash
if [ $# -eq 0 ]; then
echo "Syntax: $0 <filename>"
exit
fi
IGNORENEXT=0
COMMANDS=''
FILES='';
for FILENAME in "$@"
do
if [[ $IGNORENEXT > 0 ]]; then
IGNORENEXT=0
else
case $FILENAME in
# global, shift argument if needed
--username|--password|--config-dir|--config-option)
IGNORENEXT=1
;;
--no-auth-cache|--non-interactive|--trust-server-cert)
;;
# update arguments, shift argument if needed
-r|--revision|--depth|--set-depth|--diff3-cmd|--changelist|--editor-cmd|--accept)
IGNORENEXT=1
;;
-N|--non-recursive|-q|--quiet|--force|--ignore-externals)
;;
*)
if [ -f $FILENAME ]; then
FILES="$FILES $FILENAME"
OLDPERM=$(stat -c%a $FILENAME)
OLDOWNER=$(stat -c%U $FILENAME)
OLDGROUP=$(stat -c%G $FILENAME)
FILECOMMANDS="chmod $OLDPERM $FILENAME; chown $OLDOWNER.$OLDGROUP $FILENAME;"
COMMANDS="$COMMANDS $FILECOMMANDS"
echo "COMMANDS: $FILECOMMANDS"
else
echo "File not found: $FILENAME"
fi
;;
esac
fi
done
OUTPUT=$(svn update "$@")
echo "$OUTPUT"
if [[ ( $? -eq 0 ) && ( $OUTPUT != Skipped* ) && ( $OUTPUT != "At revision"* ) ]]; then
bash -c "$COMMANDS"
ls -l $FILES
fi
【讨论】:
【参考方案5】:我也有类似的问题。 我发现了一个很酷的脚本:asvn (Archive SVN)。
你可以在这里下载: https://svn.apache.org/repos/asf/subversion/trunk/contrib/client-side/asvn
Description: Archive SVN (asvn) will allow the recording of file types not normally handled by svn. Currently this includes devices, symlinks and file ownership/permissions. Every file and directory has a 'file:permissions' property set and every directory has a 'dir:devices' and 'dir:symlinks' for recording the extra information. Run this script instead of svn with the normal svn arguments.
这篇博文(帮助我找到脚本)http://jon.netdork.net/2010/06/28/configuration-management-part-ii-setting-up-svn/ 展示了一个简单的用法。
【讨论】:
【参考方案6】:你可以解决这个问题。使用setgid
。
你有apache:apache
在运行服务器
设置所有文件和目录的组权限。服务器将按其组读取文件
在所有目录上设置setgid
- 仅在目录上:在文件上设置这个有不同的功能
示例('2' 是 setgid):
chmod 2750
将apache
设为所有目录的组
会发生什么
任何帐户创建的新文件和目录将归apache
组所有
新目录将继承setgid
,从而毫不费力地保留结构
见https://en.wikipedia.org/wiki/Setuid#setuid_and_setgid_on_directories
【讨论】:
以上是关于避免让 subversion 修改 Linux 文件权限。的主要内容,如果未能解决你的问题,请参考以下文章
允许用户修改Subversion日志的钩子脚本 (linux)
图形化SVN管理搭建 subversion edge自行修改密码