Cấu hình dnf-automatic cập nhật bảo mật Rocky, AlmaLinux
Hướng dẫn cài đặt dnf-automatic trên Rocky Linux và AlmaLinux 9. Cách cấu hình chế độ security-only, systemd timer, email cảnh báo và chính sách reboot an toàn cho server.
dnf-automatic làm gì trên Rocky Linux và AlmaLinux
dnf-automatic là cách bạn thực hiện cập nhật bảo mật tự động trên Rocky Linux và AlmaLinux. Đây là một chương trình nhỏ, được khởi chạy bởi một systemd timer, đọc file /etc/dnf/automatic.conf và áp dụng những gì file đó cho phép. Việc cài đặt chỉ cần một lệnh. Phần còn lại của hướng dẫn này nói về các thiết lập quyết định xem nó bảo vệ máy chủ hay lặng lẽ không làm gì cả.
Nếu bạn chuyển từ Debian hoặc Ubuntu sang, đây là công việc tương tự như unattended-upgrades trên một VPS Ubuntu. Có một điểm khác biệt quan trọng hơn tất cả các điểm khác: ý nghĩa của từ "security" đối với trình quản lý gói. Trên Ubuntu, đó là một kho lưu trữ riêng biệt. Trên dòng RHEL, đó là metadata đính kèm với các thông báo bảo mật (advisory) đã công bố, và metadata đó có thể bị thiếu hoặc lỗi thời. Nếu bạn trỏ dnf-automatic vào một repository không có dữ liệu advisory, nó sẽ không cài đặt gì cả trong khi vẫn báo cáo là thành công.
Hướng dẫn này được viết dựa trên Rocky Linux 9 và AlmaLinux 9, sử dụng DNF 4 (DNF là trình quản lý gói trên dòng RHEL), tính đến tháng 8 năm 2026. Các bản phát hành 10 đã chuyển sang DNF5 và tên gọi ở đó đã thay đổi, vì vậy chúng có một phần riêng ở gần cuối. Mọi lệnh dưới đây là lệnh bạn cần chạy trên máy chủ của mình, với kết quả đầu ra bạn sẽ thấy ngay bên cạnh.
Cài đặt dnf-automatic và đọc file cấu hình đi kèm
Việc bật cập nhật tự động nên được thực hiện cùng với các bước thiết lập khác trong bài mười phút đầu tiên trên VPS mới, ngay sau khi bạn đã có một user không phải root và một firewall.
sudo dnf install -y dnf-automatic
rpm -q dnf dnf-automatic
systemctl is-enabled dnf-automatic.timersystemctl is-enabled sẽ in ra disabled trên một bản cài đặt mới, vì việc cài đặt gói này không khởi chạy bất kỳ tiến trình nào. Đây là lý do phổ biến nhất khiến một máy chủ "đã có dnf-automatic" nhưng chưa bao giờ áp dụng một bản cập nhật nào.
Phiên bản DNF rất quan trọng đối với một tùy chọn. Thiết lập reboot xuất hiện trong DNF 4.15, và Red Hat đã backport nó vào dnf-4.14.0-6.el9 vào tháng 11 năm 2023 thông qua thông báo RHBA-2023:6645. Rocky 9 và AlmaLinux 9 build lại gói đó, vì vậy một máy chủ cập nhật sẽ có nó, còn máy chủ không được đụng đến từ năm 2023 thì không.
File cấu hình là /etc/dnf/automatic.conf. Bản sao đi kèm liệt kê mọi tùy chọn mà bản build này hiểu được, cùng với giá trị mặc định của chúng dưới dạng comment. Hãy đọc nó một lần trước khi chỉnh sửa, vì file đó là nguồn thông tin chính xác nhất về phiên bản bạn đang dùng.
Hai tùy chọn quyết định hành vi
download_updates và apply_updates trong mục [commands] quyết định hành vi của hệ thống. Cả hai đều được đặt là no theo mặc định trên EL9 (enterprise Linux 9, nền tảng chung của Rocky 9 và AlmaLinux 9), vì vậy nếu bạn chỉ enable dnf-automatic mà không chỉnh sửa, nó sẽ chỉ thông báo cho bạn những gì khả dụng.
- Cả hai đều là
no: dnf-automatic báo cáo các bản cập nhật khả dụng và không thay đổi bất cứ điều gì trên máy chủ. download_updates = yesvớiapply_updates = no: các gói được tải về DNF cache. Việc cài đặt sau đó sẽ nhanh chóng và không cần mạng, nhưng không có thay đổi nào được thực hiện ngay lúc đó.- Cả hai đều là
yesvớiupgrade_type = default: mọi bản cập nhật khả dụng đều được cài đặt, bất kể đó có phải là bản cập nhật bảo mật hay không. - Cả hai đều là
yesvớiupgrade_type = security: chỉ các gói được nêu trong thông báo bảo mật mới được cài đặt.
Một cấu hình khởi đầu hợp lý cho VPS công khai:
[commands]
upgrade_type = security
download_updates = yes
apply_updates = yes
random_sleep = 0
network_online_timeout = 60
reboot = nevernetwork_online_timeout là số giây tiến trình chờ mạng hoạt động trước khi bỏ cuộc, điều này quan trọng trên máy chủ vừa mới khởi động. random_sleep là cách cũ để phân bổ tải trên nhiều máy, và hiện nay timer đã đảm nhận công việc đó. Chạy systemctl cat dnf-automatic.service để xem chính xác các flag mà service mặc định đang sử dụng.
Kiểm tra xem file cấu hình hoạt động đúng như bạn nghĩ mà không cần đợi đến 06:00:
sudo systemctl start dnf-automatic.service
sudo journalctl -u dnf-automatic.service -n 50 --no-pagerJournal hiển thị những gì tiến trình đã xem xét và đã thực hiện. Bạn cũng có thể ép buộc một hành vi từ dòng lệnh, hành vi này sẽ ghi đè lên file cấu hình chỉ cho lần chạy đó:
sudo dnf-automatic --downloadupdates --no-installupdatesÝ nghĩa thực sự của upgrade_type = security trên Rocky và Alma
DNF không xác định một bản cập nhật có phải là bản vá bảo mật hay không bằng cách so sánh số phiên bản. Nó đọc metadata errata: một tệp tin gọi là updateinfo.xml được công bố bên trong repository, nơi mỗi thông báo (advisory) liệt kê các gói cần sửa lỗi. AlmaLinux công bố các thông báo này dưới dạng ALSA, còn Rocky công bố dưới dạng RLSA. upgrade_type = security xây dựng một bộ lọc từ metadata đó và chỉ nâng cấp các gói khớp với thông báo.
Có hai hệ quả xảy ra và cả hai đều gây bất ngờ cho người dùng.
Thứ nhất, không có metadata đồng nghĩa với không có cập nhật. Nếu repository không chứa updateinfo.xml, bộ lọc sẽ không khớp với bất kỳ gói nào và tiến trình kết thúc với dòng này trong journal:
No security updates needed, but 3 updates availableMáy chủ không được vá lỗi và không có thông báo lỗi nào được ghi nhận. Hãy tự kiểm tra bằng cách:
dnf updateinfo list --security
dnf check-updateNếu dnf check-update liệt kê các gói trong khi dnf updateinfo list --security không hiển thị gì cả, thì hoặc là không có bản cập nhật nào đi kèm thông báo bảo mật, hoặc repository không có dữ liệu thông báo để đọc. Cả Rocky và AlmaLinux đều công bố dữ liệu này, nên trên hai hệ điều hành đó, danh sách trống thường là kết quả chính xác. CentOS Stream hoàn toàn không công bố dữ liệu này.
Thứ hai, chế độ bảo mật không phải là thay đổi tối thiểu. dnf-automatic thêm bộ lọc bảo mật rồi chạy quy trình nâng cấp thông thường, vì vậy một gói có tên trong thông báo sẽ được nâng cấp lên phiên bản mới nhất trong repository và kéo theo các dependency của nó. Bước nhỏ hơn, chỉ nâng cấp lên phiên bản sớm nhất có chứa bản vá, là dnf upgrade-minimal --security khi chạy thủ công. dnf-automatic không có thiết lập cho việc này.
Một lưu ý nữa áp dụng cho Rocky. Rocky tạo errata từ dữ liệu của Red Hat thông qua pipeline riêng, và pipeline đó đôi khi bị chậm trễ. Vào tháng 9 năm 2025, người dùng báo cáo rằng updateinfo.xml của Rocky 9 BaseOS đã không thay đổi từ tháng 12 năm 2024, dẫn đến việc --security thiếu các thông báo gần đây, và đội ngũ Rocky đã xác nhận đây là vấn đề đã biết. Nếu bạn phụ thuộc vào upgrade_type = security, hãy so sánh danh sách thông báo với các thông báo RLSA gần đây định kỳ. Trên một hệ thống mà độ bao phủ quan trọng hơn kiểm soát thay đổi, upgrade_type = default theo lịch trình bạn chọn là thiết lập an toàn hơn.
Systemd timer thực sự thực thi tác vụ đó
sudo systemctl enable --now dnf-automatic.timer
systemctl list-timers dnf-automatic.timerlist-timers sẽ in ra một hàng với thời gian NEXT cách khoảng một ngày. Bảng trống nghĩa là timer chưa được enable, nên sẽ không có gì chạy cả.
Timer mặc định kích hoạt vào *-*-* 6:00 với RandomizedDelaySec=60m và Persistent=true. Độ trễ ngẫu nhiên (random delay) giúp phân tán tải trên toàn bộ hệ thống trong vòng một giờ để không phải tất cả máy chủ đều truy cập mirror cùng một giây. Persistent=true nghĩa là một máy bị tắt lúc 06:00 sẽ chạy tác vụ bị bỏ lỡ ngay sau khi khởi động, thay vì bỏ qua cả ngày đó.
Thay đổi lịch trình bằng file drop-in. Đừng chỉnh sửa unit mặc định, vì khi nâng cấp package, các file trong /usr/lib/systemd/system sẽ bị ghi đè.
sudo systemctl edit dnf-automatic.timer[Timer]
OnCalendar=
OnCalendar=*-*-* 03:30
RandomizedDelaySec=30mDòng OnCalendar= trống là bắt buộc. OnCalendar có tính chất cộng dồn, nên nếu không reset, bạn sẽ giữ lại mục 06:00 cũ và thêm một mục mới, khiến tác vụ chạy hai lần mỗi ngày. Xác nhận kết quả bằng systemctl list-timers dnf-automatic.timer và đọc cột NEXT. Các quy tắc drop-in tương tự áp dụng cho mọi thứ khác bạn lập lịch, nội dung này được đề cập trong viết systemd service và timer unit.
Bây giờ là cái bẫy. Package cung cấp thêm ba timer nữa: dnf-automatic-notifyonly.timer, dnf-automatic-download.timer và dnf-automatic-install.timer. Mỗi cái khởi chạy cùng một chương trình với các flag dòng lệnh, và các flag đó sẽ ghi đè lên download_updates và apply_updates từ file cấu hình của bạn. Nếu enable một trong số chúng cùng với dnf-automatic.timer, tác vụ sẽ chạy hai lần với hai hành vi khác nhau, trông giống như file cấu hình của bạn bị bỏ qua. Hãy enable một timer và kiểm tra:
systemctl list-unit-files 'dnf-automatic*'Làm sao để biết thời điểm cài đặt một thứ gì đó?
emit_via trong phần [emitters] kiểm soát việc báo cáo. Với systemd, bộ phát stdio sẽ ghi vào journal, đây là tùy chọn đáng tin cậy vì nó không yêu cầu cài đặt thêm bất cứ thứ gì:
sudo journalctl -u dnf-automatic.service --since -7d --no-pagerBộ phát motd ghi báo cáo vào /etc/motd và thay thế nội dung của tệp đó. Nếu bạn để banner đăng nhập ở đó, hãy bỏ qua bộ phát này.
Bộ phát email mở một kết nối SMTP (simple mail transfer protocol) tới email_host trên cổng email_port, mặc định là localhost và 25. Một VPS mới không có dịch vụ nào nghe tại đó, nên kết nối sẽ bị từ chối và không có email nào được gửi đi. Hãy chạy ss -lnt | grep ':25' trước khi bạn dựa vào nó, và thiết lập một Postfix chỉ làm relay nếu đầu ra trống. Khi email hoạt động, tiêu đề sẽ là Updates applied on 'web01'., lấy tên từ system_name.
Đối với bất kỳ thứ gì khác, bộ phát command chuyển báo cáo cho một chương trình của bạn thông qua standard input:
[emitters]
emit_via = stdio, command
system_name = web01.example.com
send_error_messages = yes
[command]
command_format = /usr/local/bin/notify-ops
stdin_format = {body}send_error_messages mặc định là no, nghĩa là một lần chạy thất bại sẽ không báo cáo gì cả. Hãy bật nó lên. Một hệ thống vá lỗi chỉ thông báo khi thành công còn tệ hơn là không có gì, vì sự im lặng đó bị hiểu nhầm là hệ thống vẫn ổn.
dnf-automatic không tự khởi động lại các service của bạn
Việc cài đặt một gói phần mềm chỉ thay thế các file trên ổ đĩa. Một tiến trình đang chạy vẫn giữ mã cũ trong bộ nhớ, vì vậy một thư viện đã được vá sẽ không có tác dụng gì với một daemon đã khởi động từ tháng trước. Khoảng cách giữa trạng thái đã cài đặt và trạng thái thực thi là lý do tại sao việc vá lỗi tự động cần một chính sách khởi động lại, chứ không chỉ là chính sách cài đặt.
sudo dnf install -y dnf-plugins-core
dnf needs-restarting -s
dnf needs-restarting -r-s liệt kê các service systemd có file đã thay đổi kể từ khi chúng khởi động. -r trả lời một câu hỏi và in ra một trong hai khối kết quả:
Core libraries or services have been updated since boot-up:
* kernel
Reboot is required to fully utilize these updates.No core libraries or services have been updated since boot-up.
Reboot should not be necessary.-r không phải là một công cụ phân tích chuyên sâu. Nó kiểm tra một danh sách cố định các gói: kernel, kernel-core, kernel-rt, glibc, linux-firmware, systemd, dbus, dbus-broker, dbus-daemon và microcode_ctl. Nếu một trong số chúng được cài đặt sau lần boot cuối cùng, bạn sẽ nhận được câu trả lời đầu tiên. Hãy thêm tên các gói của riêng bạn vào một file có đuôi .conf nằm trong thư mục /etc/dnf/plugins/needs-restarting.d/ khi có thành phần khác trên máy chủ cũng cần khởi động lại để áp dụng thay đổi.
Một lưu ý cho các script: dnf needs-restarting -r trả về mã thoát khác 0 cả khi cần khởi động lại và khi chính lệnh đó bị lỗi, vì vậy chỉ dựa vào mã thoát là không thể phân biệt được hai trường hợp này. Hãy đọc nội dung văn bản đầu ra.
Khởi động lại service là thao tác nhỏ hơn và thường là lựa chọn đúng đắn. Hãy khởi động lại SSH daemon từ một phiên SSH thứ hai đang mở sẵn để tránh việc cấu hình sai khiến bạn bị khóa quyền truy cập. Kernel mới là trường hợp duy nhất cần khởi động lại máy, vì kernel đang chạy không thể bị thay thế trực tiếp.
Máy chủ có nên tự khởi động lại không?
[commands]
reboot = when-needed
reboot_command = shutdown -r +5 'Rebooting after applying package updates'reboot = never là tùy chọn mặc định. when-changed sẽ khởi động lại sau khi áp dụng bất kỳ bản cập nhật nào. when-needed chỉ khởi động lại khi quá trình kiểm tra phía sau needs-restarting -r xác định có gói lõi (core package) đã được thay thế, đây là điều mà hầu hết người dùng quản lý một máy chủ đơn lẻ mong muốn, kết hợp với một khoảng thời gian định sẵn do họ tự chọn. Giá trị mặc định reboot_command sẽ cảnh báo người dùng đang đăng nhập trước năm phút thông qua shutdown, và bạn có thể kéo dài khoảng thời gian này.
Hãy giải quyết hai vấn đề trước khi bật tính năng này. Mọi dịch vụ bạn phụ thuộc vào phải tự khởi động cùng hệ thống, đây thường là thiếu sót đối với Docker Compose stack được khởi động thủ công. Bạn cũng cần có quyền truy cập console hoặc chế độ rescue từ nhà cung cấp, vì kernel không khởi động được thì không thể sửa qua SSH. Nếu thiếu một trong hai điều kiện trên, hãy giữ nguyên reboot = never và tự khởi động lại sau khi đã đọc log trong journal.
Rocky, AlmaLinux và CentOS Stream: sự khác biệt
Trên Rocky 9 và AlmaLinux 9, mọi thứ nêu trên đều giống hệt nhau, từ đường dẫn cấu hình cho đến tên unit. Cả hai đều công bố errata, vì vậy upgrade_type = security có dữ liệu để lọc.
CentOS Stream là trường hợp ngoại lệ và khá khó xử lý. Các repository của Stream không chứa updateinfo.xml, nên bộ lọc bảo mật sẽ không bao giờ khớp và mọi lần chạy đều báo No security updates needed. Trên Stream, hãy dùng upgrade_type = default và chấp nhận việc bạn sẽ nhận mọi bản cập nhật. Stream cũng chạy trước RHEL, nên thiết lập đó sẽ thay đổi nhiều hơn trên một máy Stream so với cùng thiết lập trên Rocky hoặc AlmaLinux.
Rocky 10 và AlmaLinux 10 đã chuyển sang DNF5, dẫn đến việc đổi tên một số thành phần. Tài liệu DNF5 từ upstream chỉ định timer là dnf5-automatic.timer, đặt các giá trị mặc định được cung cấp sẵn vào /usr/share/dnf5/dnf5-plugins/automatic.conf với các ghi đè của bạn vẫn nằm trong /etc/dnf/automatic.conf, mặc định download_updates thành yes thay vì no, và thêm distro-sync như một upgrade_type. Truy vấn advisory là dnf advisory list, với updateinfo được giữ lại làm alias. Hãy xác nhận phiên bản bạn thực sự đã cài đặt trước khi sao chép tên gói hoặc tên unit từ một hướng dẫn viết cho bản 9:
dnf list --available '*automatic*'
systemctl list-unit-files '*automatic*'Nhiều hướng dẫn đã xuất bản về chủ đề này vẫn chỉ bao phủ Rocky 8. Tập hợp tùy chọn đã mở rộng kể từ khi các bài viết đó được viết, vì vậy hãy kiểm tra file cấu hình có chú thích trên máy của chính bạn thay vì tin tưởng vào một bài viết cũ.
Các chế độ lỗi và các chuỗi bạn sẽ thấy
Không có gì chạy cả. systemctl list-timers dnf-automatic.timer in ra một bảng trống và systemctl is-enabled dnf-automatic.timer in ra disabled. Gói đã được cài đặt, nhưng timer thì chưa.
Job chạy nhưng không cài đặt gì cả. Journal chứa No security updates needed, but 3 updates available. Bộ lọc bảo mật không khớp với bất kỳ thứ gì, có thể vì không có bản cập nhật nào đang chờ xử lý hoặc kho lưu trữ không công bố dữ liệu tư vấn bảo mật.
Một thiết lập có vẻ bị bỏ qua. DNF ghi log một tùy chọn không xác định trong automatic.conf ở mức debug và sau đó sử dụng giá trị mặc định, vì vậy một khóa bị viết sai chính tả sẽ không thay đổi gì và cũng không cảnh báo ai. Bạn viết apply_update = yes và apply_updates vẫn ở mức no, kết quả là máy chủ tải xuống mãi mãi mà không bao giờ cài đặt. Sau bất kỳ chỉnh sửa nào, hãy chạy sudo systemctl start dnf-automatic.service và đọc journal thay vì tin tưởng vào file cấu hình.
Job chạy hai lần một ngày. Hai timer đang được enable. systemctl list-unit-files 'dnf-automatic*' hiển thị timer nào đang chạy, và các timer thừa sẽ truyền các flag ghi đè lên file cấu hình của bạn.
Không có email nào đến. Hoặc không có tiến trình nào đang lắng nghe trên cổng 25 cho bộ phát email, hoặc send_error_messages vẫn đang là no và thứ duy nhất đáng báo cáo là một lỗi.
Một service đã được patch vẫn báo cáo phiên bản cũ. File trên đĩa đã mới nhưng tiến trình trong bộ nhớ vẫn là bản cũ. dnf needs-restarting -s liệt kê các service cần restart.
FAQ
dnf-automatic có chỉ cài đặt các bản cập nhật bảo mật trên Rocky Linux không?
Chỉ khi bạn thiết lập upgrade_type = security trong /etc/dnf/automatic.conf, và chỉ khi các repository của bạn công bố metadata errata. Cả Rocky Linux và AlmaLinux đều công bố thông tin này, nên bộ lọc có các advisory để đối chiếu. Mặc định được cài sẵn là upgrade_type = default, nó sẽ cài đặt mọi bản cập nhật khả dụng ngay khi apply_updates = yes.
Tại sao dnf-automatic báo "No security updates needed, but 3 updates available"?
DNF xác định cái gì được tính là cập nhật bảo mật bằng cách đọc updateinfo.xml từ repository, nơi mỗi advisory liệt kê các gói cần sửa lỗi. Khi metadata này thiếu hoặc cũ, bộ lọc bảo mật không khớp với bất kỳ thứ gì trong khi các bản cập nhật thông thường vẫn đang chờ, dẫn đến dòng thông báo đó. Điều này là bình thường trên CentOS Stream vì hệ điều hành này không công bố errata. Trên Rocky hoặc AlmaLinux, hãy so sánh dnf updateinfo list --security với dnf check-update và kiểm tra xem metadata của bạn đã cập nhật chưa.
dnf-automatic có tự khởi động lại server sau khi cập nhật kernel không?
Không, trừ khi bạn yêu cầu. Tùy chọn reboot mặc định là never. Hãy thiết lập reboot = when-needed để quá trình chạy chỉ khởi động lại khi kiểm tra phía sau dnf needs-restarting -r phát hiện một gói cốt lõi như kernel hoặc glibc đã bị thay thế kể từ lần boot gần nhất. reboot = when-changed sẽ khởi động lại sau bất kỳ bản cập nhật nào được áp dụng. Cả hai đều sử dụng reboot_command, mặc định là shutdown -r +5 kèm theo thông báo cảnh báo cho người dùng đang đăng nhập.
Làm thế nào để thay đổi thời gian dnf-automatic chạy?
Chạy sudo systemctl edit dnf-automatic.timer và thêm một phần [Timer] với dòng OnCalendar= trống, theo sau là lịch trình của bạn, ví dụ OnCalendar=*-*-* 03:30. Dòng trống là bắt buộc vì OnCalendar có tính chất cộng dồn, nếu bỏ qua nó, hệ thống sẽ giữ lại lịch chạy 06:00 mặc định và thêm một lịch thứ hai. Xác nhận bằng systemctl list-timers dnf-automatic.timer và đọc cột NEXT.
Tôi có cần kiểm tra server tự vá lỗi không?
Có. dnf-automatic chỉ cài đặt các gói và dừng lại ở đó. Nó không khởi động lại các daemon, và nó không báo cáo bất cứ điều gì bạn sẽ thấy trừ khi emit_via chỉ định một emitter mà bạn thực sự đọc. Hãy thiết lập emit_via thành stdio ở mức tối thiểu, bật send_error_messages để các lỗi cũng được báo cáo, và chạy dnf needs-restarting -s sau một cửa sổ vá lỗi để tìm các dịch vụ vẫn đang chạy mã cũ.