5.7.1 脚本权限与最小权限原则

脚本权限与最小权限原则#

脚本具有批量执行能力,权限过高会放大风险。最小权限原则要求“只授予完成任务所需的最低权限”,并确保操作可审计、可追溯、可回滚。

原理草图(权限边界与执行链):

文章图片

核心实践与可执行示例

1) 创建专用账户与目录权限(安装/准备)

# 1. 创建运维组与用户
groupadd ops
useradd -m -s /bin/bash -g ops ops

# 2. 创建脚本目录与日志目录
mkdir -p /opt/ops/scripts /var/log/ops

# 3. 权限收敛:脚本可执行且仅运维组可读,日志仅属主写
chown -R ops:ops /opt/ops/scripts /var/log/ops
chmod 750 /opt/ops/scripts
chmod 700 /var/log/ops

# 预期:普通用户无法写入脚本目录与日志目录

2) 精细化 sudo 授权(最小权限)

# 编辑 /etc/sudoers.d/ops,禁止使用通配符提升任意命令
cat <<'EOF' >/etc/sudoers.d/ops
# ops 仅允许重启 nginx 和查看状态,不允许编辑配置
ops ALL=(root) NOPASSWD: /bin/systemctl restart nginx, /bin/systemctl status nginx
# 允许执行特定脚本(路径固定)
ops ALL=(root) NOPASSWD: /opt/ops/scripts/deploy_nginx.sh
EOF

# 语法检查,防止配置错误导致 sudo 失效
visudo -c

3) 脚本示例:使用绝对路径、临时文件安全、日志可追溯

# /opt/ops/scripts/deploy_nginx.sh
#!/usr/bin/env bash
set -euo pipefail

LOG_DIR="/var/log/ops"
LOG_FILE="${LOG_DIR}/deploy_nginx.log"
BIN_SYSTEMCTL="/bin/systemctl"
BIN_CP="/bin/cp"

umask 027  # 新文件权限:750/640

# 安全临时目录
TMP_DIR="$(/bin/mktemp -d -p /tmp deploy.XXXX)"
trap '/bin/rm -rf "$TMP_DIR"' EXIT

echo "$(date +%F_%T) start deploy" >> "$LOG_FILE"

# 复制配置前校验权限
if [ ! -r /etc/nginx/nginx.conf ]; then
  echo "config not readable" >> "$LOG_FILE"
  exit 1
fi

# 备份
$BIN_CP /etc/nginx/nginx.conf "$TMP_DIR/nginx.conf.bak"

# 重启
$BIN_SYSTEMCTL restart nginx
$BIN_SYSTEMCTL status nginx --no-pager >> "$LOG_FILE"

echo "$(date +%F_%T) done deploy" >> "$LOG_FILE"

4) 文件权限与属主检查命令(明确解释)

# 查看脚本与目录权限
ls -ld /opt/ops/scripts /opt/ops/scripts/deploy_nginx.sh
# 预期:目录 750,脚本 750,属主 ops

# 检查是否存在危险权限(如 777)
find /opt/ops/scripts -type f -perm -o+w -ls
# 预期:无输出

5) 审计与追踪(安装/配置)

# 安装审计工具(以 RHEL/CentOS 为例)
yum -y install audit

# 启动服务
systemctl enable --now auditd

# 记录脚本执行审计(关键路径监控)
auditctl -w /opt/ops/scripts/deploy_nginx.sh -p x -k ops_script_exec

典型排错与处理

  • sudo 权限不生效
  • 症状:sudo: ops is not allowed to execute ...
  • 处理:
    bash # 检查 sudoers 语法 visudo -c # 查看实际解析 sudo -l -U ops

  • 脚本执行权限不足

  • 症状:Permission denied
  • 处理:
    bash chmod 750 /opt/ops/scripts/deploy_nginx.sh chown ops:ops /opt/ops/scripts/deploy_nginx.sh

  • 日志无法写入

  • 症状:No such file or directoryPermission denied
  • 处理:
    bash mkdir -p /var/log/ops chown ops:ops /var/log/ops chmod 700 /var/log/ops

命令与参数解释要点
- chmod 750:属主可读写执行,属组可读执行,其他无权限。
- umask 027:新建文件权限默认收敛,防止日志泄露。
- visudo -c:校验 sudo 配置语法,避免锁死 sudo。
- auditctl -w ... -p x:监控文件“执行”事件。

练习
1. 创建用户 ops,将一个脚本目录权限收敛至 750,并验证普通用户无法写入。
2. 配置 sudo 仅允许 systemctl restart nginx,验证 systemctl stop nginx 被拒绝。
3. 将脚本中的 systemctl 改为相对路径,模拟 PATH 污染并观察风险,再恢复为绝对路径。
4. 开启 auditd,对脚本执行做审计,执行后用 ausearch -k ops_script_exec 查看记录。