本文目录导读:

针对“脚本怎样限制脚本执行用户”这个问题,通常有两种理解场景:
- 场景 A(Linux/Unix 系统): 编写一个 Shell/Python 脚本,只允许特定的系统用户(如 root 或某个服务账户)执行,其他人执行就报错退出。
- 场景 B(Web 安全/系统安全): 如何限制脚本的执行权限,防止未授权用户运行。
下面分别提供对应的解决方案。
场景 A:在脚本内部通过代码限制用户(推荐做法)
这是最灵活、最安全的方式,脚本启动后,立即检查当前运行的用户是谁,如果不符合条件,立刻退出。
Shell 脚本(Bash)
方法:使用 $EUID(推荐)或 $USER
#!/bin/bash
# 定义允许运行的用户名(数组)
ALLOWED_USERS=("root" "deploy" "admin")
# 获取当前有效用户ID(EUID),root的EUID为0
if [ "$EUID" -ne 0 ]; then
echo "错误:此脚本必须以 root 用户运行!" >&2
exit 1
fi
# 或者检查用户名(更灵活,但可能会被修改)
CURRENT_USER=$(whoami)
if [[ ! " ${ALLOWED_USERS[@]} " =~ " ${CURRENT_USER} " ]]; then
echo "错误:不允许用户 '$CURRENT_USER' 执行此脚本。" >&2
echo "允许的用户:${ALLOWED_USERS[*]}" >&2
exit 1
fi
# 你的脚本逻辑
echo "用户验证通过,继续执行..."
关键点:
$EUID是数字,比字符串比较更快、更准确。whoami或$USER是字符串,适合限制特定非 root 用户。- 使用
>&2将错误信息输出到标准错误。
Python 脚本
方法:使用 os 和 pwd 模块
import os
import pwd
import sys
# 定义允许的用户名或UID
ALLOWED_USERS = ["root", "deploy"] # 用户名列表
ALLOWED_UIDS = [0] # UID列表 (0 = root)
def check_user():
current_uid = os.geteuid() # 获取有效用户ID(推荐)
try:
current_user = pwd.getpwuid(current_uid).pw_name
except KeyError:
print("错误:无法获取当前用户信息", file=sys.stderr)
sys.exit(1)
# 检查UID
if current_uid not in ALLOWED_UIDS:
# 检查用户名
if current_user not in ALLOWED_USERS:
print(f"错误:用户 '{current_user}' (UID: {current_uid}) 不允许执行此脚本。", file=sys.stderr)
print(f"允许的用户: {', '.join(ALLOWED_USERS)}", file=sys.stderr)
sys.exit(1)
print(f"验证通过,当前用户: {current_user}")
if __name__ == "__main__":
check_user()
# 你的脚本逻辑
关键点:
- 使用
os.geteuid()而不是os.getuid(),因为前者考虑了setuid位。 pwd.getpwuid()可以将UID转换为用户名,反之亦然。
几种常见的检查场景
| 需求 | Shell 命令 | Python 命令 |
|---|---|---|
| 必须是 root | if [ "$EUID" -ne 0 ]; then ... |
if os.geteuid() != 0: ... |
| 必须是特定用户 | if [ "$USER" != "deploy" ]; then ... |
if os.getlogin() != "deploy": ... 或 pwd.getpwuid(os.geteuid()).pw_name |
| 必须属于某个用户组 | if ! groups | grep -q "\badmin\b"; then ... |
使用 grp 模块:if "admin" not in os.getgroups(): ... |
场景 B:使用操作系统权限限制脚本执行(系统级限制)
如果不想修改脚本代码,或者脚本是别人的代码,可以通过以下方法在操作系统层面限制。
修改文件权限(最基本的做法)
# 1. 将脚本所有者改为特定用户 sudo chown deploy:deploy my_script.sh # 2. 设置权限:仅所有者可以执行,其他人禁止 sudo chmod 700 my_script.sh # 或:仅所有者和组可以执行,其他人禁止 sudo chmod 750 my_script.sh
缺点: 如果用户通过 sudo 或 su 切换成其他用户,或者拥有 root 权限,这个限制就失效了。
使用 Linux Capabilities(高级权限限制)
如果希望普通用户也能执行特定操作(只有 root 能执行的网络抓包脚本),但又不想给 root 权限,可以设置 Capabilities:
# 不使用脚本本身,而是使用 setcap 给脚本解释器(如 python3)赋予特定能力 # 这种方式很危险,通常不建议给脚本直接赋予能力。 # 更安全的做法是:写一个小的C程序或使用 setuid 位的编译程序。
警告: 不建议直接在 python3 或 bash 上设置 setuid 或 capabilities,这会造成巨大的安全漏洞,权限限制应在脚本内部或通过专门的工具(如 sudo)完成。
使用 sudo 权限控制(企业级做法)
在 /etc/sudoers 文件中,可以非常精细地控制:
# 只允许用户 'webadmin' 执行 /opt/scripts/deploy.sh
webadmin ALL=(ALL) /opt/scripts/deploy.sh
# 禁止所有其他用户执行
# 然后脚本设置权限为 750,组设为 webadmin 组
优点: 可以记录日志、控制参数、不需要密码等,非常强大。
总结与推荐方案
| 使用场景 | 推荐方案 |
|---|---|
| 你的脚本,逻辑简单 | 在脚本开头添加 Shell/Python 的 $EUID 或 os.geteuid() 检查,代码易懂,可以定制提示信息。 |
| 你的脚本,需要跨平台 | Python 脚本,使用 os.geteuid() + pwd 模块。 |
| 第三方脚本,不想修改其代码 | 使用 chmod 700 设置文件权限,或使用 sudo 规则限制其执行路径。 |
| 防止 root 误操作 | 在脚本中检查 if [ "$EUID" -eq 0 ]; then ... 并警告退出。 |
| 仅允许特定用户组运行 | 脚本内部检查 groups,或者直接设置文件权限为 750 并设置组所有权。 |
最后提醒: 最安全的做法永远是 场景 A(脚本内部检查) + 场景 B(文件权限限制) 结合,双重保险,既防止意外双击运行,也防止误操作。