禁止特定用户执行某个命令(最常见的需求)
这是最普遍的需求,比如你不希望某个普通用户使用 reboot、shutdown 或 rm -rf / 等危险命令,实现这个目标最推荐、最标准的方法是使用 rbash (Restricted Bash) 或 rsh (Restricted Shell)。

使用受限 Shell (rbash)
rbash 是一个受限版本的 Bash,它会限制用户的很多操作,其中就包括修改 PATH 环境变量和执行命令路径。
核心原理:
- 将用户的默认 Shell 从
/bin/bash改为/bin/rbash。 - 为该用户创建一个专用的
$HOME/bin目录。 - 只允许用户执行
$HOME/bin目录下的命令。
操作步骤:
假设我们要禁止用户 testuser 执行除了 ls, cat, vi 之外的所有命令。

第1步:创建用户的专用命令目录
# 为 testuser 创建 bin 目录 mkdir -p /home/testuser/bin # 将该目录的拥有者设为 testuser chown testuser:testuser /home/testuser/bin # 设置正确的权限,确保 testuser 可以执行 chmod 755 /home/testuser/bin
第2步:将常用命令复制到用户的专用目录
# 将允许使用的命令复制到用户的 bin 目录 # 注意:这里使用绝对路径来复制,确保是系统原始的、安全的命令 cp /bin/ls /home/testuser/bin/ cp /bin/cat /home/testuser/bin/ cp /usr/bin/vi /home/testuser/bin/
第3步:修改用户的默认 Shell
这是最关键的一步,你需要使用 usermod 命令来更改用户的登录 Shell。

# 将 testuser 的 shell 改为 rbash sudo usermod -s /bin/rbash testuser
第4步:验证
用 testuser 登录系统(或者使用 su - testuser 切换到该用户),然后尝试执行命令:
# 这些命令可以执行,因为它们在 ~/bin 目录下 ls cat /etc/passwd | head -n 1 vi my_file.txt # 尝试执行一个不在 ~/bin 目录下的命令,rm rm /tmp/test.txt # 你会看到类似 "bash: rm: command not found" 的错误 # 尝试切换到普通 bash bash # 你会看到 "rbash: restricted: cannot specify `+' or `-' options for command hashing" 错误,无法退出受限模式。 # 尝试修改环境变量 export PATH=/bin # 你会看到 "rbash: restricted: cannot modify PATH environment variable" 错误。
如何恢复?
如果想恢复该用户的权限,只需将 Shell 改回 /bin/bash 即可:
sudo usermod -s /bin/bash testuser
使用 sudoers 文件(更精细的控制)
如果你只是想限制某个用户通过 sudo 执行某些命令,而不是限制其直接执行命令,那么修改 /etc/sudoers 文件是最佳选择。
核心原理:
通过 sudoers 文件,你可以精确地定义哪些用户可以以什么身份(root 或其他用户)执行哪些命令,甚至可以传递哪些参数。
操作步骤:
第1步:安全地编辑 sudoers 文件
永远不要直接用 vi 或 nano 编辑 /etc/sudoers,应该使用 visudo 命令,它会检查语法错误,防止你因配置错误而无法使用 sudo。
sudo visudo
第2步:添加规则
在文件末尾添加你的规则。
示例1:禁止用户 testuser 使用 rm 命令
# 在文件末尾添加以下内容 Cmnd_Alias DANGEROUS_CMDS = /bin/rm, /usr/bin/rm # 定义一个命令别名 DANGEROUS_CMDS,包含 rm 命令 testuser ALL = !DANGEROUS_CMDS # 允许 testuser 执行所有命令,但除了 DANGEROUS_CMDS 别名中定义的命令
示例2:只允许用户 testuser 使用 ls 和 cat
Cmnd_Alias SAFE_CMDS = /bin/ls, /bin/cat # 定义一个命令别名 SAFE_CMDS testuser ALL = SAFE_CMDS # 只允许 testuser 执行 SAFE_CMDS 中的命令,其他任何命令都会被拒绝
第3步:保存并退出
在 visudo 中,按 Ctrl+X,然后按 Y,最后按 Enter 保存。
第4步:验证
用 testuser 登录,尝试使用 sudo:
# 尝试执行允许的命令 sudo ls /root # 如果配置正确,会要求输入 testuser 自己的密码,然后列出目录 # 尝试执行禁止的命令 sudo rm /tmp/important_file # 你会看到类似 "testuser is not allowed to run rm /tmp/important_file as root on hostname" 的错误
隐藏命令(不让普通用户看到)
如果你想让某个命令在普通用户执行 which <command> 或 type <command> 时“消失”,但用户仍然可以执行它(如果该命令在他们的 PATH 中),你可以修改该用户的 PATH 环境变量。
原理:
PATH 环境变量定义了系统在哪些目录下查找可执行文件,如果你从 PATH 中移除包含某个命令的目录,系统就找不到它了。
示例:
假设你想隐藏 reboot 命令,它通常位于 /sbin 目录。
第1步:检查命令位置
which reboot # 输出通常是 /usr/bin/reboot 或 /sbin/reboot
第2步:修改用户配置文件
对于 Bash Shell,通常是 ~/.bashrc 或 ~/.profile 文件,为特定用户 testuser 修改:
# 切换到 testuser su - testuser # 编辑其 .bashrc 文件 vi ~/.bashrc
第3步:添加或修改 PATH 行
在文件末尾添加或修改 export PATH 行,移除包含 reboot 的目录(/sbin)。
# 原始 PATH 可能是这样的 # export PATH="$HOME/.local/bin:$HOME/bin:/usr/local/bin:/usr/bin:/bin:/usr/local/games:/usr/games:/sbin" # 修改后,去掉 /sbin export PATH="$HOME/.local/bin:$HOME/bin:/usr/local/bin:/usr/bin:/bin:/usr/local/games:/usr/games" # 保存并退出
第4步:使配置生效
source ~/.bashrc
验证:
testuser 再执行 which reboot 或 type reboot,会提示 reboot not found,如果 testuser 直接输入 /sbin/reboot,命令仍然会被执行(只要有权限)。
注意: 这种方法只是“隐藏”,并没有真正“禁止”,对于系统管理员来说,这是一种非常不推荐的“安全通过 obscurity”(通过隐藏来保证安全)的做法,因为它没有真正解决问题。
重命名或移动命令(极端情况)
这是一种非常粗暴且不推荐的方法,因为它会影响整个系统,包括所有服务和脚本。
原理: 将命令的可执行文件重命名或移动到其他位置。
示例:
# 极度危险!不要在生产环境执行! # 重命名 reboot 命令 sudo mv /sbin/reboot /sbin/reboot.real # 创建一个无法执行的占位符 sudo touch /sbin/reboot sudo chmod 000 /sbin/reboot
后果:
任何尝试执行 reboot 的用户(包括 root,如果用的是 /sbin/reboot 这个路径)都会失败,系统自带的更新、重启脚本也可能因此失效。请仅在沙箱或测试环境中使用此方法。
总结与推荐
| 方法 | 优点 | 缺点 | 适用场景 |
|---|---|---|---|
受限 Shell (rbash) |
标准、安全、可靠,真正限制了用户的执行环境。 | 配置稍显繁琐,需要为每个用户管理命令列表。 | 强烈推荐,用于创建受限制的用户账号,如只用于部署或监控的账户。 |
sudoers 文件 |
精细、灵活,可以精确控制 sudo 权限,不影响用户直接执行命令。 |
只对 sudo 生效,不限制用户直接在终端执行危险命令。 |
强烈推荐,用于管理需要提升权限才能执行特定命令的用户。 |
修改 PATH |
简单,可以快速“隐藏”命令。 | 不安全,只是障眼法,用户仍可通过绝对路径执行。 | 不推荐用于安全目的,可能用于清理环境变量或避免版本冲突。 |
| 重命名/移动命令 | 简单粗暴,效果彻底。 | 破坏性强,可能影响整个系统稳定性和其他服务。 | 仅在受控的测试或沙箱环境中使用。 |
对于绝大多数情况,请优先使用 rbash 来限制普通用户,使用 sudoers 来精细控制管理员的 sudo 权限,这两种方法是 Linux 系统管理和安全实践中的标准做法。
