Vì sao “secure sau deploy” mới là tư duy đúng cho DevOps?
Trong nhiều đội ngũ DevOps, bảo mật máy chủ Ubuntu thường được xử lý theo kiểu “làm một lần rồi thôi”: harden SSH, bật firewall, tắt root login, cài fail2ban, xong. Vấn đề là hệ thống không đứng yên. Mỗi lần triển khai ứng dụng, thay đổi package, cập nhật cấu hình Nginx, mở thêm port, thêm user service hoặc chỉnh quyền file đều có thể tạo ra một lỗ hổng mới mà hôm qua chưa tồn tại.
Đó là lý do một Ubuntu server “đã secure” vẫn có thể trở nên kém an toàn chỉ sau một lần deploy tưởng như vô hại. Với DevOps hiện đại, câu hỏi không nên là “server này đã được hardening chưa?” mà là: sau mỗi lần triển khai, chúng ta có tự động xác minh rằng server vẫn an toàn không?
Bài viết này tập trung vào cách xây dựng quy trình kiểm tra bảo mật tự động cho Ubuntu server sau mỗi lần deploy: từ các hạng mục cần kiểm tra, công cụ phù hợp, cách tích hợp vào pipeline CI/CD, đến cách biến kết quả kiểm tra thành hành động thực tế.
Mục tiêu của quy trình kiểm tra bảo mật sau deploy
Khi nói đến “security checks”, nhiều người nghĩ ngay đến quét lỗ hổng phức tạp. Thực tế, với Ubuntu server phục vụ ứng dụng web hoặc API, mục tiêu nên rất thực dụng:
– Phát hiện sai lệch cấu hình sau deploy.
– Xác minh các kiểm soát bảo mật cốt lõi vẫn hoạt động.
– Cảnh báo sớm nếu có package hoặc service rủi ro xuất hiện.
– Ngăn release không an toàn đi tiếp trong pipeline.
Thay vì cố “đảm bảo tuyệt đối”, hãy xây dựng cơ chế giúp bạn trả lời nhanh các câu hỏi sau:
– SSH có còn tắt root login và password auth không?
– Firewall có chỉ mở đúng port cần thiết không?
– Có package nào mang CVE mức nghiêm trọng vừa được cài vào không?
– Service mới có đang chạy với quyền quá cao không?
– File .env, private key, hoặc thư mục ứng dụng có quyền truy cập quá rộng không?
– Nginx/Apache có vô tình lộ version header hoặc bật cấu hình yếu không?
Nếu kiểm tra được các điểm đó sau mỗi lần triển khai, bạn đã giảm đáng kể rủi ro vận hành.
Những gì nên kiểm tra trên Ubuntu server
1. Cấu hình truy cập từ xa
Đây là lớp phòng thủ đầu tiên. Sau deploy hoặc sau khi automation thay đổi hệ thống, hãy kiểm tra:
– PermitRootLogin no
– PasswordAuthentication no
– Chỉ user hoặc group được phép SSH
– Không mở SSH trên mọi nguồn nếu không cần
Bạn có thể xác minh bằng cách đọc file /etc/ssh/sshd_config hoặc dùng policy kiểm tra trạng thái thực tế. Điều quan trọng là kiểm tra nên có tính máy móc, không phụ thuộc vào việc ai đó “nhớ xem lại”.
2. Firewall và cổng mạng
Một deploy script sai có thể kéo theo việc mở nhầm port cho app, database, Redis hoặc dashboard nội bộ. Trên Ubuntu, nên kiểm tra tối thiểu:
– ufw status hoặc rules của iptables / nftables
– Các port đang listen qua ss -tulpn
– Chỉ public các port thật sự cần như 22, 80, 443
Đây là loại lỗi cực phổ biến: ứng dụng chạy được, pipeline báo xanh, nhưng Redis lại lộ ra Internet.
3. Package và lỗ hổng hệ thống
Server an toàn hôm nay có thể kém an toàn ngày mai vì CVE mới được công bố. Vì vậy, sau mỗi deploy, nên kết hợp kiểm tra:
– Package lỗi thời hoặc thiếu bản vá
– Vulnerability scan cho OS package
– Các gói không mong muốn vừa được thêm vào image hoặc host
Với Ubuntu, bạn có thể dùng các công cụ như:
– Lynis: audit hệ thống tổng quát
– Ubuntu Pro / pro security-status: nếu hạ tầng dùng Ubuntu Pro
– Trivy: quét package, container image, filesystem
– OSQuery: truy vấn trạng thái hệ thống theo kiểu SQL
Không phải lúc nào cũng cần chặn deploy nếu có mọi CVE. Tốt hơn là đặt ngưỡng rõ ràng, ví dụ: fail pipeline nếu xuất hiện CVE Critical mới trong package được triển khai.
4. Quyền file và secret
Rất nhiều sự cố không đến từ hacker tinh vi, mà từ file chứa secret bị phân quyền sai. Sau deploy, nên kiểm tra:
– File .env, private key, config production không có quyền world-readable
– Thư mục app không thuộc quyền root nếu service không cần
– User chạy ứng dụng không có shell login nếu không cần
– Không lưu plaintext secret trong repo clone trên server
Ví dụ, private key nên ở mức 600, thư mục nhạy cảm ở 700 hoặc tương đương theo đúng use case.
5. Dịch vụ hệ thống và nguyên tắc tối thiểu quyền hạn
Mỗi service mới chạy trên server đều là bề mặt tấn công mới. Sau deploy, hãy kiểm tra:
– Có service lạ nào xuất hiện trong systemctl list-units --type=service không?
– App có đang chạy dưới user riêng thay vì root không?
– Có dùng sandboxing của systemd như NoNewPrivileges=true, PrivateTmp=true, ProtectSystem=full khi phù hợp không?
Nếu bạn chạy Node.js, Python, Java app qua systemd mà bỏ qua các hardening option cơ bản, bạn đang tự đánh mất một lớp bảo vệ rất rẻ nhưng hiệu quả.
Tự động hóa bằng policy thay vì checklist thủ công
Checklist thủ công phù hợp khi hệ thống còn nhỏ. Nhưng trong môi trường CI/CD, cách tốt hơn là chuyển yêu cầu bảo mật thành policy có thể kiểm tra tự động.
Một số hướng triển khai phổ biến:
Dùng script Bash cho các kiểm tra cơ bản
Ưu điểm là nhanh, dễ hiểu, dễ nhúng vào pipeline. Ví dụ:
#!/usr/bin/env bash
set -e
grep -Eq '^PermitRootLogin no' /etc/ssh/sshd_config
grep -Eq '^PasswordAuthentication no' /etc/ssh/sshd_config
ufw status | grep -q "Status: active"
ss -tulpn | grep -E ':6379|:3306' && exit 1 || true
Cách này phù hợp cho các rule đơn giản, nhưng sẽ khó mở rộng khi số lượng kiểm tra tăng.
Dùng công cụ audit như Lynis
Lynis rất phù hợp cho Ubuntu server vì nó kiểm tra nhiều khía cạnh: cấu hình hệ thống, kernel params, auth, services, filesystem. Bạn có thể chạy:
lynis audit system --quick