วิธีแก้ปัญหา unattended-upgrades ไม่ทำงานบน Debian
สาเหตุที่ unattended-upgrades ไม่ทำงานบน Debian เพราะค่าเริ่มต้นถูกปิดไว้ เรียนรู้วิธีเปิดใช้งานผ่าน Origins-Pattern ตรวจสอบ apt-daily timers และทดสอบการอัปเดตจริง
เหตุใด unattended-upgrades จึงไม่ทำงานบน Debian ที่ติดตั้งใหม่
บน Debian นั้น unattended-upgrades อาจถูกติดตั้งไว้แต่ไม่เคยทำการอัปเกรดเลยแม้แต่ครั้งเดียว เนื่องจากขั้นตอนการติดตั้งแพ็กเกจและขั้นตอนการเปิดใช้งานเป็นคนละส่วนกัน แพ็กเกจจะถามคำถามผ่าน debconf ก่อนที่จะกำหนดค่าตัวเอง ซึ่งค่าเริ่มต้นของแพ็กเกจคือใช่ (yes) แต่ตัวติดตั้งของ Debian จะถามคำถามเกี่ยวกับการอัปเดตแยกต่างหากก่อน โดยค่าเริ่มต้นคือไม่ให้มีการอัปเดตอัตโนมัติ และตัวเลือกนั้นจะบันทึกคำตอบ false สำหรับคำถามของแพ็กเกจไว้ในกรณีที่มีการติดตั้งแพ็กเกจในภายหลัง ในขณะที่ Ubuntu เลือกคำตอบสำหรับคำถามเดียวกันในทางตรงกันข้าม จึงเป็นเหตุผลว่าทำไมแพ็กเกจเดียวกันถึงดูเหมือนทำงานได้บน Ubuntu แต่ดูเหมือนเสียบน Debian
ไม่มีส่วนใดในระบบที่แจ้งเตือนเรื่องนี้ ไม่มีการแสดงข้อผิดพลาดขณะบูต ไม่มีการแจ้งเตือนเมื่อล็อกอิน และไม่มีไฟล์ log ให้อ่าน เนื่องจากโค้ดที่จะเขียน log นั้นไม่เคยถูกเรียกใช้งาน การเปิดใช้งานทำได้ด้วยคำสั่งเดียว ส่วนที่เหลือของคู่มือนี้จะครอบคลุมปัจจัย 4 ประการที่อาจทำให้ระบบยังคงไม่ทำงานหลังจากเปิดใช้งานแล้ว ได้แก่ แหล่งเก็บแพ็กเกจ (repositories) ที่อนุญาตให้อัปเกรด, เวลาที่ systemd timers ทำงานจริง, วิธีการตรวจสอบเมื่อการทำงานล้มเหลว และการอนุญาตให้เครื่องรีบูตตัวเองได้หรือไม่
ตรวจสอบการตั้งค่าปัจจุบันก่อนดำเนินการเปลี่ยนแปลงใดๆ
dpkg -l unattended-upgrades | tail -n 1
sudo apt install -y debconf-utils
sudo debconf-show unattended-upgrades
cat /etc/apt/apt.conf.d/20auto-upgrades
apt-config dump APT::Periodicdebconf-show จะแสดงค่าที่บันทึกไว้สำหรับ unattended-upgrades/enable_auto_updates หากมี * ปรากฏที่ต้นบรรทัด แสดงว่ามีการกำหนดค่าดังกล่าวไว้แทนที่จะใช้ค่าเริ่มต้นของแพ็กเกจ สำหรับเครื่องที่ติดตั้งผ่าน Debian installer ตัวติดตั้งจะเป็นผู้กำหนดค่านี้
cat อาจแสดงผลเป็น cat: /etc/apt/apt.conf.d/20auto-upgrades: No such file or directory ซึ่งอธิบายถึงความเงียบของระบบได้ในตัว: เมื่อไม่มีไฟล์ดังกล่าว ก็จะไม่มีการกำหนดคีย์สำหรับการทำงานเป็นรอบ ทำให้ไม่มีการตั้งเวลาการทำงานใดๆ ไว้
apt-config dump คือคำสั่งที่สำคัญ APT จะอ่านไฟล์ใน /etc/apt/apt.conf.d/ ตามลำดับชื่อไฟล์และรวมค่าเข้าด้วยกัน ดังนั้นค่าที่กำหนดใน 99local จะเขียนทับค่าเดียวกันใน 20auto-upgrades เฉพาะไฟล์ที่ไม่มีนามสกุลหรือมีนามสกุล .conf เท่านั้นที่จะถูกนำมาพิจารณา ดังนั้นไฟล์อย่าง 99local.bak จะถูกข้ามไป การอ่านไฟล์เดียวจะบอกคุณเฉพาะสิ่งที่ไฟล์นั้นระบุ แต่ apt-config dump จะบอกคุณว่า APT จะดำเนินการอย่างไรจริง
มีสองคีย์ที่ตัดสินว่าระบบจะทำงานหรือไม่:
APT::Periodic::Update-Package-Listsทำหน้าที่รีเฟรชรายการแพ็กเกจ ซึ่งเป็นงานเดียวกับที่apt updateทำด้วยตนเองAPT::Periodic::Unattended-Upgradeทำหน้าที่ดำเนินการอัปเกรด
ค่าของคีย์เหล่านี้ไม่ใช่ true หรือ false แต่เป็นช่วงเวลาในหน่วยวัน "1" หมายถึง "ให้ทำหากยังไม่ได้ทำภายใน 1 วันที่ผ่านมา" "7" หมายถึงรายสัปดาห์ และ "0" หมายถึงไม่ทำเลย APT::Periodic::Unattended-Upgrade "0"; เป็นการตั้งค่าที่ถูกต้องซึ่งจะไม่มีการทำงานใดๆ เกิดขึ้นตลอดไปโดยไม่มีการแจ้งเตือน หากผลการตรวจสอบของคุณแสดงค่า 0 สำหรับคีย์ดังกล่าว หรือไม่พบการตั้งค่าคีย์นั้นเลย นั่นคือสาเหตุที่ระบบไม่ทำงาน
เปิดใช้งาน: ใช้ dpkg-reconfigure หรือเขียนค่าคอนฟิกด้วยตนเอง
sudo apt update
sudo apt install -y unattended-upgrades
sudo dpkg-reconfigure --priority=low unattended-upgradesคำถามนี้ถูกตั้งค่าไว้ที่ระดับความสำคัญต่ำ จึงเป็นเหตุผลว่าทำไมการติดตั้งตามปกติถึงไม่แสดงคำถามนี้ขึ้นมา dpkg-reconfigure จะแสดงคำถามระดับความสำคัญต่ำโดยไม่คำนึงถึงระดับความสำคัญของ debconf ที่คุณตั้งค่าไว้ ดังนั้น --priority=low จึงเป็นเพียงการระบุสิ่งที่ทำงานอยู่แล้วเท่านั้น แฟล็กเดียวที่ควรหลีกเลี่ยงคือ --default-priority ซึ่งจะปิดการทำงานดังกล่าวและซ่อนคำถามไว้อีกครั้ง ให้ตอบตกลงในกล่องโต้ตอบ จากนั้นสคริปต์ postinst ของแพ็กเกจจะเขียนค่า /etc/apt/apt.conf.d/20auto-upgrades ตามคำตอบของคุณ
บนเครื่องที่คุณสร้างจากสคริปต์ จะไม่มีกล่องโต้ตอบให้ตอบ ดังนั้นให้ตั้งค่าคำตอบไว้ล่วงหน้า:
echo 'unattended-upgrades unattended-upgrades/enable_auto_updates boolean true' \
| sudo debconf-set-selections
sudo dpkg-reconfigure -f noninteractive unattended-upgrades
apt-config dump APT::Periodicคุณยังสามารถเขียนคีย์ทั้งสองค่าลงไปโดยตรงได้ดังนี้:
printf 'APT::Periodic::Update-Package-Lists "1";\nAPT::Periodic::Unattended-Upgrade "1";\n' \
| sudo tee /etc/apt/apt.conf.d/20auto-upgrades
apt-config dump APT::Periodicวิธีนี้จะเห็นผลทันที สคริปต์คอนฟิกของแพ็กเกจจะอ่านไฟล์นี้กลับเข้าไปใน debconf ก่อนที่จะถามคำถาม ดังนั้นการเรียกใช้ dpkg-reconfigure ในภายหลัง หรือการติดตั้งแพ็กเกจใหม่ จะพบค่า "1" ของคุณและคงค่าเดิมไว้ อย่างไรก็ตาม สคริปต์จะจดจำเฉพาะบรรทัดที่ระบุไว้เป๊ะๆ คือ APT::Periodic::Unattended-Upgrade "1"; และ APT::Periodic::Unattended-Upgrade "0"; เท่านั้น หากคุณเลือกช่วงเวลาอื่น เช่น "7" ค่า false ที่ตัวติดตั้งจัดเก็บไว้จะยังคงอยู่ และสคริปต์ postinst จะพยายามสลับไปใช้ไฟล์เวอร์ชันที่ปิดการทำงานไว้แทน ทุกครั้งที่คุณเขียนไฟล์ด้วยตนเองโดยใช้ค่าอื่นที่ไม่ใช่ "1" ให้ตั้งค่าคำตอบใน debconf ควบคู่ไปด้วย
นี่คือความแตกต่างเพียงอย่างเดียวเมื่อเทียบกับระบบปฏิบัติการในตระกูลเดียวกัน ในระบบนั้นตัวติดตั้งจะเปิดใช้งานแพ็กเกจเดียวกันให้คุณโดยอัตโนมัติ ดังนั้น การตั้งค่า unattended-upgrades ของ Ubuntu จึงเริ่มต้นจากระบบที่ทำการแพตช์ตัวเองอยู่แล้ว และคุณสามารถใช้เวลาไปกับการปรับแต่งค่าต่างๆ ได้ทันที เนื้อหาทั้งหมดหลังจากจุดนี้สามารถนำไปใช้ได้กับทั้งสองระบบ
Debian ติดตั้งอัปเดตอะไรให้คุณบ้าง
การเปิดใช้งาน timer ไม่ได้หมายความว่าคุณตกลงที่จะติดตั้งทุกอย่าง แหล่งที่มาของแพ็กเกจแต่ละแห่งจะมีข้อมูล metadata ของ release กำกับอยู่ ได้แก่ origin, label, suite, codename และ site โดย unattended-upgrades จะตรวจสอบเวอร์ชันที่สามารถอัปเกรดได้ของแต่ละแพ็กเกจ อ่าน metadata ของแหล่งที่มา แล้วจะติดตั้งก็ต่อเมื่อแหล่งที่มานั้นตรงกับรายการใน Unattended-Upgrade::Origins-Pattern หรือรายการใน Unattended-Upgrade::Allowed-Origins แบบเก่าเท่านั้น หากไม่ตรงกัน ระบบจะไม่ทำการอัปเกรดโดยเงียบๆ ตามการออกแบบ
พิมพ์รูปแบบของคุณออกมา แล้วพิมพ์ metadata ที่ถูกนำมาเปรียบเทียบ:
apt-config dump Unattended-Upgrade::Origins-Pattern
grep -H -E '^(Origin|Label|Suite|Codename|Components):' /var/lib/apt/lists/*Release
apt-cache policygrep -H จะเก็บชื่อไฟล์ไว้ในแต่ละบรรทัด เพื่อให้คุณเห็นว่า metadata แต่ละชุดมาจากแหล่งที่มาใด ค่าฟิลด์เหล่านั้นคือส่วนทางขวาของรูปแบบที่คุณกำหนดไว้ ส่วน ${distro_codename} ภายในรูปแบบจะถูกแทนที่ด้วย codename ของ release ที่คุณใช้งานอยู่ในขณะรัน ทำให้ไฟล์เดียวสามารถใช้งานได้ต่อเนื่องแม้จะมีการอัปเกรด release
อ่านรูปแบบของคุณโดยเทียบกับ metadata เหล่านั้น เพราะคำตอบของคำถามที่ว่า "ฉันได้รับเฉพาะการแก้ไขด้านความปลอดภัย หรือได้รับอัปเดต point release ด้วย" ถูกเขียนไว้ในรายการทั้งสองนี้เท่านั้น:
- รูปแบบที่ระบุ
label=Debian-Securityจะตรงกับคลังข้อมูลด้านความปลอดภัย ซึ่งเป็นที่ที่ Debian security advisories ถูกส่งเข้ามา - รูปแบบที่ระบุ suite
-updatesจะตรงกับ stable-updates ซึ่งบรรจุสิ่งที่ Debian ปล่อยออกมาในช่วงระหว่าง point release เช่น ข้อมูลเขตเวลา (time zone) - รูปแบบที่ระบุ suite ของ release ปกติจะดึงการเปลี่ยนแปลงของ point release ทันทีที่มีการเผยแพร่ ซึ่งจะมีการเปลี่ยนแปลงบ่อยกว่าและต้องใช้การทดสอบจากฝั่งคุณมากขึ้น
- repository ที่คุณเพิ่มเข้ามาเองจะไม่ตรงกับอะไรเลยจนกว่าคุณจะเขียนรูปแบบสำหรับมัน
ประเด็นสุดท้ายนี้มักทำให้ผู้ใช้ประหลาดใจ repository ของบุคคลที่สามมี origin และ label ของตัวเอง ดังนั้น unattended-upgrades จะเห็นแพ็กเกจ candidate เห็นว่าแหล่งที่มาไม่ตรงกับรายการใดเลย แล้วจึงข้ามไป การเพิ่มรูปแบบสำหรับ repository เหล่านี้เป็นการตัดสินใจที่ควรทำอย่างรอบคอบ เพราะ repository ของผู้ผลิตอาจปล่อย major version ใหม่ภายใน suite เดิม ซึ่งหมายความว่าคุณได้ตกลงที่จะให้อัปเกรด major version ของซอฟต์แวร์นั้นโดยอัตโนมัติในเวลากลางคืน
unattended-upgrades จะไม่อัปเกรดระบบข้าม Debian release เช่นกัน โดยจะอัปเกรดเฉพาะแพ็กเกจภายใน release ที่ใช้งานอยู่ การเปลี่ยนจาก stable release หนึ่งไปยัง stable release ถัดไปยังเป็นงานที่ต้องกำหนดเวลาและดำเนินการด้วยตนเอง หากยังใช้ Debian 11 อยู่ งานนี้เลยกำหนดแล้ว: bullseye สิ้นสุดการสนับสนุนด้านความปลอดภัยระดับ LTS เมื่อ 31 August 2026 ดังนั้น unattended-upgrades อาจยังทำงานทุกคืนได้ตามปกติ แต่ไม่มีแพ็กเกจใหม่ให้ติดตั้งอีก และ อัปเกรดเซิร์ฟเวอร์ Debian 11 ไปเป็น Debian 13 ต้องดำเนินการอย่างระมัดระวัง 2 ขั้นตอน
เมื่อคุณเปลี่ยนรายการ อย่าลืมว่ารายการของ APT จะใช้วิธีการผนวกข้อมูล (append) บล็อก Origins-Pattern ที่สองในไฟล์อื่นจะเป็นการเพิ่มเข้าไปในรายการเดิมแทนที่จะแทนที่ ดังนั้นหากคุณต้องการแทนที่รายการเดิม ให้ล้างข้อมูลก่อน:
#clear Unattended-Upgrade::Origins-Pattern;
Unattended-Upgrade::Origins-Pattern {
"origin=Debian,codename=${distro_codename},label=Debian-Security";
"origin=Debian,codename=${distro_codename}-security,label=Debian-Security";
};ให้ใส่การเปลี่ยนแปลงในเครื่องไว้ในไฟล์ใหม่ที่ถูกประมวลผลหลังจากไฟล์หลัก เช่น /etc/apt/apt.conf.d/52unattended-upgrades-local เนื่องจาก 50unattended-upgrades เป็นไฟล์คอนฟิกูเรชันที่มีการจัดการโดยระบบ เมื่อคุณแก้ไขแล้ว หากมีการอัปเกรดแพ็กเกจในภายหลังที่มีการเปลี่ยนแปลงไฟล์นี้ ระบบจะหยุดและถามคุณว่าจะจัดการกับไฟล์ของคุณอย่างไร แต่การใช้ไฟล์แยกต่างหากจะไม่เกิดความขัดแย้งนี้
มีอีกสองคีย์ที่ควรตรวจสอบในขณะที่คุณอยู่ที่นี่ Unattended-Upgrade::Allowed-Origins เป็นรูปแบบเก่าของแนวคิดเดียวกัน โดยเขียนเป็นคู่ origin:archive และระบบยังคงอ่านค่านี้อยู่ ดังนั้นคอนฟิกูเรชันที่คัดลอกมาจากบทเรียนมักจะมีทั้งสองรายการ ทำให้ไม่ชัดเจนว่ารายการใดเป็นตัวที่จับคู่ได้จริง ส่วน Unattended-Upgrade::Package-Blacklist จะเก็บ regular expression ที่ใช้ตรวจสอบชื่อแพ็กเกจ ซึ่งหากใช้ expression ที่กว้างเกินไปอาจบล็อกแพ็กเกจมากกว่าที่คุณตั้งใจไว้ การทำ dry run ด้านล่างจะพิมพ์สิ่งที่ถูกนำไปใช้จริงออกมาให้เห็น
เหตุใดงานจึงไม่ทำงานตามเวลาที่คาดไว้?
มี systemd timer สองตัวที่ควบคุมกระบวนการนี้และทำหน้าที่ต่างกัน apt-daily.timer จะเริ่มการทำงานของ apt-daily.service ซึ่งทำหน้าที่รีเฟรชรายการแพ็กเกจและดาวน์โหลดข้อมูล ส่วน apt-daily-upgrade.timer จะเริ่มการทำงานของ apt-daily-upgrade.service ซึ่งเป็นตัวเรียกใช้ unattended-upgrade ทั้งสองตัวจะรัน /usr/lib/apt/apt.systemd.daily โดยใช้ argument ที่แตกต่างกัน หาก timer ตัวที่สองถูกปิดใช้งาน (disabled) หรือถูกระงับ (masked) แม้ว่าทั้งสองคีย์จะอ่านค่าจาก 1 ได้ตามปกติ แต่ก็ไม่มีการติดตั้งแพ็กเกจใดๆ เกิดขึ้น
systemctl list-timers 'apt-daily*' --all
systemctl is-enabled apt-daily.timer apt-daily-upgrade.timer
systemctl cat apt-daily-upgrade.timerlist-timers จะแสดง NEXT, LEFT, LAST และ PASSED ของแต่ละ unit หาก timer ไม่มี NEXT งานนั้นจะไม่ทำงาน การที่ is-enabled แสดงผลเป็น masked หมายความว่ามีคนสั่งปิดการทำงานไว้อย่างถาวร และการแก้ไขค่าใน apt.conf.d จะไม่ส่งผลใดๆ ทั้งสิ้น
จากนั้นให้อ่านส่วน [Timer] ที่ systemctl cat แสดงออกมา OnCalendar คือเวลาที่เร็วที่สุดที่ timer อาจเริ่มทำงาน RandomizedDelaySec จะเพิ่มระยะเวลาสุ่มหลังจากจุดนั้น เพื่อป้องกันไม่ให้เครื่อง Debian จำนวนมากเข้าถึง mirror พร้อมกันในวินาทีเดียวกัน นี่คือเหตุผลที่คอลัมน์ NEXT แสดงเวลาที่ไม่ตรงกับ OnCalendar และเป็นสาเหตุว่าทำไมการทำงานของเมื่อวานจึงเกิดขึ้นในนาทีที่ต่างออกไป ระบบกำลังทำงานตามที่ออกแบบไว้ Persistent=true หมายความว่าหากเครื่องถูกปิดในเวลาที่กำหนดไว้ งานจะถูกรันหลังจากเปิดเครื่องใหม่แทนที่จะข้ามวันนั้นไป
หากต้องการเปลี่ยนช่วงเวลา ให้ใช้วิธี override unit แทนการแก้ไขไฟล์โดยตรง:
sudo systemctl edit apt-daily-upgrade.timer[Timer]
OnCalendar=
OnCalendar=03:30
RandomizedDelaySec=30mบรรทัด OnCalendar= ที่ว่างเปล่ามีความจำเป็น เนื่องจากค่าการตั้งค่า unit แบบรายการจะถูกสะสมรวมกัน หากละเว้นบรรทัดนี้ คุณจะยังคงมีตารางเวลาเดิมที่มากับระบบและเพิ่มตารางเวลาใหม่เข้าไปอีกหนึ่งชุด systemctl edit จะโหลด systemd ใหม่ให้คุณ ดังนั้นให้ตรวจสอบผลลัพธ์ด้วย systemctl list-timers 'apt-daily*' และดูค่า NEXT ใหม่
คุณไม่จำเป็นต้องรอให้ timer ทำงานเพื่อทดสอบสิ่งเหล่านี้:
sudo systemctl start apt-daily-upgrade.service
journalctl -u apt-daily-upgrade.service --since -1hสิ่งหนึ่งที่ทำให้ผู้ที่เข้าไปดูใน /etc/cron.daily สับสนคือ APT ยังคงมี /etc/cron.daily/apt-compat สำหรับระบบที่ไม่มี systemd ให้ลองอ่านไฟล์นั้นด้วย cat บนเครื่องที่ใช้ systemd สคริปต์นี้จะจบการทำงานทันที ดังนั้นงานจึงไม่ถูกทำซ้ำสองครั้ง
พิสูจน์ว่าทำงานได้จริง: unattended-upgrade --dry-run --debug
sudo unattended-upgrade --dry-run --debugคำสั่งนี้เป็นรูปเอกพจน์ในขณะที่ชื่อแพ็กเกจเป็นรูปพหูพจน์ Debian 12 และ 13 ได้จัดเตรียมไฟล์ /usr/bin/unattended-upgrades มาให้ด้วย ดังนั้นชื่อพหูพจน์จึงไม่ได้ลงท้ายด้วย command not found ในระบบเหล่านั้นอีกต่อไป อย่างไรก็ตาม คำสั่งที่ระบุไว้ในเอกสารและใช้ตลอดทั้งคู่มือนี้คือคำสั่งเอกพจน์ unattended-upgrade
คำสั่งนี้เพียงคำสั่งเดียวสามารถตอบคำถามเกือบทุกข้อที่ว่า "ทำไมมันถึงข้ามแพ็กเกจนั้นไป" เพราะมันจะแสดงเหตุผลการทำงานของตัวมันเองออกมา โดยที่ส่วนบนของผลลัพธ์ มันจะแสดงแหล่งที่มา (origins) ที่คำนวณได้จากรูปแบบที่คุณกำหนดไว้:
Allowed origins are: ...จากนั้นจะแสดงรายการแพ็กเกจที่เข้าข่ายทีละบรรทัด พร้อมบันทึกแหล่งที่มาของเวอร์ชันที่จะติดตั้ง:
Checking: curl ([<Origin component:'main' archive:'stable' origin:'Debian' label:'Debian' site:'deb.debian.org' isTrusted:True>])ตามด้วยรายการที่จะดำเนินการ หรือหากเครื่องไม่มีงานต้องทำ:
No packages found that can be upgraded unattended and no pending auto-removalsเมื่อนำส่วนแรกและส่วนที่สองมาพิจารณาร่วมกัน การวินิจฉัยปัญหาจะทำได้โดยตรง ให้ค้นหาบรรทัด Checking: สำหรับแพ็กเกจที่คุณคาดว่าจะได้รับการอัปเกรด แล้วเปรียบเทียบบันทึกแหล่งที่มาแบบฟิลด์ต่อฟิลด์กับแหล่งที่มาที่อนุญาตซึ่งแสดงไว้ด้านบน หากมีฟิลด์ใดที่ไม่ตรงกัน ซึ่งส่วนใหญ่มักเป็น label หรือ archive นั่นคือสาเหตุทั้งหมดที่ทำให้แพ็กเกจนั้นถูกข้ามไป
--dry-run จะทำเครื่องหมายแพ็กเกจไว้ในหน่วยความจำและไม่มีการติดตั้งใดๆ เกิดขึ้นจริง ดังนั้นคุณสามารถรันคำสั่งนี้ได้บ่อยเท่าที่ต้องการ โดยมันยังคงบันทึกข้อมูลต่อท้ายใน /var/log/unattended-upgrades/unattended-upgrades.log
หากแหล่งที่มาตรงกันแต่แพ็กเกจยังคงถูกระงับไว้ ให้ตรวจสอบตามรายการต่อไปนี้:
apt-mark showholdแสดงรายการแพ็กเกจที่คุณหรือเครื่องมืออื่นทำการปักหมุด (pin) ไว้ unattended-upgrades จะไม่ดำเนินการกับแพ็กเกจที่ถูกระงับ (held)- การอัปเกรดอาจจำเป็นต้องลบหรือเพิ่มแพ็กเกจอื่น unattended-upgrades จะหลีกเลี่ยงการกระทำดังกล่าวเว้นแต่คีย์ที่เกี่ยวข้องจะอนุญาต ดังนั้นให้เปรียบเทียบกับ
sudo apt-get -s upgradeซึ่งแสดงการตัดสินใจแบบเดียวกันโดยไม่มีกฎความปลอดภัยเหล่านั้น - dpkg อยู่ในสถานะกำหนดค่าไม่สมบูรณ์หลังจากการทำงานถูกขัดจังหวะ ให้แก้ไขด้วย
sudo dpkg --configure -aแล้วตรวจสอบใหม่อีกครั้ง /varไม่มีพื้นที่ว่าง ทำให้ไม่สามารถดาวน์โหลดหรือแตกไฟล์ได้ ให้ตรวจสอบด้วยdf -h /var/bootเต็มไปด้วย kernel เก่า ซึ่งทำให้การอัปเกรด kernel ครั้งถัดไปล้มเหลว ให้ตรวจสอบdf -h /bootและแสดงผลapt-config dump Unattended-Upgrade::Remove-Unused-Kernel-Packagesเพื่อดูว่ามีการเปิดใช้งานการล้างข้อมูลไว้หรือไม่
หากคุณรัน apt ด้วยตนเองในขณะที่ตัวจับเวลา (timer) กำลังทำงาน คุณจะได้รับ Could not get lock /var/lib/dpkg/lock-frontend ข้อความนั้นหมายความว่า unattended-upgrades กำลังทำงานตามหน้าที่ของมันอยู่ ให้รอจนกว่าจะเสร็จสิ้น
คุณจะทราบได้อย่างไรว่าการทำงานล้มเหลว?
ให้เริ่มตรวจสอบจาก log เนื่องจาก log เหล่านี้จะมีอยู่เสมอไม่ว่าคุณจะตั้งค่าอื่นใดไว้หรือไม่ก็ตาม:
sudo tail -n 40 /var/log/unattended-upgrades/unattended-upgrades.log
sudo tail -n 40 /var/log/unattended-upgrades/unattended-upgrades-dpkg.log
journalctl -u apt-daily-upgrade.service --since -7dไฟล์แรกคือ decision log ซึ่งบันทึกสิ่งที่ถูกตรวจสอบ สิ่งที่ถูกเลือก และสิ่งที่ถูกติดตั้ง ไฟล์ที่สองเก็บผลลัพธ์ดิบจาก dpkg ซึ่งเป็นจุดที่แพ็กเกจที่มีสคริปต์ postinst ล้มเหลวจะแสดงข้อผิดพลาดออกมา หากมีการอัปเกรดเกิดขึ้นในขณะที่เครื่องกำลังปิดระบบ จะมีไฟล์ shutdown log แยกออกมาต่างหาก
อีเมลเป็นช่องทางรายงานผลตามปกติ:
Unattended-Upgrade::Mail "you@example.com";
Unattended-Upgrade::MailReport "on-change";MailReport รองรับค่า always, on-change และ only-on-error ค่า only-on-error อาจฟังดูเป็นตัวเลือกที่มีระเบียบวินัย แต่โดยปกติแล้วมักเป็นตัวเลือกที่ผิดสำหรับเซิร์ฟเวอร์ที่ไม่มีใครล็อกอินเข้าไปใช้งาน เพราะเครื่องที่หยุดการอัปเกรดไปโดยสิ้นเชิงจะไม่ส่งข้อผิดพลาดใดๆ ออกมา ความเงียบจึงปกปิดทั้งสถานะของเครื่องที่ทำงานปกติและเครื่องที่ตายไปแล้วได้ดีพอๆ กัน ส่วน on-change จะส่งอีเมลถึงคุณทุกครั้งที่มีการติดตั้งสิ่งใดก็ตาม ดังนั้นอีเมลนี้จึงทำหน้าที่เป็นหลักฐานยืนยันว่าตัวจับเวลา (timer) ยังคงทำงานอยู่
อีเมลจะออกจากเครื่องได้ก็ต่อเมื่อเครื่องนั้นสามารถส่งอีเมลได้เท่านั้น unattended-upgrades จะส่งข้อความไปยังระบบอีเมลภายในเครื่อง ดังนั้นคุณจำเป็นต้องมี MTA (mail transfer agent) เช่น postfix หรือ relay client ที่รองรับ sendmail เช่น msmtp ให้ตรวจสอบด้วย command -v sendmail และ command -v mail หากไม่มีทั้งสองอย่างนี้ รายงานจะไม่ถูกส่งไปที่ใด การอัปเกรดยังคงสำเร็จ แต่ความล้มเหลวทั้งหมดจะไม่มีใครมองเห็น นอกจากนี้ โปรดจำไว้ว่า IP address ของ VPS ที่เพิ่งได้รับมาใหม่จะไม่มีชื่อเสียงในการส่งอีเมล ดังนั้นอีเมลที่ส่งตรงไปยังกล่องจดหมายสาธารณะมักจะถูกจัดว่าเป็นสแปม การส่งผ่านผู้ให้บริการอีเมลที่คุณใช้งานอยู่แล้วจะมีความน่าเชื่อถือมากกว่าการรันเซิร์ฟเวอร์อีเมลของคุณเองเพื่อการนี้
หากคุณไม่ต้องการรันระบบอีเมลเลย ให้เฝ้าสังเกต timestamp ของ log จากระบบ monitoring ที่คุณมีอยู่:
stat -c '%y %n' /var/log/unattended-upgrades/unattended-upgrades.logtimestamp ที่ไม่มีการเปลี่ยนแปลงมาเป็นเวลาหนึ่งสัปดาห์หมายความว่าตัวจับเวลาได้หยุดทำงานลงแล้ว ไม่ว่าการตั้งค่าจะเป็นอย่างไรก็ตาม การตรวจสอบนี้ควรเป็นส่วนหนึ่งของ การตรวจสอบการบำรุงรักษาเซิร์ฟเวอร์ Linux ตามปกติของคุณ
เซิร์ฟเวอร์ควรจะรีบูตตัวเองหรือไม่?
Unattended-Upgrade::Automatic-Reboot "false";
Unattended-Upgrade::Automatic-Reboot-WithUsers "true";
Unattended-Upgrade::Automatic-Reboot-Time "02:00";เมื่อตั้งค่า Automatic-Reboot เป็น true ตัว unattended-upgrades จะทำการรีบูตโดยไม่มีการยืนยัน และจะทำก็ต่อเมื่อไฟล์ /var/run/reboot-required มีอยู่จริงหลังจากกระบวนการทำงานเสร็จสิ้น บน Debian 12 และ 13 แพ็กเกจ unattended-upgrades จะสร้างไฟล์เครื่องหมายนั้นด้วยตัวเองผ่าน kernel hook ที่ชื่อ /etc/kernel/postinst.d/unattended-upgrades ซึ่งจะทำงานเมื่อมีการติดตั้งแพ็กเกจ kernel การอัปเกรดไลบรารีจะไม่เรียกใช้ hook นี้ อย่าทึกทักเอาเองว่าไฟล์นั้นมีอยู่จริง ให้ตรวจสอบหลังจากการอัปเกรด kernel ครั้งถัดไปของคุณ:
ls -l /var/run/reboot-required /var/run/reboot-required.pkgs
uname -r
dpkg -l 'linux-image-*' | grep '^ii'หากไฟล์ดังกล่าวไม่ปรากฏบนเครื่องของคุณ Automatic-Reboot "true" ก็จะไม่ทำงาน และคุณอาจใช้เวลาหลายเดือนโดยเข้าใจผิดว่าเครื่องรีบูตเพื่ออัปเดต kernel แล้ว ทั้งที่ยังคงรัน kernel เวอร์ชันเก่าอยู่ การใช้ uname -r เทียบกับแพ็กเกจ linux-image เวอร์ชันล่าสุดที่ติดตั้งไว้จะเป็นตัวตัดสินเรื่องนี้
Automatic-Reboot-Time จะกำหนดเวลาการรีบูตตามเวลาที่ระบุแทนที่จะทำทันที การตั้งค่า Automatic-Reboot-WithUsers เป็น false จะข้ามการรีบูตหากมีผู้ใช้งานล็อกอินอยู่ ซึ่งบนเซิร์ฟเวอร์ที่มีเซสชันค้างไว้ตลอดเวลาจะหมายความว่าเครื่องจะไม่รีบูตเลย
การตัดสินใจนี้ขึ้นอยู่กับสิ่งที่เกิดขึ้นเมื่อระบบกลับมาทำงาน ไม่ใช่ตัวการรีบูตเอง บริการที่ใครบางคนเริ่มด้วยตนเองอาจไม่กลับมาทำงานต่อ โวลุ่มที่เข้ารหัสซึ่งต้องการรหัสผ่านตอนบูตอาจไม่ถูก mount เครื่องสองเครื่องที่พึ่งพากันอาจกลับมาทำงานในลำดับที่ผิดพลาด ให้เปิดการรีบูตอัตโนมัติสำหรับเว็บเซิร์ฟเวอร์แบบ stateless ที่คุณสามารถยอมให้หยุดทำงานได้หนึ่งนาทีในช่วงเวลา 02:00 น. แต่ให้ปิดไว้ในกรณีที่จำเป็นต้องมีคนดูแล และตั้งค่าการแจ้งเตือนเมื่อพบไฟล์เครื่องหมายแทนเพื่อให้มนุษย์เป็นผู้เลือกช่วงเวลาที่เหมาะสม ในระหว่างนั้นยังมี needrestart ซึ่งจะรีสตาร์ทบริการที่ยังคงทำงานอยู่กับไลบรารีที่ได้รับการอัปเกรดแล้ว จึงครอบคลุมทุกอย่างยกเว้น kernel โหมดเริ่มต้นของมันจะถามก่อนรีสตาร์ท ดังนั้นโปรดอ่าน /etc/needrestart/needrestart.conf ก่อนที่คุณจะพึ่งพามันในการทำงานแบบ unattended
การทำงานนี้เหมือนกันในรุ่น testing และ unstable หรือไม่
เนื้อหาทั้งหมดข้างต้นอธิบายถึง Debian stable ซึ่งการแก้ไขด้านความปลอดภัยจะมาจากคลังเก็บซอฟต์แวร์แยกต่างหากที่มีป้ายกำกับเฉพาะ โครงสร้างดังกล่าวคือสิ่งที่ทำให้การตั้งค่า "อัปเดตเฉพาะความปลอดภัย" สามารถใช้งานได้จริง แต่ชุดซอฟต์แวร์อื่นมีการสร้างที่แตกต่างกัน ดังนั้นการคัดลอกไฟล์ config จากเซิร์ฟเวอร์ stable ไปใช้จึงอาจได้ผลลัพธ์ไม่ตรงตามที่ผู้เขียนคาดหวัง และการอัปเกรดอัตโนมัติบนชุดซอฟต์แวร์ที่มีการเปลี่ยนแปลงตลอดเวลาหมายถึงการเปลี่ยนเวอร์ชันหลักโดยไม่มีการดูแล ซึ่งเป็นสิ่งที่ต้องพิจารณาให้รอบคอบ หากคุณกำลังชั่งน้ำหนักทางเลือกนั้น การใช้งาน Debian stable, testing หรือ unstable บนเซิร์ฟเวอร์ จะครอบคลุมถึงสิ่งที่แต่ละรุ่นรับประกันไว้ สำหรับฝั่ง Red Hat งานเดียวกันนี้จะมีเครื่องมือและคำศัพท์ที่แตกต่างออกไป และ dnf-automatic บน Rocky Linux และ AlmaLinux จะจัดการเรื่องนี้ด้วย timer และไฟล์ config ของตนเอง
การอัปเกรดอัตโนมัติช่วยลดระยะเวลาระหว่างการเผยแพร่การแก้ไขกับการติดตั้งการแก้ไขนั้น แต่ไม่ได้บอกคุณว่ายังมีส่วนใดที่เสี่ยงอยู่บ้าง ดังนั้นควรใช้งานควบคู่ไปกับ การตรวจสอบ CVE ที่ทราบผลบนเซิร์ฟเวอร์ของคุณ โดย CVE ย่อมาจาก common vulnerabilities and exposures ซึ่งเป็นตัวระบุสาธารณะที่ใช้ติดตามการแก้ไขปัญหาต่างๆ
การตรวจสอบใน 5 นาที
apt-config dump APT::Periodicแสดงผลคีย์ทั้งสองที่มีค่าไม่เป็นศูนย์systemctl list-timers 'apt-daily*'แสดงผลเวลาNEXTสำหรับตัวจับเวลาทั้งสองsudo unattended-upgrade --dry-run --debugแสดงผลแหล่งที่มาที่อนุญาตซึ่งรวมถึงคลังเก็บข้อมูลความปลอดภัยสำหรับ codename ของคุณsudo systemctl start apt-daily-upgrade.serviceทำงานเสร็จสิ้น และการประทับเวลาบน/var/log/unattended-upgrades/unattended-upgrades.logมีการเปลี่ยนแปลง- หนึ่งสัปดาห์ถัดมา log เดียวกันนั้นจะระบุชื่อแพ็กเกจที่ถูกติดตั้ง
การผ่านการตรวจสอบ 4 ข้อแรกหมายความว่าเครื่องได้รับการกำหนดค่าเรียบร้อยแล้ว การผ่านข้อที่ 5 หมายความว่าระบบทำงานได้จริง
FAQ
ทำไม Debian ถึงติดตั้ง unattended-upgrades มาให้แต่ปิดการทำงานไว้?
แพ็กเกจนี้จะถามคำถามผ่าน debconf คือ unattended-upgrades/enable_auto_updates และบันทึกค่า /etc/apt/apt.conf.d/20auto-upgrades ตามคำตอบที่ได้รับ โดยค่าเริ่มต้นของแพ็กเกจสำหรับคำถามนี้คือ true อย่างไรก็ตาม คำถามเรื่องการอัปเดตของตัวติดตั้ง Debian จะตั้งค่าเริ่มต้นไว้ที่ไม่มีการอัปเดตอัตโนมัติ ซึ่งตัวเลือกนั้นจะบันทึกค่า false ไว้สำหรับคำถามของแพ็กเกจ ดังนั้นเมื่อแพ็กเกจถูกติดตั้งในภายหลังในฐานะส่วนหนึ่งของงานหรือเป็น dependency มันจึงถูกกำหนดค่าไว้ไม่ให้ทำงานใดๆ ให้รัน sudo debconf-show unattended-upgrades เพื่อดูคำตอบที่บันทึกไว้ จากนั้นรัน sudo dpkg-reconfigure --priority=low unattended-upgrades เพื่อเปลี่ยนค่า คำถามนี้มีความสำคัญต่ำ การติดตั้งทั่วไปจึงไม่แสดงคำถามนี้ขึ้นมา แต่ dpkg-reconfigure จะแสดงคำถามที่มีความสำคัญต่ำโดยค่าเริ่มต้น ดังนั้นมันจึงปรากฏขึ้นที่นี่แม้ไม่ได้ใส่ flag ดังกล่าว
ฉันจะทดสอบ unattended-upgrades โดยไม่ต้องรอให้ถึงเวลาตาม timer ได้อย่างไร?
ให้รัน sudo unattended-upgrade --dry-run --debug คำสั่งนี้จะแสดงแหล่งที่มาที่ยอมรับ แต่ละบรรทัดของ Checking: จะแสดงแพ็กเกจที่อัปเกรดได้พร้อมบันทึกแหล่งที่มาของแพ็กเกจนั้น และแสดงรายการที่จะติดตั้งโดยที่ยังไม่มีการติดตั้งจริง หากต้องการทดสอบกระบวนการทำงานจริง ให้รัน sudo systemctl start apt-daily-upgrade.service จากนั้นตรวจสอบผลลัพธ์จาก journalctl -u apt-daily-upgrade.service --since -1h ควบคู่ไปกับไฟล์ /var/log/unattended-upgrades/unattended-upgrades.log
unattended-upgrades ติดตั้งอัปเดตทั่วไปนอกเหนือจากแพตช์ความปลอดภัยด้วยหรือไม่?
จะทำก็ต่อเมื่อมีรูปแบบที่กำหนดไว้เท่านั้น การอัปเกรดแพ็กเกจจะเกิดขึ้นเมื่อแหล่งที่มาของแพ็กเกจนั้นตรงกับรายการใน Unattended-Upgrade::Origins-Pattern หรือการตั้งค่าคอนฟิกูเรชันที่เก่ากว่าอย่าง Unattended-Upgrade::Allowed-Origins โดยที่คลังเก็บแพ็กเกจความปลอดภัย (security archive), ชุดแพ็กเกจ stable-updates และ repository ใดๆ ที่คุณเพิ่มเองจะเป็นรายการแยกต่างหาก ให้พิมพ์ apt-config dump Unattended-Upgrade::Origins-Pattern และ apt-config dump Unattended-Upgrade::Allowed-Origins บนเครื่องของคุณ แล้วเปรียบเทียบกับ grep -H -E '^(Origin|Label|Suite|Codename):' /var/lib/apt/lists/*Release นอกจากนี้ ระบบจะไม่ทำการย้ายเวอร์ชัน Debian ให้คุณโดยอัตโนมัติ
ทำไมการอัปเกรดถึงไม่ทำงานตามเวลาที่ตั้งไว้ใน timer?
apt-daily-upgrade.timer จะกำหนดค่า RandomizedDelaySec ทับบน OnCalendar ดังนั้น systemd จะสุ่มช่วงเวลาภายในกรอบเวลานั้นแทนที่จะทำงานตามเวลาที่ระบุไว้ในปฏิทินเป๊ะๆ เพื่อกระจายภาระงานไปยังเครื่อง Debian ทุกเครื่องที่เรียกใช้ mirror เดียวกัน systemctl list-timers 'apt-daily*' จะแสดงเวลาที่ระบบเลือกไว้จริง หากต้องการเปลี่ยนช่วงเวลา ให้รัน sudo systemctl edit apt-daily-upgrade.timer แล้วเว้นบรรทัด OnCalendar= ให้ว่างไว้ ตามด้วยค่าที่คุณต้องการ
ฉันควรเปิดใช้งานการรีบูตอัตโนมัติสำหรับการอัปเดตความปลอดภัยหรือไม่?
ควรทำเฉพาะในกรณีที่การรีสตาร์ทโดยไม่ได้วางแผนไว้ไม่มีผลกระทบต่อระบบเท่านั้น Unattended-Upgrade::Automatic-Reboot "true" จะรีบูตเครื่องโดยไม่มีการยืนยันเมื่อใดก็ตามที่ /var/run/reboot-required ปรากฏขึ้นหลังจากการทำงานเสร็จสิ้น บน Debian 12 และ 13 ตัวบ่งชี้นี้มาจาก kernel hook ที่มาพร้อมกับแพ็กเกจ unattended-upgrades ดังนั้นมันจะปรากฏขึ้นหลังจากการอัปเกรด kernel เท่านั้น ไม่ใช่หลังจากการอัปเกรด library ให้ตรวจสอบว่าไฟล์ดังกล่าวปรากฏบนเครื่องของคุณหลังจากการอัปเกรด kernel ก่อนที่จะเชื่อถือการตั้งค่านี้ สำหรับเครื่องที่ต้องใช้รหัสผ่านตอนบูต หรือเครื่องที่รันบริการที่มีคนเริ่มด้วยตนเอง ให้ตั้งค่าเป็น false และตั้งการแจ้งเตือนเมื่อพบไฟล์ตัวบ่งชี้นี้ เพื่อให้มีคนเป็นผู้กำหนดเวลาในการรีบูตเอง