用于编译应用程序然后执行权限提升操作的 Bash 脚本或 makefile

用于编译应用程序然后执行权限提升操作的 Bash 脚本或 makefile

我的项目中有一个基于 golang 的应用程序和关联的 systemd 文件。我正在开发一个 bash 脚本 ( install.sh)(或者 Makefile,如果这是一个更好的选择),它有助于自动执行以下操作(基本上按此顺序),但遇到了权限问题:

目标:

  • 以非 root 用户身份自动构建应用程序二进制文件

  • 将systemd文件复制到正确的路径(需要提升权限)

  • 停止/启动服务以加载更新的应用程序(需要提升的权限)。

bash 脚本中的理想步骤:

  • 作为非 sudo/非提升用户,删除现有的二进制文件并重建它go build -o binary_name .。此步骤应该以我的用户身份运行(将代码编译为 sudo 不是一个好主意。)
  • 提升权限
  • 删除现有/etc/systemd/system/binary_name.service文件。
  • 将文件复制binary_name.service到, /etc/systemd/system/binary_name.service以防其更新。
  • 停止并重新启动该binary_name服务。

我遇到的问题: - 如果我执行sudo install.sh,我们会遇到“不要编译为 sudo/root”问题。另外,go由于环境设置不同,找不到该包。 - 如果我在没有 sudo 的情况下执行install.sh,则当脚本尝试删除/复制服务文件时会出现权限问题。

以下是当前脚本的缩写版本:

#!/bin/bash

case "$1" in
  (das_application) 
    cd /usr/local/apps/das_application/

    # rebuild das_application binary
    echo "Removing old das_application binary"
    rm das_application
    echo "Building updated das_application binary"
    go build -o das_application .
    echo "Done building das_application binary"

    echo "Stopping das_application service"
    sudo systemctl stop das_application

    echo "Copying das_application.service to /etc/systemd/system"
    rm /etc/systemd/system/das_application.service
    cp ./conf/das_application.service /etc/systemd/system/das_application.service

    systemctl daemon-reload

    echo "Starting das_application service"
    systemctl start das_application.service

    exit 1
    ;;
  (*)
    echo "Use as ./install.sh das_application"
    exit 2
    ;;
esac

答案1

好问题。可能的解决方案之一是检查脚本是否正在运行sudo,如果不是则退出,并暂时放弃运行应以普通用户身份运行的命令的权限。像这样的东西:

#!/usr/bin/env sh

if [ -z "$SUDO_USER" ]
then
    printf "Not running with sudo. Exiting\n"
    exit 1
fi

touch SUDO-FILE

# drop privileges temporarily
su "$SUDO_USER" -c 'touch REGULAR-FILE'

运行后,您可以看到 2 个文件 -SUDO-FILE由 root 及其主要组拥有,以及REGULAR-FILE由普通用户及其主要组拥有的文件:

$ ls -Alhtr SUDO-FILE REGULAR-FILE
-rw-r--r-- 1 root root  0 Dec  5 21:06 SUDO-FILE
-rw-r--r-- 1 ja   users 0 Dec  5 21:06 REGULAR-FILE

在 Slackware Linux 和 FreeBSD 上进行了测试。您还可以使用su -l它来获取常规用户的 shell 登录脚本,例如~/.profile.

我不确定该解决方案有哪些缺点和可能的陷阱,因此请确保在生产中使用它之前进行了一些测试。

答案2

我会把你的脚本分成两部分:

  • 构建一个,不需要以 root 身份运行。 (您当前的install.sh将被重命名build.sh

  • 需要安装一个,需要以 root 身份运行。 (真实的deploy.sh)。

而且,为什么不调用第三个脚本install.sh并执行以下操作:

  1. 定期打电话build.sh
  2. 称呼sudo deploy.sh

相关内容