Những việc cần làm sau khi cài Ubuntu Server 22.04 để tránh thảm họa lúc 2 giờ sáng

Ubuntu tutorial - IT technology blog
Ubuntu tutorial - IT technology blog

Server vừa lên, chưa làm gì đã dính vấn đề

Hồi mới chuyển từ CentOS sang Ubuntu, mình có thói quen cài xong là deploy code luôn — không quan tâm đến bất kỳ bước cấu hình nào. Kết quả là sau 3 ngày, server bị brute-force SSH, log đầy ắp thông báo lỗi, và cái swap chưa có khiến một tiến trình Node.js bị OOM killer xử lý lúc 2 giờ sáng.

Mất khoảng 1 tuần để quen với hệ thống package management của Ubuntu sau khi rời CentOS. Nhưng cái đau hơn là mất cả buổi sáng để restore lại service từ backup — vì những lỗi hoàn toàn có thể tránh được nếu mình dành 20 phút cấu hình ngay từ đầu.

Bài này là checklist mình chạy qua sau mỗi lần cài Ubuntu Server 22.04. Không có gì cao siêu, toàn thứ mình đã trả học phí bằng production incident cả.

Tại sao server mới cài lại dễ gặp sự cố?

Ubuntu Server 22.04 fresh install trông có vẻ ổn, nhưng thực ra có vài điểm khá nguy hiểm nếu để nguyên:

  • SSH cho phép đăng nhập bằng password: Bot scanner quét toàn bộ internet liên tục. Server mới public IP thường bị probe trong vòng vài phút — thử hàng nghìn tổ hợp username/password như root/123456, admin/admin, ubuntu/ubuntu.
  • UFW cài sẵn nhưng chưa bật: Tất cả cổng đều tiếp cận được từ ngoài. Mặc định.
  • Package có thể đã cũ vài tháng: Bản ISO build từ lúc release, trong đó có thể có lỗ hổng đã được vá từ lâu.
  • Không có swap: Cloud VPS thường bỏ qua swap partition. RAM đầy là OOM killer vào, không hỏi han gì.
  • Timezone mặc định là UTC: Log ghi 03:00 trong khi thực tế là 10 giờ sáng theo giờ Việt Nam — debug mệt lắm.

Các bước cần thực hiện — theo thứ tự ưu tiên

1. Cập nhật hệ thống ngay lập tức

Trước khi làm bất cứ thứ gì khác. Deploy trước khi update là rủi ro không đáng:

sudo apt update && sudo apt upgrade -y
sudo apt autoremove -y

Nếu kernel được cập nhật, reboot luôn:

sudo reboot

2. Tạo user riêng, không dùng root

Đăng nhập root trực tiếp là thói quen xấu — một lệnh nhầm là hỏng cả hệ thống, không có gì chặn lại. Tạo user mới với quyền sudo:

adduser deploy
usermod -aG sudo deploy

Đăng nhập bằng user mới để test quyền trước khi khóa root.

3. Cấu hình SSH key và khóa password login

Bot brute-force thử password — tắt password login là tắt luôn vector tấn công đó. Trên máy local:

# Tạo SSH key nếu chưa có
ssh-keygen -t ed25519 -C "[email protected]"

# Copy public key lên server
ssh-copy-id deploy@your-server-ip

Sau khi đăng nhập bằng key thành công, chỉnh /etc/ssh/sshd_config:

sudo nano /etc/ssh/sshd_config

Sửa ba dòng này:

PermitRootLogin no
PasswordAuthentication no
PubkeyAuthentication yes

Khởi động lại SSH:

sudo systemctl restart sshd

Quan trọng: Giữ nguyên session SSH cũ khi mở session mới để test. Bị khóa ra ngoài thì vẫn có session cũ để vào sửa.

4. Bật UFW firewall

Chỉ mở cổng nào thực sự cần, đóng hết phần còn lại:

# Cho phép SSH trước — bắt buộc, không thì tự khóa mình ra
sudo ufw allow ssh

# Nếu chạy web server
sudo ufw allow 80/tcp
sudo ufw allow 443/tcp

# Bật firewall
sudo ufw enable

# Xem kết quả
sudo ufw status verbose

Đang chạy SSH trên cổng tùy chỉnh, ví dụ 2222? Thêm dòng này trước khi enable:

sudo ufw allow 2222/tcp

5. Cấu hình timezone

Server deploy cho người dùng Việt Nam thì set giờ Việt Nam — đọc log mới không bị rối:

sudo timedatectl set-timezone Asia/Ho_Chi_Minh

# Server ở Nhật thì dùng cái này
sudo timedatectl set-timezone Asia/Tokyo

# Kiểm tra
timedatectl status

6. Tạo swap file

Cái sự cố OOM lúc 2 giờ sáng mình nói ở đầu bài? Nguyên nhân là không có swap. Node.js tiến trình nào dùng nhiều RAM một chút là bị kill ngay, không có buffer. Cloud VPS 1-2GB RAM thì tạo swap 2GB là hợp lý:

sudo fallocate -l 2G /swapfile
sudo chmod 600 /swapfile
sudo mkswap /swapfile
sudo swapon /swapfile

# Kiểm tra
free -h

# Tự động mount khi reboot
echo '/swapfile none swap sw 0 0' | sudo tee -a /etc/fstab

Mặc định Linux dùng swap khá sớm (swappiness=60). Server production nên để 10 — chỉ dùng swap khi thực sự cần:

echo 'vm.swappiness=10' | sudo tee -a /etc/sysctl.conf
sudo sysctl -p

7. Cài đặt các gói cơ bản

Mấy tool này không phải lúc nào cũng cần ngay, nhưng khi cần debug mà thiếu thì khó chịu lắm:

sudo apt install -y \
  curl wget git vim htop \
  net-tools dnsutils \
  unzip build-essential \
  fail2ban

8. Cấu hình Fail2ban

Đã tắt password login rồi nhưng bot vẫn thử kết nối liên tục, spam log cho đẹp. Fail2ban tự block IP sau N lần thất bại:

sudo systemctl enable fail2ban
sudo systemctl start fail2ban

# Xem trạng thái — bao nhiêu IP đã bị block
sudo fail2ban-client status sshd

9. Bật automatic security updates

Không ai nhớ vào update server thủ công mỗi tuần. Để nó tự làm:

sudo apt install -y unattended-upgrades
sudo dpkg-reconfigure --priority=low unattended-upgrades

Chọn “Yes” khi được hỏi. Chỉ security patch được áp dụng tự động — không phải toàn bộ package, nên không lo bị update bể ứng dụng.

10. Kiểm tra service nào đang chạy

Bước cuối: rà soát lại xem có gì đang expose ra ngoài không cần thiết không:

# Cổng nào đang lắng nghe?
sudo ss -tlnp

# Service nào đang chạy?
sudo systemctl list-units --type=service --state=running

Tắt những thứ không cần:

sudo systemctl disable --now snapd      # Không dùng snap thì tắt
sudo systemctl disable --now bluetooth  # Server không cần bluetooth

Gom lại thành một script cho lần sau

Làm đi làm lại 4-5 lần thì mình viết luôn script. Chạy một lệnh là xong 6 bước đầu, khỏi nhớ từng command:

#!/bin/bash
# bootstrap-ubuntu.sh — Chạy ngay sau khi cài Ubuntu Server 22.04
set -e

echo "[1/6] Updating system..."
apt update && apt upgrade -y && apt autoremove -y

echo "[2/6] Installing essential packages..."
apt install -y curl wget git vim htop net-tools dnsutils unzip fail2ban

echo "[3/6] Setting up swap..."
if [ ! -f /swapfile ]; then
  fallocate -l 2G /swapfile
  chmod 600 /swapfile
  mkswap /swapfile
  swapon /swapfile
  echo '/swapfile none swap sw 0 0' >> /etc/fstab
  echo 'vm.swappiness=10' >> /etc/sysctl.conf
fi

echo "[4/6] Configuring UFW..."
ufw allow ssh
ufw --force enable

echo "[5/6] Enabling Fail2ban..."
systemctl enable fail2ban
systemctl start fail2ban

echo "[6/6] Enabling auto security updates..."
apt install -y unattended-upgrades
dpkg-reconfigure --priority=low unattended-upgrades

echo "Done! Don't forget to:"
echo "  - Create a non-root user"
echo "  - Set up SSH key auth and disable password login"
echo "  - Set correct timezone: timedatectl set-timezone Asia/Ho_Chi_Minh"

Chạy với quyền root:

chmod +x bootstrap-ubuntu.sh
sudo ./bootstrap-ubuntu.sh

Checklist kiểm tra nhanh trước khi deploy

Xong hết rồi, chạy nhanh mấy lệnh này để chắc chắn không sót gì:

# UFW có bật chưa?
sudo ufw status

# SSH đã khóa password chưa?
grep -E 'PermitRootLogin|PasswordAuthentication' /etc/ssh/sshd_config

# Swap có không?
free -h

# Timezone đúng chưa?
date

# Fail2ban đang chạy?
sudo fail2ban-client status

Tổng cộng mất khoảng 15-20 phút. Lần đầu có thể lâu hơn vì đọc output từng bước — lần thứ hai thì chạy script là xong. Còn restore từ backup sau sự cố thì mình đã mất gần 4 tiếng, chưa tính nửa ngày sau debug để chắc không còn lỗi nào.

Share: