SSD Nodes Learn Hosting plans →
คู่มือ Matt Connorโดย Matt Connor · อัปเดตเมื่อ 2026-09-14

วิธีแก้ปัญหา unattended-upgrades ไม่ทำงานบน Debian

Debian ปิดการทำงาน unattended-upgrades ไว้เป็นค่าเริ่มต้น เรียนรู้วิธีเปิดใช้งานที่ถูกต้อง การตั้งค่า Origins-Pattern การตรวจสอบ apt-daily และวิธีทดสอบว่าระบบอัปเดตเองจริง

เหตุใด unattended-upgrades จึงไม่ทำงานบน Debian ที่ติดตั้งใหม่

บน Debian นั้น unattended-upgrades อาจถูกติดตั้งไว้แต่ไม่เคยทำการอัปเกรดเลยแม้แต่ครั้งเดียว เนื่องจากขั้นตอนการติดตั้งแพ็กเกจและขั้นตอนการเปิดใช้งานเป็นคนละส่วนกัน แพ็กเกจจะถามคำถามผ่าน debconf ก่อนที่จะกำหนดค่าตัวเอง และตัวติดตั้งของ Debian จะเก็บคำตอบ false สำหรับคำถามนั้นไว้ ในขณะที่ Ubuntu ตอบคำถามเดียวกันในทิศทางตรงกันข้าม ซึ่งเป็นเหตุผลว่าทำไมแพ็กเกจเดียวกันจึงดูเหมือนทำงานได้ปกติบน Ubuntu แต่ดูเหมือนเสียบน Debian

ไม่มีสิ่งใดในระบบที่แจ้งเตือนเรื่องนี้ ไม่มีการแสดงข้อผิดพลาดขณะบูต ไม่มีการแจ้งเตือนเมื่อล็อกอิน และไม่มีไฟล์ log ให้ตรวจสอบ เนื่องจากโค้ดที่จะเขียน log ดังกล่าวไม่เคยถูกเรียกใช้งาน การเปิดใช้งานทำได้ด้วยคำสั่งเดียว ส่วนที่เหลือของคู่มือนี้จะครอบคลุมปัจจัยอีก 4 ประการที่อาจทำให้ระบบยังคงไม่ทำงานหลังจากเปิดใช้งานแล้ว ได้แก่ repository ใดบ้างที่อนุญาตให้อัปเกรด, เวลาที่ 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::Periodic

debconf-show จะแสดงคำตอบที่ถูกจัดเก็บไว้สำหรับ unattended-upgrades/enable_auto_updates หากมี * ปรากฏที่ต้นบรรทัดนั้น หมายความว่ามีการกำหนดค่าดังกล่าวไว้แทนที่จะใช้ค่าเริ่มต้นของแพ็กเกจ สำหรับเครื่องที่ติดตั้งผ่านตัวติดตั้ง Debian สิ่งที่กำหนดค่านั้นคือตัวติดตั้งเอง

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 การอ่านไฟล์เดียวจะบอกคุณว่าไฟล์นั้นระบุไว้อย่างไร แต่ 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

--priority=low เป็นสิ่งที่จำเป็นในกรณีนี้ คำถามนี้ถูกตั้งค่าไว้ที่ลำดับความสำคัญต่ำ ดังนั้นที่ลำดับความสำคัญเริ่มต้น dpkg-reconfigure จะไม่แสดงผลลัพธ์ใดๆ ไม่เปลี่ยนแปลงค่าใดๆ และจบการทำงานด้วยสถานะ 0 ซึ่งดูเหมือนคำสั่งที่ทำงานสำเร็จทุกประการ ให้ตอบตกลงในหน้าต่างโต้ตอบ จากนั้น 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 ในครั้งถัดไป หรือการติดตั้งแพ็กเกจใหม่ จะทำให้ไฟล์ถูกเขียนทับด้วยค่าจาก debconf และยกเลิกการแก้ไขของคุณโดยไม่มีการแจ้งเตือนใดๆ ให้ตั้งค่าทั้งสองที่ หรือตั้งค่าผ่าน debconf แล้วปล่อยให้ postinst จัดการไฟล์นั้น

นี่คือความแตกต่างที่แท้จริงเพียงอย่างเดียวเมื่อเทียบกับฝั่งอื่นในตระกูลเดียวกัน ในฝั่งนั้นตัวติดตั้งจะเปิดใช้งานแพ็กเกจเดียวกันให้คุณ ดังนั้น การตั้งค่า unattended-upgrades บน Ubuntu จึงเริ่มต้นจากระบบที่แพตช์ตัวเองอยู่แล้วและใช้เวลาไปกับการปรับแต่ง ทุกหัวข้อหลังจากจุดนี้สามารถใช้ได้กับทั้งสองฝั่ง

Debian ติดตั้งอัปเดตอะไรให้คุณบ้าง

การเปิดใช้งาน timer ไม่ได้หมายความว่าคุณตกลงที่จะติดตั้งทุกอย่าง แหล่งที่มาของแพ็กเกจแต่ละแห่งจะมี metadata ของรุ่นระบุไว้ ได้แก่ origin, label, suite, codename และ site โดย unattended-upgrades จะตรวจสอบเวอร์ชันที่สามารถอัปเกรดได้ของแต่ละแพ็กเกจ อ่าน metadata ของแหล่งที่มานั้น และจะติดตั้งก็ต่อเมื่อแหล่งที่มาดังกล่าวตรงกับรายการใน Unattended-Upgrade::Origins-Pattern เท่านั้น หากไม่ตรงกัน ระบบจะไม่ทำการอัปเกรดโดยไม่มีการแจ้งเตือนใดๆ ตามที่ออกแบบไว้

แสดงรูปแบบ (pattern) ของคุณ จากนั้นแสดง metadata ที่ใช้จับคู่กับรูปแบบเหล่านั้น:

apt-config dump Unattended-Upgrade::Origins-Pattern
grep -H -E '^(Origin|Label|Suite|Codename|Components):' /var/lib/apt/lists/*Release
apt-cache policy

grep -H จะคงชื่อไฟล์ไว้ในแต่ละบรรทัด เพื่อให้คุณเห็นว่า metadata แต่ละชุดมาจากแหล่งที่มาใด ค่าฟิลด์เหล่านั้นคือค่าทางด้านขวาของรูปแบบที่คุณกำหนดไว้ ส่วน ${distro_codename} ภายในรูปแบบจะถูกแทนที่ด้วย codename ของรุ่นที่คุณใช้งานอยู่ในขณะที่โปรแกรมทำงาน ทำให้ไฟล์เดียวสามารถใช้งานได้ต่อเนื่องแม้จะมีการอัปเกรดรุ่นของระบบปฏิบัติการ

อ่านรูปแบบของคุณโดยเทียบกับ metadata เหล่านั้น เพราะคำตอบของคำถามที่ว่า "ฉันได้รับเฉพาะการแก้ไขด้านความปลอดภัย หรือได้รับอัปเดตย่อย (point release) ด้วย" ถูกเขียนไว้ที่นั่นและไม่มีที่อื่นอีก:

  • รูปแบบที่ระบุ label=Debian-Security จะจับคู่กับคลังเก็บข้อมูลด้านความปลอดภัย ซึ่งเป็นที่ที่ Debian ส่งประกาศด้านความปลอดภัยเข้ามา
  • รูปแบบที่ระบุ suite -updates จะจับคู่กับ stable-updates ซึ่งบรรจุสิ่งที่ Debian ปล่อยออกมาในช่วงระหว่างการออก point release เช่น ข้อมูลเขตเวลา (time zone)
  • รูปแบบที่ระบุ suite รุ่นปกติจะดึงการเปลี่ยนแปลงของ point release ทันทีที่มีการเผยแพร่ ซึ่งจะมีการเปลี่ยนแปลงบ่อยกว่าและต้องใช้แรงในการทดสอบฝั่งคุณมากขึ้น
  • คลังเก็บข้อมูลที่คุณเพิ่มเข้ามาเองจะไม่ถูกจับคู่กับสิ่งใดเลยจนกว่าคุณจะเขียนรูปแบบสำหรับมัน

ประเด็นสุดท้ายนี้มักทำให้ผู้ใช้ประหลาดใจ คลังเก็บข้อมูลของบุคคลที่สามมี origin และ label เป็นของตัวเอง ดังนั้น unattended-upgrades จะเห็นแพ็กเกจที่รอการอัปเกรด เห็นว่าแหล่งที่มาไม่ตรงกับรูปแบบใดเลย แล้วจึงข้ามไป การเพิ่มรูปแบบสำหรับคลังเก็บข้อมูลเหล่านี้เป็นการตัดสินใจที่ควรพิจารณาอย่างรอบคอบ เพราะผู้ให้บริการอาจปล่อยซอฟต์แวร์เวอร์ชันหลัก (major version) ใหม่เข้ามาใน suite เดิม ซึ่งหมายความว่าคุณได้ตกลงที่จะให้อัปเกรดเวอร์ชันหลักของซอฟต์แวร์นั้นโดยอัตโนมัติในยามวิกาล

นอกจากนี้ unattended-upgrades จะไม่ย้ายคุณข้ามรุ่นของ Debian โดยเด็ดขาด มันจะอัปเกรดเฉพาะแพ็กเกจภายในรุ่นที่คุณใช้งานอยู่เท่านั้น การย้ายจากรุ่น stable หนึ่งไปยังอีกรุ่นหนึ่งยังคงเป็นงานที่คุณต้องดำเนินการด้วยตนเองตามเวลาที่คุณกำหนด

เมื่อคุณแก้ไขรายการ โปรดจำไว้ว่ารายการของ APT จะเป็นการเพิ่มต่อท้ายเสมอ บล็อก 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 เป็น conffile การแก้ไขไฟล์นี้จะทำให้การอัปเกรดแพ็กเกจในอนาคตหยุดชะงักและถามคุณว่าจะจัดการกับเวอร์ชันของคุณอย่างไร การแยกไฟล์ใหม่จะไม่ทำให้เกิดความขัดแย้งดังกล่าว

มีอีกสองค่าที่ควรตรวจสอบในขณะที่คุณอยู่ที่นี่ Unattended-Upgrade::Allowed-Origins เป็นรูปแบบเก่าของแนวคิดเดียวกัน โดยเขียนเป็นคู่ origin:archive และระบบยังคงอ่านค่านี้อยู่ ดังนั้นการตั้งค่าที่คัดลอกมาจากบทความสอนใช้งานมักจะมีรายการทั้งสองแบบปนกัน ทำให้ไม่ชัดเจนว่ารายการใดเป็นตัวจับคู่ ส่วน Unattended-Upgrade::Package-Blacklist จะเก็บนิพจน์ทั่วไป (regular 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.timer

list-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

ไฟล์ binary เป็นเอกพจน์ แต่ชื่อแพ็กเกจเป็นพหูพจน์ การพิมพ์ unattended-upgrades ลงไปจะแสดงผลเป็น command not found ซึ่งหลายคนมักเข้าใจผิดว่าเป็นหลักฐานว่าแพ็กเกจนั้นหายไป

คำสั่งนี้คำสั่งเดียวตอบคำถามเกือบทุกข้อที่ว่า "ทำไมถึงข้ามแพ็กเกจนั้นไป" เพราะมันจะแสดงเหตุผลการทำงานของตัวมันเองออกมา โดยที่ส่วนบนของผลลัพธ์จะแสดงแหล่งที่มา (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 จะไม่ดำเนินการกับแพ็กเกจที่ถูกระงับไว้
  • การอัปเกรดอาจจำเป็นต้องลบหรือเพิ่มแพ็กเกจอื่น 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.log

timestamp ที่ไม่มีการเปลี่ยนแปลงมาเป็นเวลาหนึ่งสัปดาห์หมายความว่าตัวจับเวลาได้หยุดทำงานลงแล้ว ไม่ว่าการตั้งค่าจะเป็นอย่างไรก็ตาม การตรวจสอบนี้ควรเป็นส่วนหนึ่งของ การตรวจสอบการบำรุงรักษาเซิร์ฟเวอร์ Linux ตามปกติของคุณ

เซิร์ฟเวอร์ควรทำการรีบูตตัวเองหรือไม่?

Unattended-Upgrade::Automatic-Reboot "false";
Unattended-Upgrade::Automatic-Reboot-WithUsers "true";
Unattended-Upgrade::Automatic-Reboot-Time "02:00";

เมื่อตั้งค่า Automatic-Reboot เป็น true ตัว /var/run/reboot-required จะทำการรีบูตโดยไม่มีการยืนยัน และจะทำก็ต่อเมื่อไฟล์ /var/run/reboot-required มีอยู่จริงหลังจากกระบวนการทำงานเสร็จสิ้น ตัวไฟล์เครื่องหมายดังกล่าวไม่ได้ถูกสร้างโดย /var/run/reboot-required เอง แต่ต้องมีแพ็กเกจอื่นเป็นผู้สร้าง ซึ่งบน Debian โดยปกติจะเป็น needrestart อย่าทึกทักเอาเองว่าไฟล์นี้มีอยู่จริง ให้ตรวจสอบหลังจากมีการอัปเกรดเคอร์เนลครั้งถัดไป:

ls -l /var/run/reboot-required /var/run/reboot-required.pkgs
uname -r
dpkg -l 'linux-image-*' | grep '^ii'

หากไฟล์ดังกล่าวไม่เคยปรากฏบนเครื่องของคุณ Automatic-Reboot "true" ก็จะไม่ทำงาน และคุณอาจใช้เวลาหลายเดือนโดยเข้าใจผิดว่าเครื่องได้รีบูตเพื่ออัปเดตเคอร์เนลแล้ว ทั้งที่ยังคงรันเคอร์เนลเวอร์ชันเก่าอยู่ การใช้ uname -r เทียบกับแพ็กเกจ linux-image เวอร์ชันล่าสุดที่ติดตั้งไว้จะเป็นตัวตัดสินเรื่องนี้

Automatic-Reboot-Time จะกำหนดเวลาการรีบูตตามเวลาที่ระบุแทนที่จะทำทันที ส่วนการตั้งค่า Automatic-Reboot-WithUsers เป็น false จะข้ามการรีบูตหากมีผู้ใช้งานล็อกอินอยู่ ซึ่งบนเซิร์ฟเวอร์ที่มีเซสชันเปิดค้างไว้ตลอดเวลาจะส่งผลให้เครื่องไม่รีบูตเลย

การตัดสินใจนี้ขึ้นอยู่กับสิ่งที่เกิดขึ้นระหว่างการบูตระบบกลับขึ้นมา ไม่ใช่ตัวการรีบูตเอง บริการที่ใครบางคนเริ่มด้วยตนเองจะไม่กลับมาทำงานต่อ วอลลุ่มที่เข้ารหัสซึ่งต้องการรหัสผ่านตอนบูตจะไม่ถูกเมาท์ เครื่องสองเครื่องที่พึ่งพากันอาจกลับมาทำงานในลำดับที่ผิดพลาดได้ ให้เปิดการรีบูตอัตโนมัติสำหรับเว็บเซิร์ฟเวอร์แบบ stateless ที่คุณสามารถยอมให้หยุดทำงานได้หนึ่งนาทีในช่วงเวลา 02:00 น. แต่ให้ปิดไว้ในกรณีที่จำเป็นต้องมีคนดูแล และใช้การแจ้งเตือนเมื่อพบไฟล์เครื่องหมายแทนเพื่อให้มนุษย์เป็นผู้กำหนดช่วงเวลาที่เหมาะสม ส่วนทางเลือกกึ่งกลางคือ needrestart ซึ่งจะรีสตาร์ทเฉพาะบริการที่ยังคงเรียกใช้ไลบรารีเวอร์ชันเก่า จึงครอบคลุมทุกอย่างยกเว้นเคอร์เนล โดยโหมดเริ่มต้นของมันจะถามก่อนทำการรีสตาร์ท ดังนั้นโปรดอ่าน /etc/needrestart/needrestart.conf ก่อนที่คุณจะใช้งานในโหมดอัตโนมัติโดยไม่มีผู้ดูแล

การทำงานนี้เหมือนกันในรุ่น 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 นาที

  1. apt-config dump APT::Periodic แสดงผลคีย์ทั้งสองที่มีค่าไม่เป็นศูนย์
  2. systemctl list-timers 'apt-daily*' แสดงผลเวลา NEXT สำหรับตัวจับเวลาทั้งสอง
  3. sudo unattended-upgrade --dry-run --debug แสดงผลแหล่งที่มาที่อนุญาตซึ่งรวมถึงคลังเก็บข้อมูลความปลอดภัยสำหรับ codename ของคุณ
  4. sudo systemctl start apt-daily-upgrade.service ทำงานเสร็จสิ้น และการประทับเวลาบน /var/log/unattended-upgrades/unattended-upgrades.log มีการเปลี่ยนแปลง
  5. หนึ่งสัปดาห์ถัดมา log เดียวกันนั้นจะระบุชื่อแพ็กเกจที่ถูกติดตั้ง

การผ่านการตรวจสอบ 4 ข้อแรกหมายความว่าเครื่องได้รับการกำหนดค่าเรียบร้อยแล้ว การผ่านข้อที่ 5 หมายความว่าระบบทำงานได้จริง

FAQ

ทำไม Debian ถึงติดตั้ง unattended-upgrades มาให้แต่ปิดการทำงานไว้?

แพ็กเกจนี้จะถามคำถามผ่าน debconf คือ unattended-upgrades/enable_auto_updates และเขียนค่า /etc/apt/apt.conf.d/20auto-upgrades ตามคำตอบที่ได้รับ ตัวติดตั้งของ Debian จะจัดเก็บค่า false สำหรับคำถามนั้นไว้ ดังนั้นเมื่อแพ็กเกจถูกติดตั้งในฐานะส่วนหนึ่งของ task หรือ dependency มันจึงถูกตั้งค่าให้ไม่ทำงาน ให้รันคำสั่ง sudo debconf-show unattended-upgrades เพื่อดูคำตอบที่ถูกจัดเก็บไว้ จากนั้นใช้ sudo dpkg-reconfigure --priority=low unattended-upgrades เพื่อเปลี่ยนค่า การกำหนดระดับความสำคัญให้ต่ำ (low priority) เป็นเรื่องสำคัญ เพราะหากใช้ระดับความสำคัญปกติ คำสั่งจะจบการทำงานโดยไม่แสดงคำถามให้คุณเห็น

ฉันจะทดสอบ unattended-upgrades โดยไม่ต้องรอให้ถึงเวลาตาม timer ได้อย่างไร?

ให้รันคำสั่ง sudo unattended-upgrade --dry-run --debug ระบบจะแสดงแหล่งที่มา (origins) ที่ยอมรับ โดยแสดงบรรทัด 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 ติดตั้งอัปเดตทั่วไปนอกเหนือจากแพตช์ความปลอดภัยด้วยหรือไม่?

จะติดตั้งก็ต่อเมื่อมีรูปแบบ (pattern) ระบุไว้เท่านั้น การอัปเกรดแพ็กเกจจะเกิดขึ้นเมื่อแหล่งที่มาของแพ็กเกจนั้นตรงกับรายการใน Unattended-Upgrade::Origins-Pattern ซึ่งคลังเก็บแพ็กเกจความปลอดภัย (security archive), ชุดแพ็กเกจ stable-updates และ repository อื่นๆ ที่คุณเพิ่มเองนั้นถือเป็นรายการแยกต่างหาก ให้รันคำสั่ง apt-config dump Unattended-Upgrade::Origins-Pattern บนเครื่องของคุณ แล้วเปรียบเทียบกับ grep -H -E '^(Origin|Label|Suite|Codename):' /var/lib/apt/lists/*Release นอกจากนี้ ระบบจะไม่ทำการย้ายเวอร์ชัน Debian (release) ให้คุณโดยอัตโนมัติ

ทำไมการอัปเกรดถึงไม่ทำงานตามเวลาที่ตั้งไว้ใน 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 ปรากฏขึ้นหลังจากการทำงาน ซึ่งไฟล์เครื่องหมายนี้จะถูกสร้างโดยแพ็กเกจอื่น (โดยปกติคือ needrestart) ไม่ใช่โดย unattended-upgrades โดยตรง คุณควรตรวจสอบให้แน่ใจว่าไฟล์ดังกล่าวปรากฏขึ้นบนเครื่องของคุณหลังจากการอัปเกรด kernel ก่อนที่จะเชื่อถือการตั้งค่านี้ สำหรับเครื่องที่ต้องใช้รหัสผ่านตอนบูต หรือเครื่องที่รันบริการซึ่งมีคนเริ่มทำงานด้วยตนเอง ควรตั้งค่าเป็น false และตั้งการแจ้งเตือนเมื่อพบไฟล์เครื่องหมายแทน เพื่อให้ผู้ดูแลระบบเป็นผู้เลือกว่าจะรีบูตเมื่อใด