有没有办法可以防止所有命令被定义为别名?
例如,用户不应该能够将rm
或任何其他命令(Ubuntu 默认命令)定义为别名。
答案1
您无法阻止用户定义他们喜欢的任何别名。考虑一下:
- 您在 中禁用别名
/etc/bash.bashrc
。他们选择在任何地方启用它。 - 您通过脚本删除 中的所有别名提及
/etc/bash.bashrc
,以及所有~/.bashrc
和。他们将别名放在另一个文件中并获取它。~/.bash_aliases
- 您运行一个命令来
PROMPT_COMMAND
禁用某些别名。它们会重新定义或取消定义PROMPT_COMMAND
。 - 您设置陷阱
DEBUG
并取消定义别名。它们会移除陷阱。 - 您将调用时获取的所有文件都更改为 root。它们使用另一个文件,并手动获取该文件作为它们运行的第一个命令。
- 您禁用内置命令
unset
,builtin
和enable
;创建alias
一个函数;declare -rf alias
以防止用户修改该函数;并导出该函数。它们使用/bin/bash
和运行--rcfile
以--init-file
启动新 shell,其中现在已启用上述内置函数。 - ...
您可以在编译时禁用别名,然后由您来保持 bash 最新,并确保您不会受到下一个 Shellshock 的影响。当然,用户可以构建自己的 bash。
答案2
总结
阻止用户创建别名的唯一方法是向他们提供不支持别名的 shell。这通常是一个 X/Y 问题,其中 X 实际上是一个威胁模型,应该使用适当的控制或架构来解决,而不是试图解决问题事后在共享系统上为用户提供 shell 之后。
下面,我将提供一个技术上正确的答案,以及一些关于这将解决和不会解决的问题的指导。我还提供了一些关于替代控制的额外指导。
使用 Bash 受限 Shell
你可以使用 Bash 的受限外壳通过将 rbash 指定为用户的登录 shell。例如:
foo:x:2001:2001:restricted user:/home/foo:/bin/rbash
然后您必须禁用别名为用户内置,最好不要破坏其他人的 shell。例如,您可以将以下内容添加到如下文件中:/etc/profile.d/rbash.sh:
# Limit effect to users in a specific UID range.
if ((UID >= 2000)) && ((UID < 3000)); then
# Check shell options; disable alias builtins when shell is restricted.
if [[ $- =~ r ]]; then
enable -n alias
enable -n unalias
fi
fi
注意事项
除非你把用户放入 chroot jail 中,或者给他们提供一个修改过的小路这不包括对其他 shell 的访问,没有什么可以阻止用户bash
在提示符下简单地键入并获取不受限制的 shell。
此外,受限 shell 按照设计可以阻止许多常见活动,例如更改目录:
$ cd /tmp
rbash: cd: restricted
但不会阻止其他脚本或程序小路这样做。这意味着你必须小心地设计用户的环境,特别是你需要阻止他们修改小路在他们的启动文件中,因为即使 rbash小路只读它这样做后初始化。
更好的选择
即使您使用 rbash,您也需要将其作为更广泛的控件集的一部分来使用。一些示例可能包括:
防止非技术用户偶然通过提供默认别名来调用危险命令
rm -i
,例如mv -i
cp -i
/etc/bash.bashrc文件。- 考虑到您最初的例子,这可能是最合理的解决方案。
enable -n alias
如果愿意的话,你可以将其结合起来。- 这不会阻止知识渊博的用户更改别名,但足以阻止非技术用户做您所担心的任何事情。
使用传统的 Unix 权限或 POSIX ACL 来保护文件和目录。
执行单个非交互式命令的登录名。例如:
foo:x:2001:2001:run foo.sh:/home/foo:/usr/local/bin/foo.sh
使用每个密钥的 SSH 强制命令。例如:
# ~foo/.ssh/authorized_keys command="/usr/local/bin/foo.sh" [remainder of line]
使用OpenSSH Force命令带有条件匹配块的选项。
用一个chroot 监狱。
使用虚拟化技术(例如 Xen、OpenVZ、LXC、VMware、VirtualBox 或其他技术)来提供隔离的环境。
一旦你准确地定义了威胁模型,你就可以确定最适合你用例的控制措施。如果没有对威胁模型有更有意义的理解,为什么您想防止混叠(例如它解决了什么实际问题?)您无法选择最合适的控件。
答案3
这是毫无意义的尝试,正如 muru 的回答所表明的那样。但也有一些选择,但它们并不完美。
根据bash
手册,函数总是优先于别名,因此我们可以执行以下操作:
xieerqi@eagle:~$ function alias { echo "Aliases are no-no" ; }
xieerqi@eagle:~$ alias TEST='rm'
Aliases are no-no
您可以将函数定义放入系统范围.bashrc
,但是正如 muru 指出的那样,聪明的用户会找到通过获取不同的bashrc
文件来获取别名的方法。
我尝试过的另一个想法是enable
内置。
alias
是一个内置的 shell,并且bash
有一个不错的enable
命令,允许启用或禁用内置命令。例如,这是我禁用的alias
。
xieerqi@eagle:~$ enable -n alias
xieerqi@eagle:~$ alias
No command 'alias' found, did you mean:
Command '0alias' from package 'zeroinstall-injector' (universe)
alias: command not found
xieerqi@eagle:~$ alias TEST='rm'
No command 'alias' found, did you mean:
Command '0alias' from package 'zeroinstall-injector' (universe)
alias: command not found
xieerqi@eagle:~$ enable alias
xieerqi@eagle:~$ alias
alias egrep='egrep --color=auto'
alias fgrep='fgrep --color=auto'
alias grep='grep --color=auto'
alias l='ls -CF'
alias la='ls -A'
alias ll='ls -alF'
alias ls='ls --color=auto'
xieerqi@eagle:~$
再次强调,bashrc
此处使用系统范围是一种选择。
答案4
你可以在 中定义/etc/profile
一个名为 的函数,alias
该函数执行您想要的验证(可能使用type -p
)(毕竟“Ubuntu 默认命令”是“ 中的可执行文件$PATH
”),然后再调用内置的alias
,但是,正如其他人指出的那样,您的用户可以绕过这一点。为什么不找一组不同的用户,或者教育他们(“定义一个alias
覆盖命令的 是搬起石头砸自己的脚的好方法,并造成混乱(例如,为什么 会ls
提示我输入密码?))?