问题描述
我需要为一个特定文件夹设置 umask
值。我有一个 Web 应用程序,当它创建一些文件时,默认权限为 700。但我需要至少 755 权限才能访问该文件。怎么能这样做呢?
最佳方法
你可以使用 setfacl
setfacl -d -m group:name:rwx /path/to/your/dir
其中 name
是组名
要查找您或特定用户所属的组,请参阅 In unix/linux how do you find out what group a given user is in via command line?
次佳方法
您不能为每个目录设置 umask,它是一个 process-level 值。如果需要防止其他人读取目录中的文件,请撤销相应的权限位。
例如,如果您有一个目录 /home/user/directory
,其中包含一些文件和目录,这些文件和目录可以从进程中获得 777 之类的权限,请将 /home/user/directory
的权限位设置为 700 之类的东西。这将使其他用户无法访问(超级用户 root 除外)下降到 /home/user/directory
。
我很偏执,将 /home/user
的权限设置为 750,因此只有我可以在我的主目录中读取、写入和下降。这导致像 /home/user/Public
这样的文件夹不能被其他人访问,但我可以接受。
根据你的问题的更新:仍然,你无法在文件系统中控制它(除了使用不同的文件系统类型,如强烈反对的 FAT),你需要在你的 webapp 中做到这一点。如果您的 webapp 是用 PHP 编码的,您可以使用 umask
函数即时更改 umask:
<?php
umask(0022);
// other code
?>
您可以将它放在一个配置文件中,例如包含数据库连接密码的文件(在 WordPress 等应用程序中思考)。
请记住这是一个进程值,一些网络服务器允许您在其配置文件中设置它,否则您可以修改启动脚本以设置所需的 umask。请记住,像 755
和 644
这样的权限对于 Web 应用程序来说是相当危险的,如果代码是敏感的,那么每个人都可以阅读它。
第三种方法
提供使用 shell hooks 和 direnv
实现的花药解决方案。如果 setfacl
在您的系统上不可用,则以下解决方案可能更兼容。 (例如 macOS)
\\n
direnv
is an environment switcher for the shell. It knows how to hook into bash, zsh, tcsh, fish shell and elvish to load or unload environment variables depending on the current directory.\\n
使用 .envrc
到 export
特定目录的自定义 umask
值,当您离开该目录时,将卸载 export
ed env var。
# example .envrc file
export UMASK=0022
一旦更改工作目录,定义一个挂钩以更改 umask
值。
function _umask_hook {
if [[ -n $UMASK ]]; then
umask "$UMASK"
elif [[ $OSTYPE == darwin* ]]; then
umask 0077
else
umask 0022
fi
}
# To make the code more reliable on detecting the default umask
function _umask_hook {
# Record the default umask value on the 1st run
[[ -z $DEFAULT_UMASK ]] && export DEFAULT_UMASK="$(builtin umask)"
if [[ -n $UMASK ]]; then
umask "$UMASK"
else
umask "$DEFAULT_UMASK"
fi
}
# zsh hooks
# trigger _umask_hook once working dir is changed
add-zsh-hook chpwd _umask_hook
# bash
# Append `;` if PROMPT_COMMAND is not empty
PROMPT_COMMAND="${PROMPT_COMMAND:+$PROMPT_COMMAND;}_umask_hook"
目前,zsh 的 direnv 钩子初始化不支持 chpwd
钩子。如果您看到此页面时拉取请求 GH-514 尚未合并。请使用以下代码手动注释掉 eval "$(direnv hook zsh)"
并在 chpwd
上挂接 direnv
,
if (( $+commands[direnv] )) && ! (( $+functions[_direnv_hook] )); then
_direnv_hook() {
eval "$(command "direnv" export zsh)";
}
typeset -agU precmd_functions;
if [[ -z ${precmd_functions[(r)_direnv_hook]} ]]; then
precmd_functions=( _direnv_hook ${precmd_functions[@]} )
fi
typeset -agU chpwd_functions;
if [[ -z ${chpwd_functions[(r)_direnv_hook]} ]]; then
chpwd_functions=( _direnv_hook ${chpwd_functions[@]} )
fi
fi
来源:dynamic-umask-based-on-cwd.md
第四种方法
另一种解决方案可能是只在目录中创建的文件上设置组 ID,这使得新文件由目录组 ID 拥有,而不是创建文件的用户的组 ID。所以我认为你可以这样做:
chown www-data:www-data /my/folder
chmod 2755 /my/folder
这设置了 setgid 特殊文件权限,这将导致在 /my/folder
中创建的所有文件都归 www-data
组所有,然后由于父目录而具有 rx
( 5
) 权限。
特殊权限使用八进制表示法在第一位数字中定义。将下面的数字加在一起以组合选项(例如,3
用于 sgid 和粘性位)
-
1
为粘性位 -
2
为 sgid -
4
代表 suid
参考:https://en.wikipedia.org/wiki/Setuid