Security

Cách bảo mật đăng nhập SSH trên máy chủ Linux

SSH là cửa trước riêng biệt để bạn quản trị máy chủ Linux, và cũng là cổng mà botnet quét trong giờ hành chính. Chỉ cần một VPS mới cài xong, bật lên là trong vòng vài giờ log đã đầy những dòng "Failed password for root from 103.xx.xx.xx". Nếu bạn vẫn đang đăng nhập bằng mật khẩu, nhất là bằng user root, thì không phải nói quá: sớm muộn cũng có người dò ra. Bài này tôi sẽ hướng dẫn bạn bảo mật đăng nhập SSH trên máy chủ Linux, áp dụng được trên Ubuntu 24.04, Debian 12 và AlmaLinux 9, từ tạo key ED25519, tắt root, đổi port, đến chặn brute-force bằng fail2ban hay crowdsec.

Yêu cầu trước khi bắt đầu

  • Một VPS hoặc máy chủ riêng chạy Linux, có quyền root hoặc user có sudo.
  • Kết nối SSH hoạt động bình thường. Nếu bạn chưa có máy chủ, có thể thuê VPS Linux tại thueVPS, hệ thống cài sẵn OS để bắt đầu ngay.
  • Máy tính cá nhân (client) dùng để SSH vào server. Trên Windows dùng PowerShell hoặc Windows Terminal, trên macOS/Linux dùng terminal sẵn có.
  • Lệnh ssh-keygen có sẵn trên client. Hầu hết hệ điều hành hiện tại đều có.

Vì sao SSH key an toàn hơn mật khẩu?

Mật khẩu dù mạnh đến đâu cũng có thể bị dò bằng brute-force, đặc biệt khi bạn không giới hạn số lần thử. SSH key dùng cặp khóa bất đối xứng: khóa riêng (private key) nằm trên máy bạn, khóa công khai (public key) nằm trên server. Máy chủ dùng public key để mã hóa một thử thách, chỉ ai giữ private key mới giải được. Không có gì để dò, không có mật khẩu để đoán, kể cả khi tên user đã biết.

Có hai loại key phổ biến: RSA 4096 bit và ED25519. Tôi khuyên dùng ED25519 vì khóa ngắn, sinh nhanh, độ an toàn cao hơn RSA cùng cấp và được OpenSSH hỗ trợ đầy đủ từ phiên bản 6.5 (năm 2014) nên mọi hệ điều hành hiện tại đều dùng được. Đừng dùng RSA 1024 hay DSA nữa, đó là công nghệ đã lỗi thời.

Bước 1 - Tạo cặp SSH key ED25519 trên máy tính của bạn

Trên terminal của máy tính cá nhân, chạy lệnh sau:

ssh-keygen -t ed25519 -a 100 -C "[email protected]"

Giải thích các tham số:

  • -t ed25519: loại key là ED25519.
  • -a 100: số lần lặp KDF (Key Derivation Function) cho passphrase, giúp chống brute-force khóa riêng nếu bạn đặt passphrase. Giá trị 100 cao hơn mặc định là 16, tốt hơn cho bảo mật.
  • -C: comment, thường là email của bạn để dễ nhận biết key nào của ai.

Lệnh sẽ hỏi nơi lưu key, mặc định là /home/your_user/.ssh/id_ed25519. Nếu bạn đã có key rồi thì nên đặt tên khác như id_ed25519_server1 để không ghi đè. Sau đó nó hỏi passphrase. Đừng bỏ trống. Passphrase để khóa private key lại: nếu ai đó lấy được file key, họ vẫn cần passphrase mới dùng được.

Enter passphrase (empty for no passphrase): 
Enter same passphrase again: 

Kết quả sẽ có hai file: id_ed25519 (khóa riêng, giữ rất cao bí mật) và id_ed25519.pub (khóa công khai, đưa lên server). Kiểm tra bằng lệnh:

ls -la ~/.ssh/
drwx------ 2 user user 4096 Jan 15 10:30 .
drwxr-xr-x 8 user user 4096 Jan 15 10:30 ..
-rw------- 1 user user   411 Jan 15 10:30 id_ed25519
-rw-r--r-- 1 user user   108 Jan 15 10:30 id_ed25519.pub

Quyền của thư mục .ssh phải là 700 và file private key phải là 600, nếu không SSH sẽ từ chối dùng key vì lý do bảo mật. Nếu quyền sai, sửa lại:

chmod 700 ~/.ssh
chmod 600 ~/.ssh/id_ed25519

Bước 2 - Đưa public key lên máy chủ

Có hai cách: dùng lệnh có sẵn hoặc tự tạo file. Cách đơn giản nhất là dùng ssh-copy-id (có sẵn trên Linux và macOS, cài qua OpenSSH client trên Windows):

ssh-copy-id -i ~/.ssh/id_ed25519.pub root@your_server_ip

Nó sẽ hỏi mật khẩu root một lần, sau đó tự ghi public key vào ~/.ssh/authorized_keys trên server. Nếu client không có ssh-copy-id (thường gặp trên Windows), bạn tự làm thủ công. Đọc nội dung public key:

cat ~/.ssh/id_ed25519.pub

Trên server, tạo thư mục và thêm key:

mkdir -p ~/.ssh
chmod 700 ~/.ssh
echo "PASTE_PUBLIC_KEY_CONTENT_HERE" >> ~/.ssh/authorized_keys
chmod 600 ~/.ssh/authorized_keys

Thay PASTE_PUBLIC_KEY_CONTENT_HERE bằng đúng chuỗi key bạn vừa đọc trên máy cá nhân. Sau đó kiểm tra đăng nhập bằng key từ máy tính:

ssh -i ~/.ssh/id_ed25519 root@your_server_ip

Nếu vào được mà không hỏi mật khẩu (chỉ hỏi passphrase của key), xem như bước này thành công. Đừng ngắt kết nối đang mở, hãy giữ nó để phòng khi bước sau có sai sót bạn còn sửa được.

Bước 3 - Tạo user thường trực và cấp quyền sudo

Chạy mọi thứ bằng root là thói quen tệ. Bạn cần một user thường để làm việc hằng ngày, chỉ dùng sudo khi cần. Trên Ubuntu/Debian:

adduser deploy

Lệnh này tạo user deploy và hỏi mật khẩu, cũng như một số thông tin có thể bỏ trống. Cấp quyền sudo:

usermod -aG sudo deploy

Trên AlmaLinux/Rocky Linux 9 dùng wheel thay vì sudo:

useradd -m -G wheel deploy
passwd deploy

Kiểm tra bằng cách đăng nhập với user mới và chạy sudo whoami, kết quả phải trả về root. Bây giờ chép public key của bạn vào user vừa tạo:

ssh-copy-id -i ~/.ssh/id_ed25519.pub deploy@your_server_ip

Từ giờ, đăng nhập chính thức là bằng user này, root không dùng nữa.

Bước 4 - Chỉnh cấu hình sshd để bảo mật SSH triệt để

File cấu hình SSH nằm tại /etc/ssh/sshd_config. Trước khi sửa, hãy backup:

sudo cp /etc/ssh/sshd_config /etc/ssh/sshd_config.bak

Mở file bằng sudo nano /etc/ssh/sshd_config và sửa hoặc thêm các dòng sau, theo khuyến nghị bảo mật SSH của ngành:

# Không cho đăng nhập bằng root
PermitRootLogin no

# Chỉ dùng key, tắt hẳn mật khẩu
PasswordAuthentication no
KbdInteractiveAuthentication no
UsePAM yes

# Giới hạn user được SSH vào
AllowUsers deploy

# Giảm thời gian chờ và số lần thử
LoginGraceTime 30
MaxAuthTries 2
MaxSessions 4

# Không dùng giao thức và thuật toán cũ
Protocol 2
HostKeyAlgorithms ssh-ed25519
PubkeyAcceptedAlgorithms ssh-ed25519
Ciphers [email protected],[email protected]
MACs [email protected],[email protected]

Giải thích vài dòng quan trọng:

  • PermitRootLogin no: chặn đăng nhập root qua SSH. Với VPS, bạn vẫn vào được bằng console tại bảng quản trị nếu cần.
  • PasswordAuthentication no: đây là dòng quyết định. Sau khi bật, mọi thử nghiệm mật khẩu từ bot đều vô nghĩa, vì server chỉ nhận key.
  • AllowUsers deploy: chỉ user nằm trong danh sách mới được SSH, giảm bề mặt tấn công.
  • LoginGraceTime 30: nếu không xác thực xong trong 30 giây, kết nối bị đóng, chống giữ kết nối treo làm đầy kết nối tối đa.

Trước khi khởi động lại dịch vụ, kiểm tra cú pháp file cấu hình:

sudo sshd -t

Nếu không có thông báo gì tức là cú pháp đúng. Nếu có lỗi, nó sẽ chỉ ra dòng cụ thể, bạn sửa lại rồi kiểm tra lần nữa. Khi mọi thứ ổn, khởi động lại:

sudo systemctl restart ssh

Trên Ubuntu/Debian dịch vụ tên ssh, trên AlmaLinux tên sshd. Lưu ý mở một phiên SSH mới bằng user deploy để xác nhận hoạt động trước khi đóng phiên cũ đang mở. Nếu có gì trục trặc, bạn còn phiên cũ để sửa lại.

Bước 5 - Đổi port SSH nếu cần và cấu hình firewall

Đổi port SSH mặc định 22 sang một port khác, ví dụ 2222, là cách làm giảm ngay lượng log quét từ bot, vì phần lớn bot chỉ quét port 22. Trong /etc/ssh/sshd_config, thêm:

Port 2222

Kiểm tra cú pháp và restart lại SSH. Sau đó cập nhật firewall. Trên Ubuntu với UFW:

sudo ufw allow 2222/tcp
sudo ufw allow OpenSSH
sudo ufw enable

Trên AlmaLinux với firewalld:

sudo firewall-cmd --permanent --add-port=2222/tcp
sudo firewall-cmd --permanent --add-service=ssh
sudo firewall-cmd --reload

Lưu ý: nếu bạn đăng nhập bằng port mới, lệnh là ssh -p 2222 deploy@your_server_ip. Đừng quên mở port mới trên firewall trước khi tắt port cũ. Nếu máy chủ của bạn đặt tại Việt Nam với IPv4 riêng, việc đổi port và bật firewall giúp giảm rõ rệt các đợt quét tự động từ nước ngoài. Chi tiết hơn về cách cấu hình từng loại tường lửa, bạn xem thêm bài cấu hình UFW trên Ubuntu hoặc firewalld trên AlmaLinux 9.

Bước 6 - Chặn brute-force bằng fail2ban

Dù đã tắt mật khẩu, fail2ban vẫn đáng cài để chặn các hành vi quét và dò port. Fail2ban giám sát log, đếm số lần thất bại, rồi chặn IP bằng firewall trong một khoảng thời gian. Cài trên Ubuntu/Debian:

sudo apt update
sudo apt install fail2ban -y

Trên AlmaLinux:

sudo dnf install epel-release -y
sudo dnf install fail2ban -y

Tạo file cấu hình riêng để tránh bị ghi đè khi cập nhật:

sudo nano /etc/fail2ban/jail.local

Nội dung mẫu:

[sshd]
enabled = true
port = 2222
filter = sshd
logpath = /var/log/auth.log
maxretry = 3
bantime = 3600
findtime = 600

Nếu dùng AlmaLinux, đường dẫn log là /var/log/secure thay vì /var/log/auth.log. Khởi động và kích hoạt dịch vụ:

sudo systemctl enable --now fail2ban
sudo systemctl status fail2ban

Kiểm tra các IP đang bị chặn:

sudo fail2ban-client status sshd

Bạn sẽ thấy số IP bị chặn và danh sách. Nếu muốn bỏ chặn một IP, dùng sudo fail2ban-client set sshd unbanip IP_ADDRESS. Có một hệ thống tương tự nhưng mạnh hơn là CrowdSec, dùng chung cơ sở dữ liệu IP độc hại trên toàn cầu. Xem thêm bài cài đặt CrowdSec chống tấn công tự động để biết cách triển khai.

Các lỗi thường gặp và cách xử lý

Sau khi sửa sshd_config, mất kết nối SSH

Nếu bạn đã restart SSH và không vào được nữa, kiểm tra cú pháp cấu hình trước khi restart: sudo sshd -t. Lỗi này thường do sai cú pháp hoặc quên mở port mới trên firewall. Với VPS, hãy dùng console qua bảng quản trị (thueVPS có sẵn tính năng xem console trên web) để vào sửa lại file /etc/ssh/sshd_configsudo systemctl restart ssh.

Permission denied khi đăng nhập bằng key

Nguyên nhân gần như luôn là quyền file sai hoặc key không đúng. Kiểm tra trên server:

ls -la ~/.ssh/
chmod 700 ~/.ssh
chmod 600 ~/.ssh/authorized_keys

Đồng thời xem log SSH để biết lý do chính xác:

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

Trên AlmaLinux dùng /var/log/secure. Log sẽ nói rõ key bị từ chối vì lý do gì, ví dụ quyền sai của thư mục home.

Fail2ban chặn nhầm IP của chính bạn

Nếu bạn gõ sai mật khẩu vài lần trước khi chuyển sang key, fail2ban có thể chặn luôn IP nhà bạn. Cách nhanh nhất là dùng console của VPS để gỡ chặn: sudo fail2ban-client set sshd unbanip YOUR_IP. Chính vì vậy, hãy thêm IP tin cậy vào ignoreip trong jail.local:

[DEFAULT]
ignoreip = 127.0.0.1/8 YOUR_HOME_IP

Kết luận và kiểm tra tổng thể

Bảo mật SSH không phải là làm một lần rồi thôi. Sau khi hoàn tất các bước trên, hãy kiểm tra lại toàn bộ với một góc nhìn khác: tắt kết nối hiện tại, thử đăng nhập từ máy khác bằng mật khẩu xem có bị từ chối không, thử từ một IP lạ xem fail2ban có chặn không. Với một VPS Linux dùng để chạy website, ứng dụng, hay automation, thói quen này nên lặp lại mỗi khi bạn tạo máy chủ mới. Nếu cần máy chủ có sẵn hạ tầng ổn định tại Việt Nam, bạn có thể tham khảo dịch vụ thuê VPS Linux NVMe tại thueVPS, hệ thống có bảng điều khiển để cài lại OS và xem console ngay khi cần.

Câu hỏi thường gặp

Có nên tắt hẳn đăng nhập bằng mật khẩu không?

Có, sau khi bạn đã chắc chắn key hoạt động trên mọi máy cần dùng. Nếu chỉ có một máy tính thường dùng, hãy đặt PasswordAuthentication no. Khi cần truy cập từ máy lạ, bạn có thể bật lại tạm thời rồi tắt, hoặc dùng console của nhà cung cấp.

Mất file private key thì làm thế nào?

Bạn sẽ không vào được server bằng SSH, nhưng vẫn vào được qua console web của nhà cung cấp VPS. Từ đó tạo cặp key mới và cập nhật vào ~/.ssh/authorized_keys của user. Nếu bạn đã tắt mật khẩu thì console là cửa thoát hiểm riêng biệt, vì vậy hãy nhớ nó luôn hoạt động.

Đổi port SSH có thực sự cần thiết không?

Không bắt buộc nếu bạn đã tắt mật khẩu và dùng key, nhưng nên làm vì nó giảm ngay lượng log nhiễu từ bot, giúp bạn đọc log dễ hơn và giảm tải nhỏ cho CPU. Với các hệ thống quan trọng, đổi port kết hợp AllowUsers là chuẩn nên làm.

Fail2ban và CrowdSec khác nhau thế nào?

Fail2ban chỉ chặn IP dựa trên log của máy bạn, còn CrowdSec chia sẻ danh sách IP độc hại với cộng đồng toàn cầu nên chặn được nhiều hơn từ ngày đầu. Bạn có thể dùng cả hai, hoặc chọn một. CrowdSec tốn tài nguyên hơn một chút nhưng đáng cân nhắc với máy chủ công khai.

Bảo mật SSH có cần thiết với VPS trong nước không?

Có. Máy chủ đặt ở Việt Nam vẫn bị botnet quét như thường, thậm chí còn bị nhắm nhiều vì dân số internet lớn. Dùng VPS Linux có IPv4 Việt Nam không làm giảm nguy cơ bị dò mật khẩu, nên các bước trên vẫn phải làm đầy đủ.

Bài viết liên quan

Lưu ý: Bài viết mang tính tham khảo, tổng hợp kiến thức chung. Mỗi hệ thống, hạ tầng và nhu cầu có đặc thù riêng, nên kiểm thử trong môi trường an toàn và tham vấn kỹ sư trước khi triển khai thực tế.