允许 bash 脚本以 root 身份运行,但不允许 sudo

允许 bash 脚本以 root 身份运行,但不允许 sudo

我是新来的,也是 bash/linux 的新手。

我的老师给我布置了一项作业,要求仅当您是“真正”root 时才允许运行脚本,而不是在使用 sudo 时运行。经过两个小时的搜索和尝试,我开始认为他在欺骗我。仅允许 root 很容易,但如何排除使用 sudo 运行它的用户?

这就是我所拥有的:

if [[ $EUID -ne 0 ]]; then
  echo "You must be root to run this script."
  exit
fi

答案1

我能想到的唯一方法是检查SUDO_*sudo 设置的环境变量之一:

#!/usr/bin/env sh

if [ "$(id -u)" -eq 0 ]
then
    if [ -n "$SUDO_USER" ]
    then
        printf "This script has to run as root (not sudo)\n" >&2
        exit 1
    fi
    printf "OK, script run as root (not sudo)\n"
else
    printf "This script has to run as root\n" >&2
    exit 1
fi

请注意,当然这个解决方案并不是面向未来的,因为您无法阻止任何人在运行脚本之前设置变量:

$ su
Password:
# SUDO_USER=whatever ./root.sh
This script has to run as root (not sudo)
# ./root.sh
OK, script run as root (not sudo)

答案2

另一种选择是检查祖父母进程名称是否为“sudo”:

#!/bin/sh
if [ "$(id -u)" -eq 0 ]
then
  if [ $(ps -o comm= -p $(ps -o ppid= -p $$)) = "sudo" ]
  then
    echo Running under sudo
  else
    echo Running as root and not via sudo
  fi
else
  echo Not running as root
fi

答案3

有关哪个用户登录的信息可在 中找到/proc/self/loginuid编辑 由于评论:该文件似乎并不存在于所有系统上。我进行了测试,它可以在 Centos 6、Fedora 32、Fedora 33 和 Ubuntu 20.04 上使用,所有这些都采用标准 x86_64 设置。 如果我们以用户身份登录并使用sudosu成为 root,则这不会改变/proc/self/loginuid,并且它将是某个非零值。如果我们直接以 root 身份登录,cat /proc/self/loginuid则会返回0请注意,该文件无法修改,即使 root 也无法执行此操作。 编辑 由于 Stéphane Chazelas 的评论:Root 可以使用echo 0 > /proc/self/loginuid.但是,可以通过设置来防止这种情况auditctl --loginuid-immutable

检查真实根目录(如果auditctl --loginuid-immutable已设置)的脚本可能如下所示

#!/bin/bash
loginuid=$(cat /proc/self/loginuid)
echo $loginuid
if [[ $loginuid -ne 0 ]]; then
    echo "You did not log in as root."
    exit
fi

答案4

我建议检查进程列表字符串并查看用户是否正在使用sudo

contype=`tty | cut -d '/' -f 3`
tty="$contype/`tty | cut -d '/' -f 4`"

if [ "$(id -u)" -eq 0 ]
then
    res=`ps ax | grep "$tty" | grep "$0" | grep "sudo"`
    if [ $? == 0 ]
    then
        echo "You should not run the script using sudo!"
        exit 2
    else
        echo "Done."
    fi
else
    echo "You are not root. Run this script as root."
    exit 2
fi

res如果您想再次过滤结果,该变量非常适合您。

Arkadusz 代码很好,但不幸的是它可以很容易被绕过......

相关内容