Bảo mật VPS không nên bắt đầu bằng việc đổi cổng SSH hoặc cài thật nhiều công cụ. Với người mới, điều quan trọng nhất là thực hiện đúng thứ tự: giữ đường cứu hộ, cập nhật hệ thống, tạo tài khoản riêng, kiểm tra SSH key, sau đó mới tắt đăng nhập nguy hiểm và siết firewall.
Bài viết này gồm đúng 15 bước, ưu tiên Ubuntu/Debian và ghi chú khác biệt khi dùng RHEL/AlmaLinux/Rocky Linux. Hãy làm từng bước, giữ nguyên một phiên SSH đang hoạt động và kiểm tra kết nối mới trước khi đóng phiên cũ.
Cảnh báo chống tự khóa: Trước khi sửa SSH hoặc firewall, hãy xác nhận bạn truy cập được console/VNC/serial console của nhà cung cấp và đã có snapshot hoặc backup. Không tắt đăng nhập root/mật khẩu cho đến khi SSH key và tài khoản sudo mới hoạt động thực tế.

Bảo mật VPS cần giải quyết những rủi ro nào?
Một VPS mới thường mở SSH ra Internet, dùng tài khoản root, chưa có chính sách cập nhật, chưa giám sát đăng nhập và chỉ có bản sao dữ liệu trên chính máy chủ. Bot có thể quét địa chỉ IP và thử mật khẩu liên tục, nhưng brute force không phải rủi ro duy nhất.
| Rủi ro | Biện pháp chính |
|---|---|
| Tài khoản bị chiếm | SSH key, tài khoản riêng, giới hạn quyền, MFA khi phù hợp |
| Dịch vụ có lỗ hổng | Cập nhật hệ điều hành và phần mềm, giảm dịch vụ không dùng |
| Cổng công khai quá rộng | Firewall tại nhà cung cấp và trên VPS |
| Không phát hiện sự cố | Log, cảnh báo đăng nhập, theo dõi tài nguyên |
| Mất dữ liệu hoặc ransomware | Backup tách khỏi VPS và thử khôi phục |
| Cấu hình sai gây mất truy cập | Console cứu hộ, kiểm tra cấu hình, rollback từng bước |
Đổi cổng SSH chỉ giảm log rác; nó không thay thế SSH key, cập nhật hay firewall. Tương tự, Fail2ban không vá lỗ hổng và antivirus không thể bảo vệ một tài khoản quản trị đã bị lộ.
1. Giữ đường cứu hộ và ghi lại cấu hình ban đầu
Trước mọi thay đổi, đăng nhập trang quản lý VPS và kiểm tra console, rescue mode, snapshot cùng thông tin liên hệ hỗ trợ. Snapshot giúp quay lui nhanh khi cấu hình lỗi nhưng không thay thế backup dài hạn vì thường nằm cùng nhà cung cấp.
Ghi lại hệ điều hành, kernel, IP, dịch vụ đang chạy và cổng đang lắng nghe:
cat /etc/os-release
uname -r
ip -br address
sudo ss -tulpn
sudo systemctl --type=service --state=running
sudo sshd -T | grep -E '^(port|permitrootlogin|passwordauthentication|kbdinteractiveauthentication|pubkeyauthentication) '
Không đăng công khai kết quả có IP quản trị, hostname nội bộ hoặc token. Danh sách này là baseline để nhận ra cổng hay dịch vụ xuất hiện bất thường sau này.
2. Cập nhật hệ điều hành và dùng phiên bản còn hỗ trợ
Hệ điều hành hết vòng đời không còn nhận bản vá bảo mật. Nếu VPS đang chạy bản quá cũ, hãy lên kế hoạch dựng máy mới và chuyển dữ liệu thay vì tiếp tục chắp vá vô thời hạn.
Ubuntu/Debian:
sudo apt update
apt list --upgradable
sudo apt upgrade
RHEL, AlmaLinux hoặc Rocky Linux:
sudo dnf upgrade --refresh
Kiểm tra yêu cầu reboot sau khi cập nhật Ubuntu/Debian:
if [ -f /var/run/reboot-required ]; then
cat /var/run/reboot-required
fi
Đọc changelog và lên maintenance window với kernel, database, control panel hoặc máy chủ có giao dịch. Sau reboot, kiểm tra SSH, web, database, cron, mail và firewall.
Với OpenSSH, nên theo dõi thông báo bảo mật và cập nhật package từ repository chính thức; có thể xem ví dụ thực tế tại bài cập nhật OpenSSH để xử lý lỗ hổng regreSSHion.
3. Tạo tài khoản quản trị riêng có quyền sudo
Không nên để nhiều người dùng chung tài khoản root. Mỗi quản trị viên cần một tài khoản riêng để thu hồi và truy vết khi nhân sự thay đổi.
Trên Ubuntu/Debian, thay opsadmin bằng tên tài khoản của bạn:
sudo adduser opsadmin
sudo usermod -aG sudo opsadmin
id opsadmin
Trên RHEL-based, nhóm quản trị thường là wheel:
sudo usermod -aG wheel opsadmin
Đừng cấp sudo cho tài khoản chạy website, database hoặc ứng dụng. Khi cần chỉnh sudoers, luôn dùng visudo để tránh lỗi cú pháp:
sudo visudo
4. Tạo SSH key trên máy cá nhân
Chạy lệnh tạo khóa trên máy tính của bạn, không phải trên VPS. Ed25519 là lựa chọn hiện đại, gọn và được OpenSSH hỗ trợ rộng rãi:
ssh-keygen -t ed25519 -a 100 -C "opsadmin-vps"
Đặt passphrase mạnh cho private key. Chỉ sao chép file public có đuôi .pub; không gửi private key qua email, chat hoặc đặt lên VPS.
Cài public key cho tài khoản mới:
ssh-copy-id opsadmin@SERVER_IP
Nếu đang dùng Windows hoặc môi trường không có ssh-copy-id, có thể thêm nội dung public key vào ~/.ssh/authorized_keys của user mới, rồi đặt quyền thư mục/file tương ứng là 700 và 600.
Xem hướng dẫn chi tiết tại bài sử dụng SSH Key để truy cập VPS/Server.
5. Xác minh SSH key trong một phiên mới
Giữ nguyên phiên root hoặc phiên quản trị đang hoạt động. Mở một cửa sổ terminal khác và thử đăng nhập:
ssh -i ~/.ssh/id_ed25519 opsadmin@SERVER_IP
Sau khi vào được, xác minh sudo:
sudo -v
sudo whoami
Kết quả sudo whoami phải là root. Nếu key không hoạt động, kiểm tra owner và permission của thư mục .ssh, public key, log SSH và rule firewall. Không chuyển sang bước tắt mật khẩu cho đến khi đăng nhập mới thành công nhiều lần.

6. Harden SSH bằng file cấu hình riêng
Ưu tiên tạo file drop-in để dễ rollback thay vì sửa nhiều dòng rải rác trong file chính. OpenSSH thường dùng giá trị đầu tiên tìm thấy cho nhiều directive; trên Ubuntu, thư mục sshd_config.d được include sớm và có thể đã có file như 50-cloud-init.conf. Vì vậy hãy dùng tên đọc trước và luôn kiểm tra cấu hình hiệu lực:
sudoedit /etc/ssh/sshd_config.d/00-vps-hardening.conf
Cấu hình cơ bản sau chỉ áp dụng sau khi bước 5 đã thành công:
PermitRootLogin no
PubkeyAuthentication yes
PasswordAuthentication no
KbdInteractiveAuthentication no
MaxAuthTries 3
LoginGraceTime 30
AllowUsers opsadmin
Nếu bạn dùng PAM/Google Authenticator hoặc MFA qua keyboard-interactive, không đặt KbdInteractiveAuthentication no cho đến khi đã xác định cấu hình 2FA cần giá trị nào. AllowUsers cũng phải liệt kê đầy đủ tài khoản quản trị hoặc tự động hóa hợp lệ.
Kiểm tra cú pháp trước khi reload:
sudo sshd -t
sudo sshd -T | grep -E \
'^(pubkeyauthentication|permitrootlogin|passwordauthentication|kbdinteractiveauthentication|maxauthtries) '
sudo systemctl reload ssh
Trên RHEL-based, tên service thường là sshd. Sau reload, mở thêm một phiên SSH mới để thử; chỉ đóng phiên cũ khi kết nối mới hoạt động. Nếu muốn triển khai MFA, xem bài cấu hình 2FA cho SSH trên Ubuntu.
Nếu cấu hình mới gây lỗi và phiên cũ vẫn còn mở, rollback bằng cách xóa file drop-in vừa tạo, kiểm tra lại cú pháp rồi reload. Nếu đã mất SSH, thực hiện từ console cứu hộ của nhà cung cấp:
sudo rm /etc/ssh/sshd_config.d/00-vps-hardening.conf
sudo sshd -t && sudo systemctl reload ssh
7. Cấu hình firewall theo nguyên tắc chỉ mở cổng cần thiết
Dùng hai lớp nếu nhà cung cấp hỗ trợ: cloud firewall/security group bên ngoài và firewall trên hệ điều hành. Trước khi bật rule deny, phải allow đúng cổng SSH đang sử dụng.
Ví dụ UFW cho VPS web dùng SSH mặc định, HTTP và HTTPS:
sudo ufw default deny incoming
sudo ufw default allow outgoing
sudo ufw allow OpenSSH
sudo ufw allow 80/tcp
sudo ufw allow 443/tcp
sudo ufw enable
sudo ufw status verbose
Nếu SSH chạy cổng khác, mở cổng mới trước khi xóa rule cũ. Kiểm tra /etc/default/ufw để chắc chắn chính sách IPv6 phù hợp; đừng chỉ lọc IPv4 trong khi dịch vụ vẫn lắng nghe trên IPv6.
Trên RHEL-based có thể dùng firewalld:
sudo firewall-cmd --permanent --add-service=ssh
sudo firewall-cmd --permanent --add-service=http
sudo firewall-cmd --permanent --add-service=https
sudo firewall-cmd --reload
sudo firewall-cmd --list-all
Không mở database, Redis, Docker API hoặc control panel cho toàn Internet nếu không cần. Hãy giới hạn IP quản trị, dùng VPN hoặc private network. Xem thêm hướng dẫn cài đặt CSF trên Ubuntu nếu hạ tầng của bạn phù hợp CSF.

8. Chống brute force bằng Fail2ban hoặc lớp tương đương
Fail2ban đọc log và tạm chặn IP vi phạm nhiều lần. Nó là lớp giảm bot/brute force, không thay thế SSH key, cập nhật hoặc firewall.
Ubuntu/Debian:
sudo apt install fail2ban
sudoedit /etc/fail2ban/jail.d/sshd.local
Nội dung tối thiểu:
[sshd]
enabled = true
backend = systemd
bantime = 1h
findtime = 10m
maxretry = 5
Kiểm tra rồi khởi động:
sudo fail2ban-client -t
sudo systemctl enable --now fail2ban
sudo fail2ban-client status sshd
Ngưỡng cần phù hợp với người dùng thật. Tránh ban vĩnh viễn ngay từ đầu; NAT công ty hoặc mạng di động có thể khiến nhiều người dùng chung một IP. Nếu đã dùng WAF, CrowdSec hoặc cơ chế của nhà cung cấp, tránh chồng rule mà không biết lớp nào đang chặn.
9. Đóng cổng và tắt dịch vụ không sử dụng
Mỗi daemon chạy nền là thêm một thành phần phải cập nhật và giám sát. So sánh kết quả với baseline ở bước 1:
sudo ss -lntup
sudo systemctl --type=service --state=running
Trước khi tắt service, xác định package nào cài nó và ứng dụng nào đang phụ thuộc. Sau đó mới thực hiện có kiểm soát:
sudo systemctl disable --now TEN_DICH_VU
Không sao chép lệnh trên với tên bất kỳ. Các dịch vụ như DNS, mail, database, control panel hoặc agent backup có thể là thành phần thiết yếu dù bạn không truy cập trực tiếp.
10. Bật cập nhật bảo mật tự động có giám sát
Trên Ubuntu, unattended-upgrades có thể tự cài security updates. Cần kiểm tra nguồn package được phép, log và chính sách reboot thay vì bật rồi quên.
sudo apt install unattended-upgrades
sudo dpkg-reconfigure --priority=low unattended-upgrades
systemctl status unattended-upgrades
Các file chính nằm tại /etc/apt/apt.conf.d/50unattended-upgrades và /etc/apt/apt.conf.d/20auto-upgrades; log nằm trong /var/log/unattended-upgrades/.
Không mặc định mọi repository bên thứ ba đều được cập nhật tự động. Với kernel hoặc dịch vụ cần reboot, đặt maintenance window và cảnh báo thay vì tự khởi động lại ngẫu nhiên trên máy production.
11. Giữ AppArmor hoặc SELinux ở chế độ bảo vệ
AppArmor trên Ubuntu và SELinux trên RHEL-based giúp giới hạn những gì một tiến trình có thể truy cập ngay cả khi dịch vụ bị khai thác.
Ubuntu:
sudo aa-status
RHEL-based:
getenforce
sestatus
Không tắt AppArmor/SELinux chỉ để “sửa nhanh” lỗi permission. Hãy đọc audit log, xác định rule hoặc context thiếu và tạo exception hẹp. Chuyển SELinux sang permissive có thể dùng tạm để chẩn đoán, nhưng không phải trạng thái vận hành an toàn lâu dài.
12. Quản lý user, sudo, secret và quyền file
Rà tài khoản có shell, nhóm sudo/wheel, SSH key và cron định kỳ:
getent passwd
getent group sudo
sudo find /root /home -maxdepth 3 -name authorized_keys -type f -print
sudo crontab -l
Trên RHEL-based, thay nhóm sudo bằng wheel. Thu hồi user và key của nhân sự đã nghỉ, không dùng chung private key, không lưu token trong shell history hoặc repository công khai.
Secret của database, API và backup nên có owner/phân quyền tối thiểu. Không dùng chmod -R 777 để sửa lỗi. Dùng sudoers.d cho quyền cụ thể thay vì cấp toàn bộ root nếu automation chỉ cần restart một service.
13. Cô lập ứng dụng và container
Mỗi website hoặc dịch vụ quan trọng nên có user riêng. Database và Redis chỉ lắng nghe private interface/localhost khi không cần công khai. Với Docker, không publish port quản trị ra 0.0.0.0, không mount Docker socket vào container không tin cậy và tránh chạy container ở chế độ --privileged.
Kiểm tra port container đang publish:
docker ps --format "table {{.Names}}\t{{.Ports}}"
Docker có thể tự thêm rule mạng; đừng giả định bật UFW là mọi port container đã được chặn. Với Traefik, xem cách bảo mật Docker Socket bằng Socket Proxy.
14. Bật log, giám sát và cảnh báo quan trọng
Tối thiểu cần theo dõi đăng nhập SSH, sudo, thay đổi user, trạng thái service, dung lượng ổ đĩa, RAM/CPU, certificate và backup thất bại.
Một số lệnh kiểm tra nhanh:
sudo journalctl -u ssh --since today
sudo journalctl -p warning -b
last -ai
df -h
systemctl --failed
Trên RHEL-based, unit SSH thường là sshd. Đừng gửi password, private key, token hoặc toàn bộ log nhạy cảm vào kênh chat. Đặt cảnh báo theo ngưỡng và đẩy log quan trọng ra hệ thống khác để kẻ tấn công khó xóa dấu vết.
Nếu cần cảnh báo tức thời, tham khảo bài tạo bot cảnh báo đăng nhập SSH qua Telegram.
15. Backup ngoài VPS, thử restore và chuẩn bị xử lý sự cố
Một kế hoạch backup tối thiểu phải bao gồm dữ liệu ứng dụng, database, cấu hình, certificate và thông tin cần thiết để dựng lại máy. Giữ ít nhất một bản ở tài khoản hoặc nhà cung cấp khác; snapshot cùng VPS không đủ cho sự cố tài khoản bị chiếm hoặc nhà cung cấp gặp lỗi.
Xác định:
- RPO: Chấp nhận mất tối đa bao nhiêu dữ liệu.
- RTO: Chấp nhận dịch vụ ngừng bao lâu.
- Lịch backup và retention.
- Ai nhận cảnh báo khi job thất bại.
- Lần gần nhất restore thử thành công.
Có thể tham khảo backup dữ liệu website trên VPS bằng script và Rclone để đưa dữ liệu ra kho lưu trữ ngoài. Backup chứa secret hoặc dữ liệu khách hàng phải được mã hóa và giới hạn quyền.
Khi nghi VPS bị xâm nhập, không vội xóa log. Hãy cô lập máy, lưu snapshot hiện trạng để điều tra, xoay credential từ thiết bị sạch, dựng lại từ image/package tin cậy và chỉ phục hồi dữ liệu đã kiểm tra. Với sự cố nghiêm trọng, dựng VPS mới thường đáng tin cậy hơn cố “làm sạch” một hệ điều hành đã mất quyền kiểm soát.

Checklist bảo mật VPS theo lịch
Hàng ngày hoặc tự động
- Theo dõi uptime, CPU, RAM, disk và service quan trọng.
- Kiểm tra backup và cập nhật tự động có thành công không.
- Xử lý cảnh báo đăng nhập, sudo hoặc cổng mới bất thường.
Hàng tuần
- Cài bản vá còn chờ và kiểm tra yêu cầu reboot.
- Rà
ss -lntup, service failed và log warning/error. - Kiểm tra user, SSH key, cron và container mới.
Hàng tháng
- Xóa package/service không còn dùng.
- Rà firewall tại nhà cung cấp và trên VPS, gồm cả IPv6.
- Kiểm tra certificate, domain, API token và tài khoản quản trị.
- Restore thử một phần dữ liệu trên môi trường cô lập.
Hàng quý hoặc sau thay đổi lớn
- Thử dựng lại VPS từ tài liệu và backup.
- Rà quyền sudo, khóa của đối tác và recovery account.
- Kiểm tra AppArmor/SELinux, cấu hình SSH và chính sách reboot.
- Cập nhật playbook xử lý sự cố và người chịu trách nhiệm.
Những cách bảo mật VPS thường bị hiểu sai
- Chỉ đổi cổng SSH: Giảm log bot nhưng không thay SSH key, cập nhật hay rate limit.
- Tắt root/password ngay: Có thể tự khóa nếu key hoặc sudo chưa được kiểm tra.
- Mở firewall rồi quên IPv6: Dịch vụ có thể vẫn công khai qua địa chỉ IPv6.
- Cài Fail2ban là đủ: Fail2ban không vá CVE và không bảo vệ private key bị lộ.
- Tắt SELinux/AppArmor để hết lỗi: Làm mất lớp giới hạn thiệt hại thay vì sửa nguyên nhân.
- Backup trên cùng VPS: Có thể mất cùng dữ liệu khi ổ đĩa, tài khoản hoặc máy chủ gặp sự cố.
- Dùng nhiều script hardening tự động: Có thể tắt nhầm dịch vụ, khóa SSH và tạo cấu hình không hiểu được.
- Cài antivirus rồi an tâm: Quét malware chỉ là một lớp phát hiện, không thay quản lý quyền và cập nhật.
Cấu hình tối thiểu theo loại VPS
VPS chỉ chạy website
Mở SSH giới hạn IP nếu có thể, HTTP/HTTPS; database và Redis chỉ nội bộ. Dùng user riêng cho từng website, backup database thường xuyên và giám sát certificate, disk, web service.
VPS chạy control panel
Bảo vệ cổng panel bằng IP allowlist, VPN hoặc MFA nếu panel hỗ trợ. Cập nhật panel và extension, không mở toàn bộ dải passive FTP hoặc database nếu không cần. Kiểm tra firewall của panel có xung đột với UFW/CSF/firewalld hay không.
VPS chạy Docker
Rà port publish, Docker socket, quyền volume, image provenance và secret. Cập nhật cả host lẫn image/container; host an toàn không bù được image lỗi thời, và ngược lại.
Câu hỏi thường gặp
Có nên đổi cổng SSH mặc định 22 không?
Có thể đổi để giảm bot và log rác, nhưng đây không phải biện pháp bảo mật chính. SSH key, tắt mật khẩu sau khi kiểm tra, firewall/rate limit và cập nhật OpenSSH quan trọng hơn. Nếu đổi cổng, phải mở cổng mới ở cloud firewall và firewall VPS trước khi reload SSH.
Khi nào mới nên tắt đăng nhập root và mật khẩu?
Chỉ sau khi đã tạo user sudo riêng, cài SSH key, đăng nhập thành công trong một phiên mới và xác nhận có console cứu hộ. Giữ phiên cũ cho đến khi kiểm tra xong cấu hình mới.
UFW có chặn được tất cả cổng Docker không?
Không nên mặc định như vậy. Docker quản lý rule mạng riêng và port publish có thể vượt ngoài kỳ vọng của UFW. Hãy kiểm tra docker ps, rule nftables/iptables thực tế và firewall tại nhà cung cấp.
Có cần cài Fail2ban nếu đã dùng SSH key?
SSH key đã giảm mạnh nguy cơ đoán mật khẩu, nhưng Fail2ban hoặc rate limit vẫn hữu ích để giảm bot, log và tải xác thực. Cần cấu hình ngưỡng hợp lý và không xem nó là lớp thay thế cập nhật.
Có nên tắt SELinux hoặc AppArmor không?
Không. Nếu ứng dụng bị chặn, hãy đọc audit log và sửa policy/context. Chỉ dùng permissive hoặc complain mode tạm thời để chẩn đoán rồi đưa hệ thống về enforce.
Snapshot của nhà cung cấp có thay thế backup không?
Không. Snapshot thường cùng tài khoản hoặc hạ tầng với VPS và có thể bị xóa cùng lúc. Cần ít nhất một bản backup ở vị trí độc lập và đã thử restore.
Có nên chạy script hardening tự động trên VPS production không?
Chỉ khi đã đọc từng thay đổi, có snapshot/console cứu hộ và thử trên staging. Script chung có thể đóng nhầm cổng, vô hiệu hóa dịch vụ hoặc áp rule không phù hợp control panel, Docker và IPv6.
Kết luận
Bảo mật VPS cho người mới hiệu quả nhất khi triển khai theo đúng thứ tự. Nếu chỉ làm năm việc trước, hãy chọn: cập nhật hệ điều hành, tạo user sudo riêng, dùng SSH key đã kiểm tra, bật firewall chỉ mở cổng cần thiết và đưa backup ra ngoài VPS.
Sau đó mới bổ sung Fail2ban, cập nhật tự động, AppArmor/SELinux, giám sát và diễn tập khôi phục. Mục tiêu không phải biến VPS thành hệ thống “không thể bị hack”, mà là giảm bề mặt tấn công, phát hiện sớm và có khả năng phục hồi khi sự cố xảy ra.
