Hardening SSH server Linux là một trong những việc đầu tiên SysAdmin nên làm trước khi đưa máy chủ ra Internet. SSH là cửa ngõ quản trị production: chỉ cần cấu hình lỏng, mật khẩu yếu hoặc không có lớp chống brute force, toàn bộ hạ tầng phía sau có thể bị đe dọa.
Bài này đi theo hướng thực chiến: có bối cảnh lab/production, giải thích vì sao cần làm, lệnh cấu hình cụ thể, output mẫu, lỗi thường gặp, checklist nghiệm thu và bài tập cuối bài. Mục tiêu không phải “tắt hết cho an toàn”, mà là tạo một cấu hình SSH cân bằng giữa bảo mật, khả năng vận hành và khả năng khôi phục khi có sự cố.
1. Bối cảnh production: vì sao cần hardening SSH server Linux?
Trong môi trường doanh nghiệp nhỏ, VPS, máy chủ web hoặc node chạy dịch vụ nội bộ, SSH thường được mở để quản trị từ xa. Các bot quét Internet liên tục thử đăng nhập bằng tài khoản phổ biến như root, admin, ubuntu. Nếu server vẫn cho đăng nhập bằng mật khẩu, không giới hạn IP, không có rate limit và không có audit log, rủi ro tăng rất nhanh.
Một quy trình hardening SSH server Linux tốt thường giải quyết 5 nhóm vấn đề:
- Giảm bề mặt tấn công: không cho root login trực tiếp, hạn chế user được phép SSH.
- Tăng độ mạnh xác thực: ưu tiên SSH key, tắt password nếu có thể.
- Giảm brute force: firewall, Fail2ban hoặc cơ chế rate limit tương đương.
- Dễ audit: log rõ ai đăng nhập, từ đâu, thời điểm nào.
- Không tự khóa chính mình: luôn có rollback, console hoặc session dự phòng.
2. Chuẩn bị an toàn trước khi sửa cấu hình SSH
Trước khi đụng vào /etc/ssh/sshd_config, hãy mở sẵn một phiên SSH đang hoạt động và không đóng phiên đó cho tới khi kiểm thử xong. Nếu là VPS/cloud, cần chắc chắn bạn có console web hoặc serial console để cứu máy nếu cấu hình sai.
2.1. Sao lưu cấu hình hiện tại
sudo cp -a /etc/ssh/sshd_config /etc/ssh/sshd_config.$(date +%F-%H%M%S).bak
sudo sshd -t
Giải thích:
cp -agiữ nguyên quyền file và metadata.sshd -tkiểm tra syntax trước khi reload dịch vụ.
Output tốt là không in gì ra màn hình. Nếu có lỗi, ví dụ:
/etc/ssh/sshd_config line 98: Bad configuration option: PasswordAuthenticatio
thì nghĩa là có typo hoặc option không phù hợp phiên bản OpenSSH.
2.2. Kiểm tra phiên bản OpenSSH và distro
ssh -V
sshd -V 2>&1 | head -1
cat /etc/os-release
Việc này giúp tránh copy cấu hình không tương thích. Một số option mới có thể chưa có trên distro cũ. Tài liệu chính thống nên tham khảo là OpenSSH sshd_config manual và tài liệu bảo mật của distro bạn dùng.
3. Tạo user quản trị và SSH key đúng cách
Không nên vận hành production bằng root login trực tiếp. Tạo user quản trị riêng, cấp sudo có kiểm soát, sau đó dùng SSH key để đăng nhập.
3.1. Tạo user quản trị
sudo adduser opsadmin
sudo usermod -aG sudo opsadmin
id opsadmin
Output mẫu:
uid=1001(opsadmin) gid=1001(opsadmin) groups=1001(opsadmin),27(sudo)
Trên RHEL/CentOS/Rocky Linux, nhóm quản trị thường là wheel thay vì sudo:
sudo usermod -aG wheel opsadmin
3.2. Sinh SSH key trên máy cá nhân
ssh-keygen -t ed25519 -a 100 -C "opsadmin@production" -f ~/.ssh/opsadmin_prod_ed25519
ed25519 gọn, nhanh và an toàn cho đa số trường hợp hiện nay. Tham số -a 100 tăng số vòng KDF để bảo vệ private key tốt hơn nếu file bị lộ. Luôn đặt passphrase cho private key, đặc biệt với server production.
3.3. Cài public key lên server
ssh-copy-id -i ~/.ssh/opsadmin_prod_ed25519.pub opsadmin@SERVER_IP
Nếu chưa dùng được ssh-copy-id, có thể làm thủ công:
mkdir -p ~/.ssh
chmod 700 ~/.ssh
nano ~/.ssh/authorized_keys
chmod 600 ~/.ssh/authorized_keys
Sau đó kiểm thử bằng một terminal mới:
ssh -i ~/.ssh/opsadmin_prod_ed25519 opsadmin@SERVER_IP
sudo -v
4. Cấu hình sshd_config an toàn nhưng vẫn vận hành được
Mở file cấu hình:
sudo nano /etc/ssh/sshd_config
Có thể bắt đầu với block cấu hình sau. Hãy điều chỉnh AllowUsers và port theo môi trường thực tế.
Port 22
Protocol 2
PermitRootLogin no
PasswordAuthentication no
KbdInteractiveAuthentication no
PubkeyAuthentication yes
AuthenticationMethods publickey
PermitEmptyPasswords no
X11Forwarding no
AllowTcpForwarding no
ClientAliveInterval 300
ClientAliveCountMax 2
MaxAuthTries 3
LoginGraceTime 30
AllowUsers opsadmin
4.1. Giải thích các option quan trọng
PermitRootLogin no: chặn đăng nhập root trực tiếp. Khi cần quyền cao, user quản trị dùngsudo.PasswordAuthentication no: tắt đăng nhập bằng mật khẩu, giảm đáng kể brute force.AuthenticationMethods publickey: yêu cầu xác thực bằng public key.MaxAuthTries 3: giảm số lần thử sai trong một kết nối.AllowUsers opsadmin: chỉ user được liệt kê mới được SSH.X11Forwarding novàAllowTcpForwarding no: tắt tính năng không cần thiết nếu bạn không dùng tunnel.
Lưu ý: nếu hệ thống cần SFTP, Git over SSH, SSH tunnel hoặc automation từ CI/CD, đừng tắt vội các option liên quan khi chưa kiểm tra dependency.
5. Kiểm tra syntax và reload SSH không làm rớt phiên hiện tại
sudo sshd -t
sudo systemctl reload ssh
# hoặc trên một số distro:
sudo systemctl reload sshd
Nếu reload không lỗi, mở terminal mới và thử đăng nhập:
ssh -i ~/.ssh/opsadmin_prod_ed25519 opsadmin@SERVER_IP
Sau đó thử xác nhận password login đã bị chặn:
ssh -o PreferredAuthentications=password -o PubkeyAuthentication=no opsadmin@SERVER_IP
Output mong muốn:
opsadmin@SERVER_IP: Permission denied (publickey).
6. Firewall: chỉ mở SSH theo nhu cầu thật
Hardening SSH không chỉ nằm trong sshd_config. Nếu IP quản trị cố định, nên giới hạn firewall chỉ cho phép IP đó truy cập SSH.
6.1. UFW trên Ubuntu/Debian
sudo ufw allow from YOUR_OFFICE_IP to any port 22 proto tcp
sudo ufw deny 22/tcp
sudo ufw status numbered
Nếu chưa thể cố định IP, ít nhất hãy bật UFW và chỉ mở các port cần thiết:
sudo ufw allow 22/tcp
sudo ufw allow 80/tcp
sudo ufw allow 443/tcp
sudo ufw enable
sudo ufw status verbose
6.2. firewalld trên RHEL/Rocky/AlmaLinux
sudo firewall-cmd --permanent --add-service=ssh
sudo firewall-cmd --reload
sudo firewall-cmd --list-all
Nếu cần giới hạn IP, dùng rich rule:
sudo firewall-cmd --permanent --add-rich-rule='rule family="ipv4" source address="YOUR_OFFICE_IP/32" service name="ssh" accept'
sudo firewall-cmd --permanent --remove-service=ssh
sudo firewall-cmd --reload
7. Fail2ban: giảm brute force khi chưa giới hạn được IP
Fail2ban đọc log đăng nhập thất bại và tự động ban IP vi phạm trong một khoảng thời gian. Đây không phải thay thế cho SSH key và firewall, nhưng là lớp phòng thủ hữu ích.
sudo apt update
sudo apt install -y fail2ban
sudo systemctl enable --now fail2ban
Tạo file jail riêng:
sudo nano /etc/fail2ban/jail.d/sshd.local
Nội dung mẫu:
[sshd]
enabled = true
port = ssh
filter = sshd
logpath = %(sshd_log)s
maxretry = 5
findtime = 10m
bantime = 1h
Khởi động lại và kiểm tra:
sudo systemctl restart fail2ban
sudo fail2ban-client status sshd
Output mẫu:
Status for the jail: sshd
|- Filter
| |- Currently failed: 0
| `- Total failed: 12
`- Actions
|- Currently banned: 1
`- Banned IP list: 203.0.113.10
8. Đổi port SSH có giúp bảo mật hơn không?
Đổi port từ 22 sang port khác có thể giảm log rác từ bot quét mặc định, nhưng không nên xem là biện pháp bảo mật chính. Nếu đổi port, vẫn phải dùng SSH key, tắt root login, firewall và monitoring. Với production có nhiều automation, đổi port còn có thể gây lỗi pipeline hoặc script vận hành.
Nếu quyết định đổi port, ví dụ sang 2222:
Port 2222
Đừng quên mở firewall trước khi reload SSH:
sudo ufw allow 2222/tcp
sudo sshd -t
sudo systemctl reload ssh
ssh -p 2222 -i ~/.ssh/opsadmin_prod_ed25519 opsadmin@SERVER_IP
9. Audit log: biết ai đã vào server và khi nào
Trên Ubuntu/Debian, log SSH thường nằm trong /var/log/auth.log. Trên RHEL/Rocky, thường là /var/log/secure.
sudo grep "Accepted publickey" /var/log/auth.log | tail -20
sudo grep "Failed password" /var/log/auth.log | tail -20
journalctl -u ssh --since "1 hour ago"
Output mẫu:
Accepted publickey for opsadmin from 198.51.100.20 port 54822 ssh2: ED25519 SHA256:...
Với server quan trọng, nên đẩy log về hệ thống tập trung như ELK, Loki, Graylog hoặc SIEM để tránh tình huống attacker xóa log cục bộ.
10. Troubleshooting các lỗi thường gặp sau khi hardening SSH
10.1. Lỗi Permission denied (publickey)
Nguyên nhân phổ biến:
- Public key chưa nằm đúng trong
~/.ssh/authorized_keys. - Quyền thư mục sai:
~/.sshkhông phải 700 hoặcauthorized_keyskhông phải 600. - Dùng nhầm private key ở máy client.
- User không nằm trong
AllowUsers.
Kiểm tra nhanh:
ssh -vvv -i ~/.ssh/opsadmin_prod_ed25519 opsadmin@SERVER_IP
sudo tail -f /var/log/auth.log
10.2. Reload SSH báo lỗi cấu hình
Luôn chạy:
sudo sshd -t
Nếu lỗi option, kiểm tra lại chính tả và phiên bản OpenSSH. Có distro dùng KbdInteractiveAuthentication, có nơi vẫn thấy ChallengeResponseAuthentication trong cấu hình cũ.
10.3. Tự khóa khỏi server
Nếu còn phiên SSH cũ, sửa lại file từ phiên đó và reload. Nếu mất toàn bộ SSH, dùng console của nhà cung cấp cloud/VPS để đăng nhập, restore file backup:
sudo cp -a /etc/ssh/sshd_config.2026-05-30-1900.bak /etc/ssh/sshd_config
sudo sshd -t
sudo systemctl reload ssh
11. Checklist nghiệm thu sau hardening SSH server Linux
- Đã backup
/etc/ssh/sshd_config. sshd -tkhông báo lỗi.- User quản trị riêng đăng nhập được bằng SSH key.
- Root login trực tiếp bị chặn.
- Password login bị chặn hoặc chỉ được bật có kiểm soát trong giai đoạn chuyển đổi.
- Firewall chỉ mở SSH theo nhu cầu thật.
- Fail2ban hoặc cơ chế rate limit tương đương hoạt động.
- Log đăng nhập thành công/thất bại đọc được.
- Có phương án cứu hộ: console, snapshot, backup config.
- Automation, backup job, SFTP, Git deploy vẫn hoạt động sau thay đổi.
12. Lab thực hành: dựng một SSH baseline cho VPS mới
Bài tập đề xuất:
- Tạo một VPS test hoặc máy ảo Linux.
- Tạo user
opsadmin, cấp sudo. - Sinh SSH key ed25519 và đăng nhập bằng key.
- Tắt root login và password login.
- Bật UFW/firewalld chỉ mở SSH, HTTP, HTTPS.
- Cài Fail2ban và kiểm tra jail
sshd. - Viết lại checklist nghiệm thu riêng cho môi trường của bạn.
Kết luận
Hardening SSH server Linux không phải một lần chỉnh file rồi quên. Đây là baseline vận hành cần được kiểm tra định kỳ, đặc biệt sau khi thêm user mới, đổi IP quản trị, thay đổi pipeline deploy hoặc chuyển server sang môi trường cloud khác. Nếu làm đúng, bạn giảm đáng kể rủi ro brute force, hạn chế thiệt hại khi credential bị lộ và vẫn giữ được khả năng vận hành an toàn trong production.
