Setup SSH an toàn cho VPS CentOS: đổi cổng, tắt root, bật SSH key, Fail2Ban

Cứng hóa OpenSSH trên VPS CentOS theo chuẩn production: SSH key, đổi cổng kèm SELinux và firewall, tắt root/password, Fail2Ban, kiểm tra, giám sát và quy trình rollback an toàn.

NHT
· 7 phút đọc
Setup SSH an toàn cho VPS CentOS: đổi cổng, tắt root, bật SSH key, Fail2Ban

TL;DR: Quy trình harden OpenSSH cho VPS CentOS, có đường lui an toàn. Tạo user sudo + SSH key, bật Fail2Ban, đổi port kèm SELinux + firewall, vô hiệu root/password, kiểm tra bằng sshd -t và xác thực lại từ phiên mới trước khi gỡ port 22. Luôn giữ 1 phiên SSH/console mở để rollback.

Điều kiện tiên quyết, môi trường tham chiếu và cảnh báo rủi ro

  • Yêu cầu: 1 phiên SSH/console đang mở (VNC/Serial console của nhà cung cấp) để còn hoàn tác khi cấu hình sai.
  • Tài khoản có sudo hoặc root; khuyến nghị tạo user thường thuộc nhóm wheel.
  • Máy chủ CentOS (tham chiếu: CentOS 7, OpenSSH server mặc định). Trên CentOS 8/Stream thay yum bằng dnf; gói semanage là policycoreutils-python-utils.
  • Cảnh báo: Thao tác với sshd_config, firewall, SELinux có thể làm mất kết nối từ xa. Luôn sao lưu file cấu hình và kiểm tra cú pháp trước khi reload.
  • Cập nhật: 2026-08. Lưu ý CentOS Linux 7 đã EOL; cân nhắc kế hoạch nâng cấp hệ điều hành cho môi trường production.

Checklist nhanh trước khi bắt đầu

  • Đang có 1 phiên SSH/console mở.
  • Có user sudo hoạt động; đã kiểm tra sudo -v.
  • Sao lưu /etc/ssh/sshd_config.
  • Biết IP hoặc domain của máy chủ, và đang dùng firewalld (ưu tiên) hoặc iptables.

1) Chuẩn bị user sudo và console fallback

Tạo user không phải root, thêm vào nhóm wheel để dùng sudo:

useradd -m -s /bin/bash deployer
passwd deployer
usermod -aG wheel deployer

Kiểm tra quyền sudo:

su - deployer
sudo -v

Mẹo an toàn: giữ nguyên phiên SSH cũ (root hoặc user cũ) và mở sẵn console của VPS để có đường lui nếu bị khoá.

2) Cài và cấu hình Fail2Ban cho sshd

Fail2Ban tự động chặn IP brute-force dựa trên log.

yum install -y epel-release
yum install -y fail2ban

Tạo cấu hình local tối thiểu cho jail sshd (ưu tiên firewalld):

# /etc/fail2ban/jail.local
[sshd]
enabled = true
port = ssh
logpath = /var/log/secure
maxretry = 5
findtime = 10m
bantime = 1h
banaction = firewallcmd-rich-rules
systemctl enable --now fail2ban
fail2ban-client status
fail2ban-client status sshd

Kiểm chứng: thử nhập sai mật khẩu 5 lần trong vòng 10 phút từ một IP khác, sau đó chạy fail2ban-client status sshd để xem IP bị ban.

3) Bật SSH key và kiểm tra phân quyền thư mục

Tạo cặp khóa trên máy cá nhân (khuyến nghị ed25519):

ssh-keygen -t ed25519 -C "your_email@example.com"

Chép khóa công khai lên máy chủ (đang dùng port 22 mặc định):

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

Nếu phải chép tay, đảm bảo phân quyền đúng để sshd không bỏ qua key:

su - deployer
mkdir -p ~/.ssh
chmod 700 ~/.ssh
cat <<'EOF' >> ~/.ssh/authorized_keys
ssh-ed25519 AAAAC3NzaC1lZDI1NTE5AAAAI... your_email@example.com
EOF
chmod 600 ~/.ssh/authorized_keys
chown -R deployer:deployer ~/.ssh

Thử đăng nhập lại bằng key:

ssh deployer@your_server_ip

4) Đổi cổng SSH an toàn (kèm SELinux + firewall) và giữ đường lui

Sao lưu cấu hình trước khi chỉnh:

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

Chỉnh cổng mới (ví dụ 2222) và tạm thời giữ cả 22 và 2222 để chuyển dần:

sed -i 's/^#\?Port .*/Port 22\nPort 2222/' /etc/ssh/sshd_config || echo -e "Port 22\nPort 2222" >> /etc/ssh/sshd_config

Nếu SELinux đang Enforcing, cần gán nhãn cổng mới cho sshd:

yum install -y policycoreutils-python || true
semanage port -a -t ssh_port_t -p tcp 2222 2>/dev/null || semanage port -m -t ssh_port_t -p tcp 2222
semanage port -l | grep ssh_port_t

Mở cổng mới trên firewalld và tải lại:

firewall-cmd --permanent --add-port=2222/tcp
firewall-cmd --reload

Kiểm tra cú pháp trước khi áp dụng và chỉ reload (reload không ngắt phiên hiện tại):

sshd -t
systemctl reload sshd
ss -tnlp | grep :2222 || true

Thử kết nối ở một phiên/terminal mới qua cổng 2222:

ssh -p 2222 deployer@your_server_ip

Nếu phiên mới vào được và hoạt động ổn định, mới tiến hành gỡ cổng 22 khỏi sshd và firewall:

# Gỡ Port 22 trong sshd_config (giữ lại Port 2222)
sed -i '/^Port 22$/d' /etc/ssh/sshd_config
sshd -t && systemctl reload sshd

# Gỡ cổng 22 khỏi firewall
firewall-cmd --permanent --remove-port=22/tcp
firewall-cmd --reload

5) Vô hiệu root login và tắt password sau khi đã xác thực bằng key

Chỉ làm bước này khi đã đăng nhập ổn định bằng SSH key.

# Chỉnh sửa sshd_config
sed -i 's/^#\?PermitRootLogin.*/PermitRootLogin no/' /etc/ssh/sshd_config
sed -i 's/^#\?PasswordAuthentication.*/PasswordAuthentication no/' /etc/ssh/sshd_config
sed -i 's/^#\?PubkeyAuthentication.*/PubkeyAuthentication yes/' /etc/ssh/sshd_config

# Một số tuỳ chọn harden thêm (khuyến nghị an toàn chung)
awk 'END{print "ChallengeResponseAuthentication no\nMaxAuthTries 3\nLoginGraceTime 30\nX11Forwarding no\nClientAliveInterval 300\nClientAliveCountMax 2"}' /dev/null >> /etc/ssh/sshd_config

# Kiểm tra và áp dụng
sshd -t && systemctl reload sshd

Kiểm chứng: mở phiên SSH mới (không dùng phiên đang mở) để xác nhận đăng nhập bằng key hoạt động; thử đăng nhập bằng mật khẩu sẽ bị từ chối.

6) Chặn nhanh IP/dải IP đang tấn công (tùy chọn)

Nếu thấy cùng dải IP “gõ cửa” dồn dập trong log:

# firewalld (khuyến nghị)
firewall-cmd --permanent --add-rich-rule="rule family='ipv4' source address='218.92.0.0/24' reject"
firewall-cmd --reload

# iptables (khi không dùng firewalld)
iptables -A INPUT -s 218.92.0.0/24 -j DROP
service iptables save || true

Lưu ý: Cẩn trọng khi chặn theo dải lớn để tránh ảnh hưởng người dùng hợp lệ.

7) Giám sát, kiểm tra định kỳ

Fail2Ban:

fail2ban-client status sshd

Phiên và lần đăng nhập thất bại:

last -a | head
lastb -a | head

sshd và xác thực:

tail -f /var/log/secure
journalctl -u sshd -f --no-pager

8) Mẫu cấu hình sshd_config tham khảo (an toàn ở mức bảo thủ)

# /etc/ssh/sshd_config (các dòng chính)
Port 2222
Protocol 2
PermitRootLogin no
PasswordAuthentication no
PubkeyAuthentication yes
ChallengeResponseAuthentication no
MaxAuthTries 3
LoginGraceTime 30
X11Forwarding no
ClientAliveInterval 300
ClientAliveCountMax 2
# Tùy chọn thêm (chỉ bật khi đã kiểm soát danh tính user)
# AllowUsers deployer

Sau khi chỉnh, luôn chạy sshd -tsystemctl reload sshd thay vì restart ngay để tránh ngắt phiên hiện tại.

Rollback nhanh khi bị khoá kết nối

Nếu mất kết nối sau khi đổi cổng hoặc chỉnh cấu hình, dùng console để hoàn tác:

# Khôi phục file cấu hình
cp /etc/ssh/sshd_config.bak /etc/ssh/sshd_config

# Khôi phục SELinux port (nếu đã thêm 2222 và muốn xoá)
semanage port -d -t ssh_port_t -p tcp 2222 || true

# Mở lại cổng 22 trên firewall
firewall-cmd --permanent --add-port=22/tcp || true
firewall-cmd --reload || true

# Áp dụng
sshd -t && systemctl restart sshd

Nếu chỉ sai cú pháp: sửa lại cấu hình, chạy sshd -t cho đến khi không báo lỗi, rồi systemctl reload sshd.

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

  • Đổi cổng nhưng vẫn không kết nối được: quên gán SELinux port cho sshd. Chạy semanage port -a -t ssh_port_t -p tcp 2222 (hoặc -m nếu đã tồn tại), rồi mở firewall và reload sshd.
  • Đã chép key nhưng vẫn báo “Permission denied (publickey)”: sai phân quyền. Đặt chmod 700 ~/.ssh, chmod 600 ~/.ssh/authorized_keys, đúng chủ sở hữu user.
  • Fail2Ban không ban IP: kiểm tra enabled = true cho jail sshd, đúng logpath = /var/log/secure, và dùng banaction = firewallcmd-rich-rules nếu bạn đang chạy firewalld.
  • Restart sshd bị lỗi: chạy sshd -t để thấy dòng cấu hình gây lỗi; sửa rồi systemctl reload sshd.
  • Too many authentication failures: client gửi quá nhiều khóa qua agent. Kết nối với tuỳ chọn: ssh -o IdentitiesOnly=yes -i ~/.ssh/id_ed25519 -p 2222 user@host.

FAQ

  • Có nên đổi cổng SSH? Đổi cổng không thay thế biện pháp bảo mật, nhưng giảm đáng kể “rác” dò quét tự động. Bảo mật cốt lõi vẫn là SSH key + vô hiệu mật khẩu + hạn chế user.
  • Tắt root hoàn toàn hay chỉ cấm mật khẩu? Với máy Internet-facing, khuyến nghị PermitRootLogin no. Trường hợp đặc thù có thể dùng prohibit-password nhưng cần kiểm soát chặt khóa root.
  • Mất khóa SSH thì sao? Dùng console để đăng nhập bằng mật khẩu tạm (nếu chưa tắt), thêm khóa mới vào ~/.ssh/authorized_keys, sau đó tắt lại mật khẩu.
  • IPv6 có cần cấu hình riêng? firewalld mở theo dịch vụ/port cho cả IPv4/IPv6. Nếu dùng iptables thuần, cần thêm luật tương ứng ở ip6tables.
  • Có thể giới hạn theo nhóm/người dùng? Có, dùng AllowUsers hoặc AllowGroups để thu hẹp bề mặt tấn công.

Liên quan trên TechNT

Tài liệu tham khảo