Sổ tay kỹ thuật

SSH hardening – sshd_config, key-only, fail2ban

how-to#ssh#linux#security· cập nhật 2026-11-06

Dùng khi dựng server Linux mới (jump host, collector, runner) và cần khoá SSH về key-only, giới hạn user, chặn brute-force mà không tự khoá mình ra ngoài.

Sửa trang này
Mục lục

Tóm tắt: Đưa key lên trước, giữ một phiên SSH đang mở, đặt cấu hình trong /etc/ssh/sshd_config.d/ (tắt password, tắt root, AllowGroups), kiểm tra bằng sshd -t / sshd -T, reload, mở phiên mới để xác nhận. Thêm fail2ban hoặc chỉ mở cổng 22 cho dải quản trị bằng nftables.

Luồng hoạt động

flowchart TD A["ssh-copy-id: đưa public key lên"] --> B["Giữ 1 phiên SSH đang mở"] B --> C["Ghi sshd_config.d/10-hardening.conf"] C --> D{"sshd -t OK?"} D -->|không| C D -->|có| E["systemctl reload ssh"] E --> F["Mở phiên mới để test"] F -->|lỗi| G["Sửa từ phiên cũ"] F -->|OK| H["fail2ban / firewall"]

Cấu hình

Đưa key lên trước

# Trên máy quản trị: key ed25519, có passphrase
ssh-keygen -t ed25519 -C "ops@example.com"
ssh-copy-id -i ~/.ssh/id_ed25519.pub ops@203.0.113.30
ssh -o PasswordAuthentication=no ops@203.0.113.30 true && echo "key OK"

sshd_config

Trên Ubuntu/Debian, sshd_config có Include /etc/ssh/sshd_config.d/*.conf ở đầu file, và sshd lấy giá trị xuất hiện đầu tiên của mỗi directive. Vì vậy file drop-in có tên sắp xếp trước sẽ thắng, kể cả file do cloud-init sinh ra (vd 50-cloud-init.conf bật PasswordAuthentication yes). Đặt tên 10-... để chắc chắn.

/etc/ssh/sshd_config.d/10-hardening.conf
# Xác thực
PermitRootLogin no
PubkeyAuthentication yes
PasswordAuthentication no
KbdInteractiveAuthentication no
PermitEmptyPasswords no
AuthenticationMethods publickey
 
# Giới hạn ai được vào (tạo group trước: groupadd ssh-users)
AllowGroups ssh-users
 
# Chống brute-force / phiên treo
MaxAuthTries 3
LoginGraceTime 30
MaxStartups 10:30:60
ClientAliveInterval 300
ClientAliveCountMax 2
 
# Tắt tính năng không dùng (jump host thì giữ AllowTcpForwarding)
X11Forwarding no
AllowAgentForwarding no
AllowTcpForwarding no
 
LogLevel VERBOSE

Jump host cần ProxyJump thì phải để AllowTcpForwarding yes (ít nhất cho group dùng jump). Có thể nới riêng bằng Match Group netops ở cuối file. Cấu hình phía client xem SSH config và jump host.

Chỉ cho phép thuật toán hiện đại (tuỳ chọn, kiểm tra client cũ và thiết bị mạng trước khi áp):

/etc/ssh/sshd_config.d/20-crypto.conf
KexAlgorithms curve25519-sha256,curve25519-sha256@libssh.org
Ciphers chacha20-poly1305@openssh.com,aes256-gcm@openssh.com,aes128-gcm@openssh.com
MACs hmac-sha2-512-etm@openssh.com,hmac-sha2-256-etm@openssh.com

Áp dụng

sudo groupadd -f ssh-users && sudo usermod -aG ssh-users ops
sudo sshd -t                                   # kiểm tra cú pháp, không in gì = OK
sudo sshd -T | grep -Ei 'passwordauth|permitroot|allowgroups|authenticationmethods'
sudo systemctl reload ssh                      # RHEL: sshd
# Mở terminal MỚI và ssh vào, chỉ đóng phiên cũ khi phiên mới vào được

Ubuntu 24.04 dùng socket activation (ssh.socket): đổi Port/ListenAddress trong sshd_config cần systemctl daemon-reload && systemctl restart ssh.socket, không chỉ reload service.

fail2ban

sudo apt install fail2ban
/etc/fail2ban/jail.d/sshd.local
[sshd]
enabled  = true
backend  = systemd
maxretry = 5
findtime = 10m
bantime  = 1h
ignoreip = 127.0.0.1/8 ::1 198.51.100.0/24
sudo systemctl enable --now fail2ban
sudo fail2ban-client status sshd
sudo fail2ban-client set sshd unbanip 203.0.113.50

ignoreip là dải mạng quản trị, tránh tự ban chính mình. OpenSSH ≥ 9.8 có thêm PerSourcePenalties tích hợp sẵn, nhưng fail2ban vẫn hữu ích cho bản cũ và để chặn ở firewall.

Kiểm tra

Mục đích Lệnh
Cấu hình hiệu lực cho một user/host cụ thể sudo sshd -T -C user=ops,host=client.example.com,addr=198.51.100.5
Server chấp nhận phương thức nào ssh -v ops@203.0.113.30 2>&1 | grep 'Authentications that can continue'
Thử ép password (phải bị từ chối) ssh -o PubkeyAuthentication=no ops@203.0.113.30
Log đăng nhập journalctl -u ssh --since "1 hour ago"
Phiên đang mở who, ss -tnp state established '( sport = :22 )'
Fingerprint host key (so với lần đầu kết nối) ssh-keygen -lf /etc/ssh/ssh_host_ed25519_key.pub

Lỗi thường gặp

Triệu chứng Nguyên nhân Cách xử lý
Vẫn đăng nhập được bằng password File drop-in khác (cloud-init) có PasswordAuthentication yes được đọc trước sshd -T | grep passwordauth; đổi tên file của bạn thành 10-... hoặc sửa file kia
Permission denied (publickey) sau khi bật key-only User không thuộc AllowGroups, hoặc quyền ~/.ssh sai chmod 700 ~/.ssh; chmod 600 ~/.ssh/authorized_keys; xem journalctl -u ssh
Authentication refused: bad ownership or modes Home hoặc ~/.ssh cho group/other ghi Sửa quyền, owner đúng user
Ansible/automation hỏng sau hardening Tắt AllowTcpForwarding/agent forwarding hoặc giới hạn cipher Nới bằng Match User <automation>
Thiết bị/tool cũ báo no matching key exchange method Đã bỏ KEX/cipher cũ Giữ thuật toán cũ chỉ trong Match Address của dải đó, hoặc nâng cấp client
Sau reload không SSH vào được Lỗi cú pháp (bỏ qua sshd -t) hoặc tự khoá mình Dùng phiên cũ còn mở / console để sửa

Tham khảo