Debian:如何在启动时使用 sudo bash 脚本而无需密码

Debian:如何在启动时使用 sudo bash 脚本而无需密码

我正在进行 Debian 11 测试。这是一台低端计算机,适用于计算机经验很少的用户,我希望使用不提示用户输入密码的脚本使其保持最新状态。

遵循几个主题的建议(例如这里):

所以我写了一个像这样的简单脚本/home/user/Documents/update.sh

#!/bin/bash
sudo apt update -y
sudo apt upgrade -y
sudo apt autoclean -y
sudo apt autoremove -y

然后我使脚本可执行:

chmod a+x /home/user/Documents/update.sh

然后我给了用户user权限,visudo以免询问密码

user ALL=(ALL:ALL) NOPASSWD:/home/user/Documents/update.sh, /usr/bin/apt update, /usr/bin/apt upgrade, /usr/bin/apt autoclean, /usr/bin/apt autoremove

在终端上运行命令进行测试后sh '/home/user/Documents/update.sh',该脚本无需输入密码即可运行。

第一次尝试在启动时使用 crontab 运行脚本:

为了在每次启动时运行脚本,我修改了crontab -u user -e(我也直接使用测试crontab -e):

@reboot sh '/home/user/Documents/update.sh'

但每次重新启动时:没有脚本启动。

第二次尝试使用 Gnome Tweaks 和桌面文件在启动时运行脚本:

作为替代方案,我尝试创建一个update.desktop文件,/usr/share/applications在其中双击启动脚本:

[Desktop Entry]
Name=update
Exec=sh '/home/user/Documents/update.sh'
Terminal=true
Type=Application
Encoding=UTF-8

测试后,双击该文件即可运行脚本,无需输入密码

然后,与侏儒调整,我在启动时将文件添加updates.desktop为应用程序

这就是我的第二个问题出现的地方:脚本在启动时启动,但要求我输入密码。

然后我不明白为什么会发生这种情况(Gnome Tweaks 是否在另一个用户下运行,等等)。

问题 :

  1. 为什么 crontab 方法不起作用? (我已经启动了 crontab 服务以确保)
  2. 为什么 Gnome Tweak 方法提示我输入密码以及如何解决此问题?

非常感谢。

答案1

您可以做的最基本的事情是/usr/bin在脚本中添加前缀:

#!/bin/bash
sudo /usr/bin/apt update -y
sudo /usr/bin/apt upgrade -y
sudo /usr/bin/apt autoclean -y
sudo /usr/bin/apt autoremove -y

这将起作用,因为您允许用户运行/usr/bin/apt但不允许apt。这实际上很好,因为它可以阻止某人调用自己的恶意程序apt并将其放入$PATH.但是,我建议不要这样做,因为依赖于 NOPASSWD 选项的脚本并不是最好的。


下一个最简单的解决方案可能是替换sudopkexec与桌面条目一起使用的脚本。 pkexec是 的一部分polkit,并且是 的 GUI 版本sudo。它会使您的 gnome 会话变暗并提示输入密码,而不是使用终端。

#!/bin/bash
pkexec /usr/bin/apt update -y
pkexec /usr/bin/apt upgrade -y
pkexec /usr/bin/apt autoclean -y
pkexec /usr/bin/apt autoremove -y

还有一些方法可以让用户在没有交互式提示的情况下执行某些操作。您需要为此查找 polkit 规则。例如,这可以适用于/usr/share/polkit-1/actions/org.update.policy

<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE policyconfig PUBLIC
 "-//freedesktop//DTD PolicyKit Policy Configuration 1.0//EN"
 "http://www.freedesktop.org/standards/PolicyKit/1/policyconfig.dtd">
<policyconfig>
  <vendor>Your name</vendor>
  <action id="org.update">
    <description>Update the system</description>
    <message>This will run apt update/upgrade and then autoremove.</message>
    <defaults>
      <allow_any>yes</allow_any>
      <allow_inactive>yes</allow_inactive>
      <allow_active>yes</allow_active>
    </defaults>
    <annotate key="org.freedesktop.policykit.exec.path">/usr/bin/apt</annotate>
  </action>
</policyconfig>

但是,最好的答案(特别是如果您更喜欢非交互性)是将其作为服务运行。一个简单的解决方案可能是:

#/etc/systemd/system/update.service
[Unit]
Description=Auto upgrade
After=network-online.target

[Service]
Type=oneshot
ExecStart=/usr/bin/apt update -y
ExecStart=/usr/bin/apt upgrade -y
ExecStart=/usr/bin/apt autoclean -y
ExecStart=/usr/bin/apt autoremove -y

[Install]
WantedBy=multi-user.target

然后用于sudo systemctl enable --now update.service运行它并为下一次启动做好准备。


apt(至少在 Debian 发行版中)已经有类似于服务解决方案的东西: 每天触发一次并为您做一些更新apt-daily.serviceapt-daily-upgrade.service

看一眼

/etc/apt/apt.conf.d/50unattended-upgrades以及/usr/lib/apt/apt.systed.daily有关如何配置它来执行您想要的操作的说明。我认为这个解决方案甚至比制作您自己的服务更好,因为可能破坏您系统的边缘情况和稳定性已经由其作者解决了apt。例如,如果自动清理会卸载libc6,或者linux-*此脚本将避免这种情况。

像这样的东西可能会起作用(默认情况下这些值都是 0 禁用):

# /etc/apt/apt.conf.d/10periodic

# Run 'apt update' every day
APT::Periodic::Update-Package-Lists 1

# Run 'apt-get autoclean' every 1 day
APT::Periodic::AutocleanInterval 1

# Run apt-get clean every 1 day
APT::Periodic::CleanInterval 1

# Run unattended-upgrade every 1 day 
# This is similar to `apt upgrade` depending on your configuration
# (requires package 'unattended-upgrade')
# This effectively does the 'apt upgrade'
APT::Periodic::Unattended-Upgrade 1

# Run `apt autoremove` after upgrading
# This may be set in /etc/apt/apt.conf.d/50unattended-upgrades
#  You might want to set this in that other file to avoid
#  getting confused about what goes where
Unattended-Upgrade::Remove-Unused-Dependency "true"

答案2

请注意,这是我设置的方式无人值守升级

Debian 软件包

  1. 我必须安装无人值守升级

    sudo apt install unattended-upgrades
    
  2. 然后sudo nano /etc/apt/apt.conf.d/50unattended-upgrades修改配置文件,至少将以下几行取消注释:

    ...
    "origin=Debian,codename=${distro_codename}-updates";
    "origin=Debian,codename=${distro_codename}-proposed-updates";
    "origin=Debian,codename=${distro_codename},label=Debian";
    "origin=Debian,codename=${distro_codename},label=Debian-Security";
    ...
    Unattended-Upgrade::AutoFixInterruptedDpkg "true";
    Unattended-Upgrade::MinimalSteps "true";
    ...
    Unattended-Upgrade::Remove-Unused-Kernel-Packages "true";
    ...
    Unattended-Upgrade::Remove-New-Unused-Dependencies "true";
    Unattended-Upgrade::Remove-Unused-Dependencies "true";
    ...
    Unattended-Upgrade::OnlyOnACPower "false";
    
  3. 然后,为了在启动时启动更新(因为计算机使用的次数不多,所以可能需要安全补丁),我需要一个新服务:

    sudo nano /etc/systemd/system/unattended-upgrades.service
    

    包含:

    [Unit]
    Description=Unattended Upgrades
    After=apt-daily.service apt-daily-upgrade.service apt-daily-upgrade.timer apt-get-upgrade.service
    
    [Service]
    ExecStart=/usr/bin/unattended-upgrade
    
    [Install]
    WantedBy=multi-user.target
    
  4. 现在,启用该服务:

    systemctl enable unattended-upgrades.service
    
  5. 然后为了每天得到这个,我们必须运行sudo nano /etc/apt/apt.conf.d/20auto-upgrades并使用以下内容修改它:

APT::Periodic::Download-Upgradeable-Packages "1";
APT::Periodic::Unattended-Upgrade "1";
APT::Periodic::AutocleanInterval "1";
APT::Periodic::CleanInterval 1;
  1. 最后,为了在启动时得到这个(如我所愿),您必须首先使用sudo systemctl edit apt-daily.timer以下内容运行(定时 apt 更新服务):
[Unit]
Description=Daily apt download activities

[Timer]
OnStartupSec=20
RandomizedDelaySec=5
Persistent=true

[Install]
WantedBy=timers.target

并运行sudo systemctl edit apt-daily-upgrade.timer以下内容:

[Unit]
Description=Daily apt upgrade and clean activities
After=apt-daily.timer

[Timer]
OnStartupSec=60
RandomizedDelaySec=10
Persistent=true

[Install]
WantedBy=timers.target

弗莱帕克

  1. 对于 Flatpak 来说也是如此,我们首先要运行sudo nano /etc/systemd/system/flatpak-update.service以下内容:
[Unit]
Description=Update Flatpak
After=network-online.target
Wants=network-online.target

[Service]
Type=oneshot
ExecStart=/usr/bin/flatpak update --noninteractive --assumeyes

[Install]
WantedBy=multi-user.target
  1. 我们还必须运行sudo nano /etc/systemd/system/flatpak-update.timer以下内容:
[Unit]
Description=Update Flatpak

[Timer]
OnBootSec=2m
OnActiveSec=2m
OnUnitInactiveSec=24h
OnUnitActiveSec=24h
AccuracySec=1h
RandomizedDelaySec=10m

[Install]
WantedBy=timers.target
  1. 最后,我们必须连续运行:
systemctl enable flatpak-update.service
systemctl enable flatpak-update.timer
systemctl start flatpak-update.service
systemctl start flatpak-update.timer

感谢Stewart,所有帮助我的成员,还有ChatGPT!

相关内容