Vấn Đề: SSH Server Của Bạn Đang Bị Tấn Công Ngay Lúc Này
Nếu server của bạn đang mở cổng 22 ra internet, nó đang bị quét. Không phải có thể — mà đang xảy ra ngay lúc này. Chạy lệnh này trên bất kỳ Linux server nào có kết nối internet:
sudo journalctl -u ssh --since "1 hour ago" | grep "Failed password" | wc -l
Bạn sẽ thấy hàng chục hoặc hàng trăm lần đăng nhập thất bại. Các bot liên tục quét internet để tìm cổng SSH mở và tấn công bằng credential brute-force. Hai lỗ hổng lớn nhất tiếp tay cho các cuộc tấn công này là: cho phép đăng nhập root trực tiếp qua SSH, và dùng mật khẩu thay vì khóa mã hóa.
Mật khẩu có thể bị brute-force. Tài khoản root, nếu bị xâm phạm, cho phép kẻ tấn công toàn quyền kiểm soát máy của bạn mà không cần thêm bước nào. Kết hợp cả hai và bạn có một server cực kỳ dễ bị tấn công.
Nguyên Nhân: Tại Sao Cấu Hình SSH Mặc Định Lại Nguy Hiểm
Root Login Làm Lộ Tài Khoản Có Đặc Quyền Cao Nhất
Hầu hết các bản phân phối Linux đều cho phép đăng nhập SSH bằng root theo mặc định (hoặc ít nhất là không chặn tường minh). Khi root login được phép, kẻ tấn công chỉ cần một thứ: mật khẩu. Không cần bước leo thang đặc quyền — một lần đoán đúng là họ kiểm soát tất cả.
Hãy chuyển sang dùng user thông thường với sudo. Điều này tạo thêm một lớp bảo vệ: dù kẻ tấn công có được thông tin đăng nhập của user, họ vẫn cần mật khẩu sudo để gây hại thực sự.
Xác Thực Bằng Mật Khẩu Có Thể Bị Đoán
Ngay cả mật khẩu mạnh cũng có thể bị crack nếu có đủ thời gian và tài nguyên tính toán. Xác thực SSH bằng key sử dụng mã hóa bất đối xứng — private key trên máy của bạn, public key trên server. Không có file private key, việc đăng nhập là bất khả thi về mặt toán học bất kể sức mạnh tính toán.
Trên production Ubuntu 22.04 server của tôi, sự khác biệt rất rõ ràng. Trước khi chuyển sang xác thực bằng key, server nhận 200–400 lần thử mật khẩu thất bại mỗi giờ. Mỗi lần thử kích hoạt một SSH handshake đầy đủ và key derivation — tốn CPU thực sự. Sau khi tắt hoàn toàn xác thực bằng mật khẩu, tiếng ồn nền đó biến mất.
Thực Hành: Tăng Cường Bảo Mật SSH Server Từng Bước
Bước 1: Tạo User Không Phải Root Với Quyền Sudo
Trước khi tắt root login, hãy đảm bảo bạn có cách khác để đăng nhập. Tạo một user thông thường nếu bạn chưa có:
# Trên server
sudo adduser deployuser
sudo usermod -aG sudo deployuser
Xác minh user có thể dùng sudo trước khi tiếp tục:
su - deployuser
sudo whoami
# Kết quả phải là: root
Bước 2: Tạo Cặp SSH Key Trên Máy Tính Cá Nhân
Thực hiện bước này trên máy tính cá nhân của bạn, không phải trên server:
ssh-keygen -t ed25519 -C "deployuser@myserver" -f ~/.ssh/myserver_ed25519
Dùng ed25519 thay vì RSA — nhanh hơn, key ngắn hơn (68 ký tự so với 700+ cho RSA-4096), và bảo mật tương đương. Flag -C thêm comment để nhận biết key. Bạn sẽ được hỏi passphrase — hãy đặt một cái. Nó mã hóa file private key trên máy, nên dù ai đó lấy được laptop của bạn, key cũng vô dụng nếu không có passphrase.
Lệnh này tạo ra hai file:
~/.ssh/myserver_ed25519— private key của bạn (không bao giờ chia sẻ cái này)~/.ssh/myserver_ed25519.pub— public key của bạn (cái này sẽ được đặt trên server)
Bước 3: Sao Chép Public Key Lên Server
Cách đơn giản nhất:
ssh-copy-id -i ~/.ssh/myserver_ed25519.pub deployuser@your-server-ip
Nếu ssh-copy-id không có sẵn (thường gặp trên macOS hoặc Windows), hãy làm thủ công:
# Trên server, đăng nhập với tư cách deployuser
mkdir -p ~/.ssh
chmod 700 ~/.ssh
touch ~/.ssh/authorized_keys
chmod 600 ~/.ssh/authorized_keys
# Dán nội dung public key của bạn vào file này
nano ~/.ssh/authorized_keys
Kiểm tra xem đăng nhập bằng key có hoạt động trước khi tắt xác thực bằng mật khẩu:
ssh -i ~/.ssh/myserver_ed25519 deployuser@your-server-ip
Nếu lệnh này thành công mà không hỏi mật khẩu (chỉ hỏi passphrase cho key nếu bạn đã đặt), bạn có thể tiếp tục.
Bước 4: Cấu Hình SSH Để Tắt Root Login và Xác Thực Bằng Mật Khẩu
Chỉnh sửa file cấu hình SSH daemon:
sudo nano /etc/ssh/sshd_config
Tìm và cập nhật các directive sau (thêm vào nếu chưa có):
# Tắt hoàn toàn root login
PermitRootLogin no
# Tắt xác thực bằng mật khẩu
PasswordAuthentication no
# Tắt mật khẩu trống
PermitEmptyPasswords no
# Chỉ cho phép các user cụ thể (tùy chọn nhưng được khuyến nghị)
AllowUsers deployuser
# Tắt challenge-response (bao gồm PAM keyboard-interactive)
# OpenSSH 8.7+ đổi tên thành KbdInteractiveAuthentication — đặt cả hai để chắc ăn
ChallengeResponseAuthentication no
KbdInteractiveAuthentication no
# Keep alive để phát hiện kết nối chết
ClientAliveInterval 300
ClientAliveCountMax 2
Trên Ubuntu 22.04+, có một điểm cần lưu ý. Kiểm tra xem có file override trong thư mục sshd_config.d/ không:
ls /etc/ssh/sshd_config.d/
cat /etc/ssh/sshd_config.d/*.conf 2>/dev/null
Ubuntu 22.04 đi kèm với /etc/ssh/sshd_config.d/50-cloud-init.conf bật lại PasswordAuthentication yes. Hãy override hoặc xóa nó:
sudo sed -i 's/PasswordAuthentication yes/PasswordAuthentication no/' /etc/ssh/sshd_config.d/50-cloud-init.conf
# hoặc chỉ cần xóa file nếu nó chỉ chứa dòng đó
# sudo rm /etc/ssh/sshd_config.d/50-cloud-init.conf
Bước 5: Kiểm Tra Cấu Hình và Reload SSH
Luôn kiểm tra cấu hình trước khi reload — một lỗi cú pháp có thể khóa bạn ra ngoài:
sudo sshd -t
# Không có output = không có lỗi
sudo systemctl reload ssh
# Trên một số distro: sudo systemctl reload sshd
Giữ phiên SSH hiện tại của bạn mở. Mở cửa sổ terminal mới và kiểm tra đăng nhập:
ssh -i ~/.ssh/myserver_ed25519 deployuser@your-server-ip
Cũng hãy xác minh rằng đăng nhập bằng mật khẩu đã bị từ chối:
ssh deployuser@your-server-ip
# Sẽ ngay lập tức nhận được: Permission denied (publickey)
Bước 6: Tùy Chọn — Đổi Cổng SSH Mặc Định
Đổi từ cổng 22 không thêm bảo mật thực sự, nhưng nó giảm đáng kể tiếng ồn trong log. Các bot chủ yếu quét cổng 22; chuyển sang cổng không chuẩn giảm hơn 90% tấn công tự động theo kinh nghiệm của tôi:
# Trong /etc/ssh/sshd_config
Port 2222
Nếu bạn đang dùng UFW:
sudo ufw allow 2222/tcp
sudo ufw delete allow ssh # xóa quy tắc cho cổng 22
sudo ufw status
Kết nối với cổng tùy chỉnh:
ssh -p 2222 -i ~/.ssh/myserver_ed25519 deployuser@your-server-ip
Để tránh gõ cổng mỗi lần, thêm một mục vào file ~/.ssh/config trên máy cục bộ:
Host myserver
HostName your-server-ip
User deployuser
Port 2222
IdentityFile ~/.ssh/myserver_ed25519
Giờ bạn chỉ cần chạy ssh myserver.
Bước 7: Xác Minh Các Thay Đổi Đã Có Hiệu Lực
Kiểm tra cấu hình SSH đang chạy:
sudo sshd -T | grep -E 'permitrootlogin|passwordauthentication|port'
Kết quả mong đợi:
port 2222
permitRootLogin no
passwordauthentication no
Kiểm tra auth log để xác nhận các cuộc tấn công brute-force đang bị từ chối ở giai đoạn key thay vì giai đoạn mật khẩu:
sudo tail -f /var/log/auth.log | grep sshd
Bonus: Quản Lý Nhiều SSH Key Gọn Gàng
Nếu bạn quản lý nhiều server, việc tổ chức key gọn gàng sẽ tránh nhầm lẫn:
# ~/.ssh/config
Host production
HostName 203.0.113.10
User deployuser
Port 2222
IdentityFile ~/.ssh/prod_ed25519
Host staging
HostName 203.0.113.20
User deployuser
Port 22
IdentityFile ~/.ssh/staging_ed25519
Đặt đúng quyền cho file config:
chmod 600 ~/.ssh/config
Những Gì Bạn Đã Đạt Được
Xong. SSH server của bạn giờ yêu cầu khóa mã hóa để đăng nhập. Tấn công brute-force bằng mật khẩu đơn giản là không còn hoạt động nữa. Root login bị chặn, giới hạn thiệt hại nếu bất kỳ tài khoản user nào bị xâm phạm. Đổi cổng nữa và bạn sẽ giảm 90%+ tiếng ồn từ quét tự động.
Ba bước này — user riêng không phải root, xác thực bằng key, không đăng nhập bằng mật khẩu — bao phủ bề mặt tấn công SSH cốt lõi. Thêm quy tắc firewall giới hạn SSH chỉ với các dải IP đã biết khi có thể, và server của bạn sẽ an toàn hơn nhiều so với cấu hình mặc định.
Một điều cuối: lưu trữ bản sao lưu private key an toàn. Mất nó mà không có bản sao nghĩa là bạn bị khóa ra ngoài. Một password manager có secure notes hoặc USB drive được mã hóa hoạt động tốt cho mục đích này.

