sudoers 中引用的操作在 Kill 命令上仍然失败

sudoers 中引用的操作在 Kill 命令上仍然失败

我希望能够从 Node-RED 中重新启动 ConnMan。该服务由其自己的用户运行nodered

当我以用户身份 SSH 进入设备nodered并键入

nodered@pi:~$ sudo /etc/init.d/connman restart

这样可行。

但是,当我调用visudo并添加以下行时:

nodered ALL = (root) NOPASSWD: /etc/init.d/connman restart

执行命令时它给我以下错误:

nodered@pi:~$ /etc/init.d/connman restart
Restarting Connection Manager
/etc/init.d/connman: line 47: kill: (28874) - Operation not permitted

失败的行/etc/init.d/connman是:

do_stop() {
        # kill the script monitoring execution
        if [ "X${pid=$(pidof -x /usr/sbin/connmand-watch.sh)}" != "X" ]; then
                kill $pid 

答案1

如果服务及其观察程序都以用户身份运行nodered并且您以同一用户身份登录,那么您sudo根本不需要:进程的所有者将始终有权终止它,即使kill -9有必要也是如此。

sudoers行:

nodered ALL = (root) NOPASSWD: /etc/init.d/connman restart

授予nodered用户以 root 身份运行命令的能力/etc/init.d/connman restart。如果脚本或服务本身不能确保服务及其观察程序都以用户身份启动nodered,则运行此脚本sudo可能会产生意外的副作用,connmand-watch.sh即以 root 拥有的进程重新启动服务和/或脚本。当心。

使用kill -0,您可以测试是否可以杀死进程,而无需真正发送任何信号。您可以在脚本的开头执行类似的操作/etc/init.d/connman

if [ $(whoami) != "root" ]; then
    watcherpid=$(pidof -x /usr/sbin/connmand-watch.sh)
    if [ "" != "$watcherpid" ] && ! kill -0 "$watcherpid" 2>/dev/null; then
        # Watcher exists but cannot be signaled so it runs as some other user.
        # Attempt to re-execute this script with root powers.
        exec sudo /etc/init.d/connman "$@"
        # If we reach this line, we could not exec sudo. That's bad.
        exit 1
    fi
fi

使用exec sudo /etc/init.d/connman "$@",脚本将通过 sudo 重新运行。由于exec,脚本的常规非特权副本的执行将立即结束,并且sudoed 版本将使用与原始调用相同的命令行参数来替换它。

如果无法找到观察程序进程,或者脚本已经以 root 身份运行,则此测试将失败,无需执行任何操作。

注意:如果脚本尝试重新运行自身sudo并且尝试失败,则脚本将停止而不执行任何操作。

相关内容