Skip to main content

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 600 cho 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
  • rsync chỉ transfer file đã thay đổi → nhanh hơn nhiều khi sync lại
  • rsync hỗ trợ resume nếu bị ngắt giữa chừng
  • Dùng rsync cho deployment, backup; scp cho 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ặpNguyên nhânGiải pháp
Connection refusedSSH không chạy hoặc port saiKiểm tra systemctl status sshd, port
Permission denied (publickey)Key chưa được add, sai permissionKiểm tra authorized_keys, chmod
Host key verification failedServer đổi keyXoá dòng trong known_hosts
Warning: Unprotected private keySai permission keychmod 600 ~/.ssh/id_ed25519
Timeout mà không có lỗiFirewall chặnKiểm tra Security Group, ufw