0

Checklist bảo mật Cloud Server: Những cấu hình cần kiểm tra trước khi đưa vào production

Cloud Server thường được dùng để chạy website, API, database, container hoặc các hệ thống nội bộ. Khi mới khởi tạo, nhiều máy chủ vẫn giữ cấu hình mặc định như cho phép SSH bằng mật khẩu, mở nhiều port không cần thiết, chưa bật firewall, chưa có cơ chế cập nhật bản vá hoặc chưa thiết lập monitoring. Những cấu hình này giúp triển khai nhanh nhưng cũng có thể làm tăng bề mặt tấn công.

Bảo mật Cloud Server không chỉ là cài một công cụ chống tấn công. Một hệ thống an toàn hơn cần được xây dựng từ nhiều lớp: tài khoản người dùng, SSH, firewall, cập nhật hệ điều hành, dịch vụ đang chạy, database, log, backup, monitoring và quy trình xử lý khi có sự cố.

Bài viết này cung cấp một checklist thực tế để kiểm tra Cloud Server trước khi đưa vào production hoặc dùng để audit lại một máy chủ đang vận hành.

Nguyên tắc quan trọng: Không có một cấu hình bảo mật duy nhất phù hợp với mọi hệ thống. Mỗi thay đổi nên được kiểm thử trước, đặc biệt với firewall, SSH, database và các service quan trọng để tránh tự khóa quyền truy cập hoặc gây downtime.

Kiểm tra tài khoản root

Một trong những việc đầu tiên nên kiểm tra là cách đăng nhập vào server.

Trên Linux, tài khoản root có toàn quyền. Không nên dùng root cho mọi thao tác hàng ngày.

Kiểm tra user hiện tại:

whoami

Xem danh sách user:

cat /etc/passwd

Có thể tạo user riêng:

sudo adduser deploy
sudo usermod -aG sudo deploy

Kiểm tra quyền sudo:

su - deploy
sudo whoami

Nếu trả về root, user đã có quyền sudo.

Mục tiêu là giảm thao tác trực tiếp bằng root và dễ audit hoạt động hơn.

Sử dụng SSH Key thay vì mật khẩu

SSH bằng mật khẩu dễ bị brute force nếu server public Internet.

Nên ưu tiên SSH Key.

Trên máy client:

ssh-keygen -t ed25519

Copy public key:

ssh-copy-id deploy@server_ip

Hoặc thêm thủ công vào:

~/.ssh/authorized_keys

Sau khi xác nhận login bằng key hoạt động, chỉnh:

sudo nano /etc/ssh/sshd_config

Có thể cấu hình:

PasswordAuthentication no
PubkeyAuthentication yes

Kiểm tra syntax:

sudo sshd -t

Reload SSH:

sudo systemctl reload ssh

Nên giữ một session SSH đang mở trong lúc kiểm tra để tránh tự khóa mình khỏi server.

Hạn chế đăng nhập root qua SSH

Nếu đã có user sudo hoạt động ổn định, có thể hạn chế root login.

Trong:

/etc/ssh/sshd_config

cấu hình:

PermitRootLogin no

Sau đó:

sudo sshd -t
sudo systemctl reload ssh

Không nên thực hiện trước khi xác nhận SSH Key và user sudo hoạt động.

Bật firewall

Một Cloud Server production không nên mở toàn bộ port ra Internet nếu không cần.

Nếu dùng UFW:

sudo ufw status

Cho phép SSH:

sudo ufw allow OpenSSH

Cho phép HTTP và HTTPS:

sudo ufw allow 80/tcp
sudo ufw allow 443/tcp

Bật firewall:

sudo ufw enable

Kiểm tra:

sudo ufw status numbered

Một server web thông thường có thể chỉ cần public:

22
80
443

Các port như:

3306
5432
6379
8080
9200

không nên mở public nếu không thực sự cần.

Kiểm tra toàn bộ port đang mở

Dùng:

sudo ss -tulpn

Hoặc:

sudo lsof -i -P -n | grep LISTEN

Với từng port, cần trả lời:

Port này thuộc service nào?
Có cần public không?
Ai cần truy cập?
Có thể giới hạn theo IP không?

Ví dụ 0.0.0.0:3306 nghĩa là MySQL có thể đang lắng nghe trên mọi interface.

Nếu database chỉ phục vụ application cùng server hoặc private network, cấu hình này cần được xem lại.

Không public database nếu không cần

Các port phổ biến:

MySQL      3306
PostgreSQL 5432
Redis      6379

không nên public trực tiếp trong phần lớn kiến trúc web thông thường.

Mô hình phù hợp hơn:

Internet
   |
   v
Nginx
   |
   v
Application
   |
Private Network
   |
Database

Có thể giới hạn bằng firewall, Security Group, private network hoặc bind address.

Ví dụ MySQL chạy cùng server:

bind-address = 127.0.0.1

Cập nhật hệ điều hành

Server lâu không cập nhật có thể tồn tại package chứa lỗ hổng đã được vá.

Ubuntu:

sudo apt update
sudo apt list --upgradable

Cập nhật:

sudo apt upgrade

Không nên update production một cách máy móc.

Nên kiểm tra trước:

  • Kernel.
  • Nginx/Apache.
  • Database.
  • Docker.
  • PHP.
  • Java.
  • OpenSSL.

Với hệ thống quan trọng, nên theo quy trình:

Staging
->
Test
->
Backup
->
Update Production

Bật cập nhật bảo mật tự động khi phù hợp

Ubuntu có thể sử dụng unattended upgrades.

Cài:

sudo apt install unattended-upgrades

Cấu hình:

sudo dpkg-reconfigure --priority=low unattended-upgrades

Cập nhật tự động giúp giảm nguy cơ bỏ sót security patch, nhưng cần cân nhắc ảnh hưởng với production.

Xóa hoặc tắt service không cần thiết

Mỗi service chạy thêm có thể tạo thêm bề mặt tấn công.

Liệt kê service đang chạy:

systemctl --type=service --state=running

Kiểm tra package:

dpkg -l

Nếu server không dùng FTP, mail server, database local, web panel hoặc service test, nên cân nhắc tắt hoặc gỡ bỏ.

Ví dụ:

sudo systemctl stop service_name
sudo systemctl disable service_name

Không nên xóa service nếu chưa chắc application không phụ thuộc vào nó.

Cài Fail2ban

Fail2ban có thể theo dõi log và chặn IP có hành vi đăng nhập sai lặp lại.

Cài:

sudo apt install fail2ban

Kiểm tra:

sudo systemctl status fail2ban

Xem jail:

sudo fail2ban-client status

Kiểm tra SSH:

sudo fail2ban-client status sshd

Fail2ban hữu ích nhưng không thay thế SSH Key và firewall.

Kiểm soát quyền file

Sai permission có thể khiến file cấu hình hoặc secret bị đọc bởi user không cần thiết.

Kiểm tra:

ls -la

Ví dụ:

~/.ssh              700
authorized_keys     600
private key         600

Có thể cấu hình:

chmod 700 ~/.ssh
chmod 600 ~/.ssh/authorized_keys

Không nên dùng:

chmod -R 777

để sửa lỗi permission.

Không hardcode secret trong source code

Không nên lưu trực tiếp database password, API key hoặc secret key trong source code được commit lên Git.

Có thể sử dụng:

  • Environment Variable.
  • Secret Manager.
  • File cấu hình ngoài repository.
  • Docker Secret.
  • Kubernetes Secret.

Kiểm tra repository:

git grep -i "password"
git grep -i "secret"

Nếu secret từng bị commit, chỉ xóa khỏi file hiện tại chưa đủ. Nên rotate secret vì nó có thể vẫn tồn tại trong Git history.

Bảo vệ file .env và file cấu hình

Nếu application dùng .env, cần đảm bảo web server không trả trực tiếp file này.

Kiểm tra:

curl -I https://example.com/.env

Kết quả mong muốn là:

403

hoặc:

404

Ngoài .env, nên kiểm tra:

.git
config.php
application.yml
backup.sql
dump.sql

Không nên để các file này truy cập công khai.

Không để thư mục .git public

Kiểm tra:

curl -I https://example.com/.git/config

Nếu server cho phép truy cập, cần xử lý ngay.

Không nên deploy repository Git trực tiếp vào public web root nếu chưa có rule chặn phù hợp.

Cấu hình HTTPS

Production nên sử dụng HTTPS.

Kiểm tra:

curl -I https://example.com

Kiểm tra Nginx:

sudo nginx -t

Kiểm tra thời hạn certificate:

openssl s_client -connect example.com:443 -servername example.com </dev/null 2>/dev/null | openssl x509 -noout -dates

Ngoài certificate, cần đảm bảo HTTP redirect sang HTTPS nếu phù hợp.

Kiểm tra Security Header

Một số header có thể giảm rủi ro phía browser:

X-Content-Type-Options
Referrer-Policy
Content-Security-Policy
Strict-Transport-Security

Kiểm tra:

curl -I https://example.com

Không nên copy một Content-Security-Policy quá chặt vào production nếu chưa test vì có thể làm hỏng JavaScript, font hoặc third-party service.

Giới hạn request ở endpoint nhạy cảm

Rate limiting có thể giảm abuse với:

  • Login.
  • API.
  • Search.
  • OTP.
  • Form.
  • Endpoint tốn tài nguyên.

Ví dụ Nginx:

limit_req_zone $binary_remote_addr zone=api_limit:10m rate=10r/s;

Áp dụng:

location /api/ {
    limit_req zone=api_limit burst=20 nodelay;
    proxy_pass http://127.0.0.1:8080;
}

Giá trị cần được load test.

Rate limit quá thấp có thể chặn người dùng thật.

Giới hạn kích thước upload

Một endpoint cho phép upload file rất lớn có thể làm đầy disk hoặc tăng tài nguyên.

Nginx:

client_max_body_size 20m;

Application cũng nên kiểm tra:

  • File size.
  • MIME type.
  • Extension.
  • Tên file.
  • Quyền truy cập.
  • Nội dung file nếu cần.

Không nên chỉ dựa vào phần mở rộng của file.

Kiểm tra log đăng nhập

Ubuntu:

sudo tail -f /var/log/auth.log

Xem login thành công:

grep "Accepted" /var/log/auth.log

Xem login thất bại:

grep "Failed password" /var/log/auth.log

Có thể kiểm tra thêm:

last

và:

lastb

Log giúp phát hiện brute force, IP lạ, user lạ hoặc thời điểm truy cập bất thường.

Kiểm tra process đang chạy

Dùng:

ps aux

Process dùng CPU cao:

ps aux --sort=-%cpu | head

Process dùng RAM cao:

ps aux --sort=-%mem | head

Nếu phát hiện process không rõ nguồn gốc:

lsof -p PID

Không nên kill hoặc xóa process ngay khi chưa biết nó thuộc service nào.

Kiểm tra cronjob

Cronjob có thể bị lợi dụng để duy trì persistence.

Kiểm tra:

crontab -l
sudo crontab -l

System cron:

ls -la /etc/cron.d/
ls -la /etc/cron.daily/

Nếu xuất hiện script hoặc command lạ, cần xác minh nguồn gốc.

Kiểm tra systemd service

Liệt kê:

systemctl list-unit-files --type=service

Xem service đang chạy:

systemctl --type=service --state=running

Kiểm tra service cụ thể:

systemctl cat service_name

Đây là bước hữu ích khi audit một server cũ hoặc server vừa phát hiện hành vi bất thường.

Giới hạn quyền sudo

Kiểm tra user thuộc nhóm sudo:

getent group sudo

Kiểm tra cấu hình:

sudo visudo

Không nên cấp sudo cho mọi user.

Trong các môi trường cần kiểm soát chặt, có thể cấp đúng command cần thiết thay vì quyền toàn hệ thống.

Kiểm tra user không còn sử dụng

Liệt kê:

cut -d: -f1 /etc/passwd

User cũ của nhân viên, freelancer hoặc account test không nên tồn tại vô thời hạn.

Có thể khóa:

sudo usermod -L username

Sau khi xác minh không còn sử dụng mới cân nhắc xóa.

Bảo mật Docker

Nếu server chạy Docker, cần kiểm tra:

docker ps

và:

docker images

Không nên dùng --privileged nếu không thực sự cần.

Không nên mount:

/var/run/docker.sock

vào container tùy tiện vì Docker socket có quyền rất cao trên host.

Kiểm tra port container:

docker ps

Ví dụ:

0.0.0.0:3306->3306

có thể vô tình expose database ra Internet.

Không chạy container bằng root khi có thể

Nhiều image mặc định chạy bằng root.

Dockerfile có thể cấu hình:

USER appuser

Việc này giúp giảm impact nếu container bị khai thác.

Ngoài ra cần:

  • Update base image.
  • Scan vulnerability.
  • Không nhúng secret vào image.
  • Xóa package không cần.

Bảo mật database account

Không nên để application sử dụng database account root hoặc superuser.

Nếu application chỉ cần:

SELECT
INSERT
UPDATE
DELETE

thì không nhất thiết cần:

DROP DATABASE
CREATE USER
GRANT

Áp dụng nguyên tắc Least Privilege giúp giảm phạm vi ảnh hưởng khi credential application bị lộ.

Kiểm tra backup

Backup là một phần quan trọng của security vì sự cố không chỉ đến từ tấn công.

Có thể xảy ra:

  • Ransomware.
  • Xóa nhầm dữ liệu.
  • Application bug.
  • Database corruption.
  • Disk lỗi.
  • Deploy sai.

Checklist backup:

  • Có backup tự động.
  • Backup nằm ngoài server chính.
  • Có retention.
  • Có version.
  • Có encryption nếu cần.
  • Đã test restore.

Một backup nằm cùng ổ đĩa với production không đủ an toàn nếu cả server bị mất.

Snapshot không thay thế backup

Snapshot hữu ích để quay lại trạng thái storage tại một thời điểm, nhưng không nên là chiến lược backup duy nhất.

Nên kết hợp:

Snapshot
+
Database Backup
+
Offsite Backup

và kiểm tra restore định kỳ.

Monitoring tài nguyên

Theo dõi:

CPU
RAM
Disk
Network
Load Average

Kiểm tra disk:

df -h

Kiểm tra inode:

df -i

RAM:

free -h

CPU:

top

Disk đầy có thể làm database lỗi, log không ghi được hoặc service không restart được.

Monitoring bảo mật

Ngoài CPU/RAM, cần theo dõi:

  • SSH login fail.
  • HTTP 4xx/5xx.
  • Request bất thường.
  • Traffic spike.
  • Port mới xuất hiện.
  • Process lạ.
  • Account mới.
  • Cronjob mới.

Nếu có centralized logging, việc điều tra sự cố sẽ dễ hơn khi server bị lỗi hoặc bị xâm nhập.

Bật alert thay vì chỉ có dashboard

Dashboard chỉ hữu ích khi có người đang nhìn.

Nên có alert cho:

Server down
CPU cao
RAM thấp
Disk gần đầy
HTTP 5xx tăng
Database connection cao

Với bảo mật, có thể cảnh báo:

SSH brute force
Login bất thường
WAF block tăng
Traffic tăng bất thường

Ngưỡng alert cần phù hợp workload để tránh quá nhiều cảnh báo giả.

Đồng bộ thời gian server

Thời gian chính xác rất quan trọng với log và điều tra sự cố.

Kiểm tra:

timedatectl

Nếu nhiều server lệch thời gian, việc đối chiếu log sẽ khó hơn.

Chuẩn bị runbook khi bị xâm nhập

Không nên đợi tới khi server bị hack mới nghĩ cách xử lý.

Một runbook cơ bản:

Phát hiện
->
Cô lập
->
Thu thập log
->
Xác định phạm vi
->
Rotate credential
->
Khôi phục
->
Theo dõi

Không nên luôn reboot hoặc xóa log ngay khi phát hiện sự cố nếu hệ thống cần điều tra nguyên nhân.

Checklist bảo mật Cloud Server trước production

Tài khoản và SSH

  • Không vận hành hàng ngày bằng root.
  • Có user riêng.
  • SSH Key hoạt động.
  • Password login được hạn chế nếu phù hợp.
  • Root SSH login được kiểm soát.
  • User cũ đã được rà soát.
  • Quyền sudo đã được kiểm tra.

Network

  • Firewall đã bật.
  • Chỉ mở port cần thiết.
  • Database không public nếu không cần.
  • Redis không public.
  • Port container đã được kiểm tra.
  • Private Network được sử dụng khi phù hợp.

Hệ điều hành

  • Package security đã được cập nhật.
  • Service không cần thiết đã tắt.
  • Fail2ban hoặc cơ chế tương đương được cấu hình nếu cần.
  • Cronjob đã được kiểm tra.
  • Systemd service đã được rà soát.

Application

  • Không hardcode secret.
  • .env không public.
  • .git không public.
  • File upload được giới hạn.
  • Application không chạy root nếu không cần.
  • HTTP security header đã được kiểm tra.
  • HTTPS hoạt động.

Database

  • Không dùng root/superuser cho application.
  • Database chỉ cho phép kết nối từ nguồn cần thiết.
  • Có backup.
  • Có restore test.
  • Có monitoring connection và error.

Docker

  • Không dùng --privileged nếu không cần.
  • Không expose Docker socket tùy tiện.
  • Image được cập nhật.
  • Port container đã được kiểm tra.
  • Secret không nằm trong image.
  • Container dùng user không phải root khi có thể.

Monitoring

  • Có alert server down.
  • Có alert CPU/RAM/Disk.
  • Có alert HTTP 5xx.
  • Có log SSH.
  • Có log application.
  • Có log web server.
  • Có cơ chế phát hiện traffic bất thường.

Backup và phục hồi

  • Backup chạy tự động.
  • Backup nằm ngoài server chính.
  • Có retention.
  • Có version.
  • Có restore test.
  • Có runbook xử lý sự cố.

Kết luận

Bảo mật Cloud Server không phải là một bước cấu hình duy nhất mà là một quy trình liên tục.

Một server chỉ bật firewall nhưng vẫn dùng SSH password yếu, database public và không có backup vẫn có nhiều rủi ro. Ngược lại, một server được bảo vệ theo nhiều lớp sẽ giảm đáng kể khả năng một lỗi đơn lẻ dẫn tới sự cố nghiêm trọng.

Một quy trình thực tế có thể đi theo:

User & SSH
->
Firewall & Network
->
Update & Service
->
Application & Secret
->
Database
->
Docker
->
Log & Monitoring
->
Backup & Recovery

Không nên triển khai tất cả thay đổi cùng lúc trên production mà chưa kiểm thử. Với các thay đổi liên quan SSH, firewall hoặc database, cần luôn chuẩn bị phương án rollback để tránh tự khóa quyền truy cập.

Sau khi hoàn thành checklist ban đầu, nên audit lại định kỳ. Bảo mật không phải trạng thái “cấu hình xong là xong”, vì application, dependency, user, port và workload đều có thể thay đổi theo thời gian.


All rights reserved

Viblo
Hãy đăng ký một tài khoản Viblo để nhận được nhiều bài viết thú vị hơn.
Đăng kí