Debian

如何不是每天而是每隔幾個小時執行一次無人值守升級

  • September 13, 2019

預設情況下,無人值守升級與 cron.daily 一起執行,最多每天執行一次。對於攻擊者來說,這可能是很多時間。我想每 4 小時執行一次,我該怎麼做?

老問題,但是對於任何可能遇到與我相同問題的人來說:

在 Ubuntu 16.04(可能還有其他 systemd 系統)上,無人值守升級不再由 cron 觸發。相反,它使用 systemd 計時器。

為了修改執行時間和隨機延遲,您需要修改/覆蓋計時器。更多資訊可以在這裡找到: https ://github.com/systemd/systemd/issues/3233

無人值守升級的頻率分兩步確定:

  1. 系統調度程序(例如 systemd 計時器或 cron/anacron),以及
  2. APT::週期性間隔。

其中一個頻率較低會阻礙另一個頻率較高,因此請確保兩個步驟的設置都是正確的。

第二步(APT::Periodic 間隔)需要 apt 版本 1.5 或更高版本,頻率高於每天一次。Debian 10 (buster) 附帶 apt 1.8.2,所以沒問題。

如果你使用低於 1.5 的 apt 版本,例如 Debian 9 (stretch),那麼第二步就會有問題。滾動到此答案的底部,看看您是否願意在從第 1 步開始之前應用那裡建議的醜陋解決方法。

另請注意,與 的正常用法一樣,和/apt之間也有區別。第一個是關於更新可用包的列表,而第二個是關於包的升級。同樣,請確保更改兩者的設置。update``upgrade``install

1.系統調度器

在 Debian 9 (stretch) 和 Debian 10 (buster) 中,程序由以下兩個 systemd 計時器啟動:

  • apt-daily.timer,它通過apt-daily.service呼叫/usr/lib/apt/apt.systemd.daily update更新包列表 ( apt-get update),以及
  • apt-daily-upgrade.timer,它通過apt-daily-upgrade.service呼叫/usr/lib/apt/apt.systemd.daily install安裝升級 ( unattended-upgrade)。

(anacron 作業/etc/cron.daily/apt-compat仍然存在,但如果它檢測到 systemd 則會退出。如果沒有 systemd,它將在/usr/lib/apt/apt.systemd.daily沒有子命令的情況下執行,這意味著updateinstall。如果您不使用 systemd,請參閱其他答案或有關更改計劃的 anacron 文件。)

通過覆蓋預設計劃,可以將 systemd 計時器設置為以更高的頻率觸發,在您的範例中每四個小時觸發一次。首先,更新包列表:

$ sudo systemctl edit apt-daily.timer

這會創建/etc/systemd/system/apt-daily.timer.d/override.conf. 填寫如下:

[Timer]
OnCalendar=
OnCalendar=*-*-* 0,4,8,12,16,20:00
RandomizedDelaySec=15m

然後,對於 20 分鐘後的實際升級:

$ sudo systemctl edit apt-daily-upgrade.timer

[Timer]
OnCalendar=
OnCalendar=*-*-* 0,4,8,12,16,20:20
RandomizedDelaySec=1m

檢查您的工作:

$ systemctl cat apt-daily{,-upgrade}.timer
$ systemctl --all list-timers apt-daily{,-upgrade}.timer

(部分取自Debian Wiki:UnattendedUpgrades。)

2. APT::週期性間隔

系統調度程序呼叫腳本/usr/lib/apt/apt.systemd.daily,該腳本使用文件戳機制來確定上次執行請求的操作的時間。它將這與在 APT::Periodic 中為該操作設置的間隔進行比較。您通常應該在以下位置找到這些設置/etc/apt/apt.conf.d/20auto-upgrades

APT::Periodic::Update-Package-Lists "1";
APT::Periodic::Unattended-Upgrade "1";

我一直認為"1"這裡的值只是表示 True 或 On,但實際上,它是執行之間的最小間隔,以天表示。如果腳本確定自上次執行請求的操作以來經過的時間更短,它就不會執行該操作,而不管系統調度程序是否呼叫了它。

現在,在 apt 1.5~beta2 中,Paul Wise 可以通過添加後綴來定義以秒、分鐘和小時為單位的時間間隔sm或者h,因此您可以更改/etc/apt/apt.conf.d/20auto-upgrades為:

APT::Periodic::Update-Package-Lists "3h";
APT::Periodic::Unattended-Upgrade "3h";

(小於"4h",以說明系統調度程序中的隨機延遲。)

更好的是,他可以設置間隔以**"always"**確保在請求時執行操作,無論自上次執行以來已經過去了多少時間:

APT::Periodic::Update-Package-Lists "always";
APT::Periodic::Unattended-Upgrade "always";

我更喜歡這個,因為你設置了一次,從那時起,如果你想改變頻率,你只需要與系統調度程序(systemd timers)互動。

與 apt <1.5

Debian 9 (stretch) 附帶 apt 1.4.9,因此將 APT::Periodic 間隔設置為"always""3h"如步驟 2 中所述將不起作用。順便說一句,間隔"0.1"幾天也行不通。

如果您不介意一個醜陋的解決方法,請編輯腳本以/usr/lib/apt/apt.systemd.daily通過插入函式來排除時間戳機制(使用風險自負!):return 0``check_stamp()

--- a/lib/apt/apt.systemd.daily
+++ b/lib/apt/apt.systemd.daily
@@ -82,10 +82,12 @@ check_stamp()
       debug_echo "check_stamp: interval=0"
       # treat as no time has passed
        return 1
    fi

+    return 0
+
    if [ ! -f $stamp ]; then
       debug_echo "check_stamp: missing time stamp file: $stamp."
       # treat as enough time has passed
        return 0
    fi

這樣,腳本將始終認為時間間隔已過,因此它將執行請求的任何操作。當您升級 apt 時,此解決方法應該會被覆蓋,然後您可以"always"按照上述步驟 2 中的說明切換到使用。

如果您不想弄亂腳本,請考慮使用其他一些答案中描述的自定義 cron 作業。在這種情況下,您也無需擔心此答案的第 1 步。

引用自:https://unix.stackexchange.com/questions/178626