SSH & Remote Access
Cơ chế hoạt động SSH
SSH cơ bản
# Kết nối
ssh user@hostname # kết nối cơ bản
ssh -p 2222 user@hostname # port tùy chỉnh
ssh -i ~/.ssh/id_rsa user@hostname # chỉ định key
ssh -v user@hostname # verbose (debug kết nối)
ssh -vvv user@hostname # cực kỳ verbose
ssh -A user@hostname # SSH agent forwarding (jump host)
# Chạy lệnh từ xa không cần shell tương tác
ssh user@host "df -h"
ssh user@host "sudo systemctl restart nginx"
ssh user@host "uptime && free -h && df -h"
# Tunnel / Port Forwarding
ssh -L 8080:localhost:80 user@host # local: truy cập host:80 qua localhost:8080
ssh -R 9090:localhost:3000 user@host # remote: host truy cập laptop:3000 qua host:9090
ssh -N -L 5432:db-internal:5432 user@bastion # tunnel đến DB qua bastion (không mở shell)
SSH Key Authentication
Tạo SSH Key
# ed25519 — khuyến nghị (nhỏ gọn, bảo mật cao, nhanh)
ssh-keygen -t ed25519 -C "sontn@company.com"
# RSA 4096 — nếu cần backward compatibility
ssh-keygen -t rsa -b 4096 -C "sontn@company.com"
# Output:
# Generating public/private ed25519 key pair.
# Enter file in which to save the key (~/.ssh/id_ed25519): ← Enter để dùng mặc định
# Enter passphrase (empty for no passphrase): ← Nên đặt passphrase!
# → Tạo ra:
# ~/.ssh/id_ed25519 (private key — KHÔNG BAO GIỜ chia sẻ)
# ~/.ssh/id_ed25519.pub (public key — copy lên server)
Private Key là tài sản quan trọng
- KHÔNG commit private key lên git
- KHÔNG gửi private key qua email/chat
- NÊN đặt passphrase để mã hoá private key
- NÊN đặt permission
600cho private key
Copy Public Key lên Server
# Cách 1: ssh-copy-id (dễ nhất)
ssh-copy-id user@hostname
ssh-copy-id -i ~/.ssh/id_ed25519.pub user@hostname # chỉ định key cụ thể
ssh-copy-id -p 2222 user@hostname # port tùy chỉnh
# Cách 2: Thủ công
cat ~/.ssh/id_ed25519.pub | ssh user@host "mkdir -p ~/.ssh && cat >> ~/.ssh/authorized_keys"
# Cách 3: Nếu đã có quyền truy cập server
echo "ssh-ed25519 AAAAC3... sontn@company" >> ~/.ssh/authorized_keys
Permissions SSH (bắt buộc đúng)
chmod 700 ~/.ssh # thư mục SSH
chmod 600 ~/.ssh/id_ed25519 # private key
chmod 644 ~/.ssh/id_ed25519.pub # public key
chmod 600 ~/.ssh/authorized_keys # authorized keys
chmod 644 ~/.ssh/known_hosts # known hosts
# Nếu sai permission → SSH từ chối kết nối với lỗi "Permissions too open"
SSH Config — Cấu hình Client
# ~/.ssh/config — rút gọn lệnh ssh phức tạp
# ~/.ssh/config
# Server production
Host prod
HostName 203.0.113.100
User ubuntu
Port 22
IdentityFile ~/.ssh/prod_key
ServerAliveInterval 60
ServerAliveCountMax 3
# Bastion / Jump Host
Host bastion
HostName 10.0.0.5
User ec2-user
Port 22
IdentityFile ~/.ssh/aws_key
# Server nội bộ qua bastion (ProxyJump)
Host app-server
HostName 192.168.1.10
User ubuntu
ProxyJump bastion
IdentityFile ~/.ssh/aws_key
# Dev server non-standard port
Host dev
HostName 10.10.10.20
User sontn
Port 2222
IdentityFile ~/.ssh/dev_key
# Cấu hình chung cho tất cả host
Host *
ServerAliveInterval 120
ServerAliveCountMax 3
AddKeysToAgent yes
StrictHostKeyChecking ask
# Sau khi có config — lệnh đơn giản hơn nhiều:
ssh prod # thay vì: ssh -i ~/.ssh/prod_key ubuntu@203.0.113.100
ssh app-server # tự động đi qua bastion
scp file.txt prod:/tmp/ # scp cũng dùng config
rsync -avz ./src/ prod:/opt/ # rsync cũng dùng config
SCP và rsync
SCP — Secure Copy
# Upload file lên server
scp file.txt user@host:/remote/path/
# Download file từ server
scp user@host:/remote/file.txt ./
# Copy thư mục (-r recursive)
scp -r folder/ user@host:/remote/
# Port tùy chỉnh (-P viết hoa)
scp -P 2222 file.txt user@host:/tmp/
# Dùng với SSH config
scp file.txt prod:/tmp/
rsync — Sync hiệu quả
# Sync thư mục (chỉ copy file thay đổi)
rsync -avz ./src/ user@host:/dest/
# Sync + xoá file không còn ở nguồn
rsync -avz --delete ./src/ user@host:/dest/
# Hiện tiến độ
rsync -avz --progress large_file user@host:/tmp/
# Dùng port SSH khác
rsync -avz -e "ssh -p 2222" ./src/ user@host:/dest/
# Dry run — xem sẽ làm gì mà không thực sự copy
rsync -avzn ./src/ user@host:/dest/
# Exclude file/thư mục
rsync -avz --exclude='.git' --exclude='node_modules/' ./src/ user@host:/dest/
rsync vs scp
rsyncchỉ transfer file đã thay đổi → nhanh hơn nhiều khi sync lạirsynchỗ trợ resume nếu bị ngắt giữa chừng- Dùng
rsynccho deployment, backup;scpcho copy đơn giản
Bảo mật SSH Server
# Cấu hình /etc/ssh/sshd_config (server-side)
sudo nano /etc/ssh/sshd_config
# Sau khi sửa, reload
sudo systemctl reload sshd
# /etc/ssh/sshd_config — Cấu hình bảo mật khuyến nghị
# Đổi port (tránh scan tự động)
Port 2222
# Tắt login bằng password (chỉ dùng key)
PasswordAuthentication no
ChallengeResponseAuthentication no
# Tắt login root trực tiếp
PermitRootLogin no
# Chỉ cho phép user cụ thể
AllowUsers sontn deployer
# Chỉ cho phép group cụ thể
AllowGroups sshusers
# Timeout
LoginGraceTime 30
ClientAliveInterval 300
ClientAliveCountMax 2
# Tắt X11 forwarding nếu không cần
X11Forwarding no
# Protocol
Protocol 2
# Kiểm tra cấu hình trước khi restart (tránh lock out)
sudo sshd -t # test config syntax
sudo systemctl reload sshd # reload (không kill session hiện tại)
SSH Agent — Quản lý Key
# Khởi động SSH agent
eval "$(ssh-agent -s)" # khởi động và export biến môi trường
# Thêm key vào agent (chỉ nhập passphrase 1 lần)
ssh-add ~/.ssh/id_ed25519
ssh-add ~/.ssh/prod_key
# Xem key đang có trong agent
ssh-add -l
# Xoá key khỏi agent
ssh-add -d ~/.ssh/id_ed25519
ssh-add -D # xoá tất cả
# Agent forwarding — dùng key local khi ssh vào server và từ đó ssh tiếp
ssh -A bastion # forward agent vào bastion
# → Từ bastion, có thể ssh vào app-server mà không cần copy key lên bastion
Troubleshoot SSH
# Debug từ client
ssh -v user@host # verbose level 1
ssh -vvv user@host # verbose level 3 (rất chi tiết)
# Xem log từ server (khi có console access)
sudo tail -f /var/log/auth.log # Ubuntu
sudo journalctl -u sshd -f # systemd
sudo tail -f /var/log/secure # RHEL/CentOS
# Kiểm tra nhanh từ ngoài
nc -zv server_ip 22 # port 22 có mở không?
telnet server_ip 22 # kết nối raw để xem banner
| Lỗi thường gặp | Nguyên nhân | Giải pháp |
|---|---|---|
Connection refused | SSH không chạy hoặc port sai | Kiểm tra systemctl status sshd, port |
Permission denied (publickey) | Key chưa được add, sai permission | Kiểm tra authorized_keys, chmod |
Host key verification failed | Server đổi key | Xoá dòng trong known_hosts |
Warning: Unprotected private key | Sai permission key | chmod 600 ~/.ssh/id_ed25519 |
| Timeout mà không có lỗi | Firewall chặn | Kiểm tra Security Group, ufw |