私はここで初めてで、bash/linuxに初めて触れました。
先生は、sudoを使用するのではなく、「実際の」ルートの場合にのみスクリプトが実行されるようにする課題を与えられました。 2時間検索して努力した後、私は彼が風を吸っていると考え始めました。ルートだけを許可すると簡単ですが、sudoで実行しているユーザーはどのように除外しますか?
これが私が持っているものです:
if [[ $EUID -ne 0 ]]; then
echo "You must be root to run this script."
exit
fi
答え1
私が考えることができる唯一の方法は、SUDO_*
sudoが設定した環境変数の1つをチェックすることです。
#!/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設定で動作します。
ユーザーとしてログインしてrootを使用するsudo
か、su
rootになっても変更されず、/proc/self/loginuid
ゼロ以外の値になります。ルートとして直接ログインすると、cat /proc/self/loginuid
これが返されます0
。このファイルはrootユーザーでも変更できません。 編集する Stéphane Chazelasのコメントありがとうございます。ルートは使用できますが、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コードは良いですが、残念ながら簡単にバイパスできます。