远程设置 DEBIAN_FRONTEND

远程设置 DEBIAN_FRONTEND

有没有办法设置DEBIAN_FRONTEND=noninteractive何时通过 SSH 远程执行脚本?

这样做我会收到此错误:

sudo: sorry, you are not allowed to set the following environment variables: DEBIAN_FRONTEND

我之所以要设置DEBIAN_FRONTEND=noninteractive在此处,是因为有时apt-get dist-upgrade会显示一些用户交互的掩码(whiptail)。因为想要通过远程方式运行此脚本,crontab -e所以没有人可以点击或按任何东西。因此,我需要关闭它,否则脚本将卡住。

我尝试执行的脚本server_one位于/usr/local/bin/perform-update

#!/bin/bash

sudo apt-get update
sudo DEBIAN_FRONTEND=noninteractive apt-get -y dist-upgrade
sudo apt-get -y autoremove
sudo snap refresh

我尝试server_two使用此命令来调用它:

SERVER_COMMAND="perform-update"
ssh -i $HOME/.ssh/id_rsa backupuser@server_one $SERVER_COMMAND

backupuser我还为server_one设置了适当的权限sudo visudo

backupuser      ALL=(ALL) NOPASSWD: /usr/local/bin/perform-update
backupuser      ALL=(ALL) NOPASSWD: /usr/bin/apt-get
backupuser      ALL=(ALL) NOPASSWD: /usr/bin/snap

答案1

DEBIAN_FRONTEND您可以允许用户在使用时设置变量sudo,但是......您已授予用户使用执行脚本的权限sudo,因此没有理由再使用sudo 里面脚本。只需使用 运行脚本本身即可sudo

将您的脚本更改为:

#! /bin/bash
apt-get update
DEBIAN_FRONTEND=noninteractive apt-get -y dist-upgrade
DEBIAN_FRONTEND=noninteractive apt-get -y autoremove
snap refresh

然后使用以下命令运行它:

ssh -i "$HOME/.ssh/id_rsa" backupuser@server_one sudo "$SERVER_COMMAND"

这就是说,您应该使用unattended-upgrades而不是重新发明轮子。


对于允许用户为特定命令设置环境变量的特殊情况,SETENV除了标签外,还需添加标签NOPASSWD。从man sudoers

 SETENV and NOSETENV

   These tags override the value of the setenv flag on a per-command basis.  If SETENV has
   been set for a command, the user may disable the env_reset flag from the command line via
   the -E option.  Additionally, environment variables set on the command line are not
   subject to the restrictions imposed by env_check, env_delete, or env_keep.  As such, only
   trusted users should be allowed to set variables in this manner.  If the command matched
   is ALL, the SETENV tag is implied for that command; this default may be overridden by use
   of the NOSETENV tag.

因此规则应如下所示:

backupuser      ALL=(ALL) NOPASSWD:SETENV: /usr/bin/apt-get

答案2

出于所有实际目的和目的,请参阅@muru 的回答。如果时间紧迫,只需要sudo更改 server_two 上的行,而不需要编辑 server_one 上的脚本。但出于安全原因,应该全部遵循,并在答案末尾加上我的编辑。ssh/usr/local/bin/perform-update

如果我们换个角度考虑会怎么样?如果我们无法更改 server_two 上的命令,而只能更改 server_one 上的命令会怎么样?我正在寻找一个 APT 选项来设置环境变量,但我发现的比我预期的要多。这是一个离谱的开箱即用的答案,只是为了证明您的/etc/sudoers策略需要得到保护。

#!/bin/bash
# Put this in /usr/local/bin/perform-update
# No need to manually change any other file

# Use the -o to inject any arbitrary apt-config option.
# First write a wrapper file to execute later that
# sets up DEBIAN_FRONTEND=noninteractive and passes on the arguments.
sudo apt-get update -o APT::Update::Pre-Invoke::='echo '\'$'#!/bin/sh\nexport DEBIAN_FRONTEND=noninteractive\nexec /usr/bin/dpkg "$@"'\'' > /usr/dpkg; chmod 700 /usr/dpkg'
# Then use -o again to make dist-upgrade use the wrapper.
sudo apt-get -y dist-upgrade -o Dir::Bin::dpkg=/usr/dpkg
# autoremove should use DEBIAN_FRONTEND=noninteractive too because
# removing some packages like display managers may cause prompting.
sudo apt-get -y autoremove -o Dir::Bin::dpkg=/usr/dpkg
sudo snap refresh

我认为您无意授予backupuser完全 root 访问权限。为了保护您的系统,您需要删除中的apt-getsnapvisudo,然后按照@muru 的回答操作。

编辑:除了你需要删除apt-get中的行visudo。这 3 行应该只替换为第一行:

backupuser      ALL=(ALL) NOPASSWD: /usr/local/bin/perform-update

相关内容