Dùng SSH Bastion Host Và ProxyJump Để Quản Trị Nhiều VPS An Toàn Hơn

Thiết lập SSH Bastion Host với ProxyJump để quản trị nhiều VPS qua một điểm vào, giảm port SSH public và tổ chức quyền truy cập rõ ràng hơn.

Khi có nhiều VPS, việc mở SSH public trên từng máy làm tăng bề mặt tấn công và khiến quản lý IP, firewall, SSH key trở nên phức tạp. Mô hình bastion host tạo một điểm truy cập trung gian: máy quản trị SSH tới bastion, sau đó dùng ProxyJump để đi tiếp tới các VPS nội bộ. Bài viết này hướng dẫn cấu hình OpenSSH `-J`/`ProxyJump`, file `~/.ssh/config`, firewall và SSH key theo nguyên tắc least privilege, đồng thời lưu ý các sai lầm dễ khiến bạn tự khóa khỏi hạ tầng.

Điểm quan trọng Hãy lựa chọn dịch vụ dựa trên nhu cầu sử dụng thực tế và theo dõi tài nguyên thường xuyên để có hiệu quả tốt nhất.

Khi chỉ có một VPS, mở SSH public và giới hạn bằng SSH key/firewall có thể vẫn dễ quản lý. Nhưng khi số máy tăng, mô hình “mỗi VPS mở port 22 ra Internet” bắt đầu tạo ra nhiều điểm cần bảo vệ.

Bastion host — còn gọi là jump host — là một máy trung gian duy nhất cho phép quản trị viên đi vào mạng server bên trong.

Mô hình:

Laptop quản trị
      ↓ SSH
   Bastion
      ↓ SSH nội bộ
 ┌────┼────┐
web  api   db

OpenSSH hỗ trợ ProxyJump, giúp client kết nối tới host đích bằng cách SSH qua jump host trước rồi thiết lập TCP forwarding tới máy cuối.

Nếu bạn đã dùng mạng riêng giữa các VPS, bài Cài Tailscale trên VPS Ubuntu là lựa chọn khác hoặc có thể kết hợp với bastion tùy kiến trúc.

Bastion host giải quyết vấn đề gì?

Một thiết kế phổ biến:

  • chỉ bastion có SSH public;
  • web/db/app server chỉ cho SSH từ private network hoặc IP bastion;
  • admin dùng một entry point;
  • logging và access control tập trung hơn.

Lợi ích:

  • giảm số port SSH public;
  • dễ allowlist IP quản trị;
  • dễ thu hồi quyền;
  • dễ đặt MFA/SSO ở lớp ngoài nếu dùng công cụ hỗ trợ;
  • topology nội bộ ít lộ hơn.

Nhưng bastion trở thành tài sản rất nhạy cảm. Nếu bastion bị compromise, attacker có thể tiến sâu vào hệ thống nếu quyền nội bộ quá rộng.

ProxyJump hoạt động thế nào?

OpenSSH hỗ trợ tham số:

ssh -J user@bastion user@target

-J là shortcut của ProxyJump.

Ví dụ:

ssh -J admin@203.0.113.10 ubuntu@10.10.0.21

Client sẽ:

  1. SSH tới bastion 203.0.113.10;
  2. từ kết nối đó tạo TCP forward tới 10.10.0.21:22;
  3. xác thực SSH với target.

Điểm quan trọng: bastion không nhất thiết phải chứa private key của target.

Không copy private key vào bastion

Một sai lầm phổ biến là:

laptop → bastion có private key → target

Nếu bastion bị chiếm, private key trên đó cũng bị lộ.

Với ProxyJump, private key có thể nằm trên laptop và client thực hiện xác thực end-to-end với target.

Ví dụ:

ssh -i ~/.ssh/id_ed25519 \
  -J admin@203.0.113.10 \
  ubuntu@10.10.0.21

Nếu bastion dùng key khác:

ssh -J bastion-admin@203.0.113.10 ubuntu@10.10.0.21

và cấu hình key riêng trong ~/.ssh/config.

Cấu hình ~/.ssh/config

Thay vì gõ lệnh dài:

Host bastion
    HostName 203.0.113.10
    User admin
    IdentityFile ~/.ssh/id_ed25519_bastion

Host web01
    HostName 10.10.0.21
    User ubuntu
    IdentityFile ~/.ssh/id_ed25519_prod
    ProxyJump bastion

Host db01
    HostName 10.10.0.31
    User ubuntu
    IdentityFile ~/.ssh/id_ed25519_prod
    ProxyJump bastion

Sau đó:

ssh web01
ssh db01

OpenSSH đọc config theo thứ tự và dùng block Host phù hợp.

Nhiều jump host

OpenSSH hỗ trợ nhiều proxy nối tiếp bằng dấu phẩy.

Ví dụ:

ssh -J user1@jump1,user2@jump2 admin@target

Nhưng nhiều hop làm troubleshooting khó hơn. Chỉ dùng khi topology thực sự cần.

Chuẩn bị private network giữa bastion và target

Bastion phải route tới target.

Kiểm tra từ bastion:

ip route
ping -c 3 10.10.0.21

Ping có thể bị chặn nên quan trọng hơn là kiểm tra TCP:

nc -vz 10.10.0.21 22

Nếu không có nc, có thể dùng:

ssh -v ubuntu@10.10.0.21

Firewall trên target

Mục tiêu là chỉ cho phép SSH từ bastion/private subnet.

Ví dụ UFW, nếu bastion có private IP 10.10.0.10:

sudo ufw allow from 10.10.0.10 to any port 22 proto tcp

Sau khi test bastion thành công mới cân nhắc xóa rule SSH public cũ.

Xem rule:

sudo ufw status numbered

Luôn giữ phiên SSH hiện tại và có console/KVM/rescue mode trước khi chỉnh firewall.

Nếu cần nền tảng UFW, xem bài Cài UFW Firewall trên VPS Ubuntu.

Firewall trên bastion

Bastion là entry point nên cần chặt hơn.

Ví dụ:

  • chỉ allow SSH từ IP văn phòng/VPN;
  • không chạy dịch vụ không cần thiết;
  • dùng SSH key;
  • tắt password login sau khi test;
  • cập nhật hệ thống;
  • Fail2Ban nếu SSH vẫn public.

Tham khảo bài Dùng SSH key và tắt password trên VPS Ubuntu và Cài Fail2Ban trên VPS Ubuntu.

Tắt SSH public trên target như thế nào?

Đừng sửa sshd_config để bind sai interface trước khi test.

Cách ít rủi ro hơn thường là firewall:

  1. giữ SSH daemon listen bình thường;
  2. allow private IP bastion;
  3. test ProxyJump từ laptop;
  4. mở terminal mới và SSH lại;
  5. sau đó mới xóa public SSH rule.

Ví dụ kiểm tra listener:

sudo ss -tulnp | grep ':22'

Kiểm tra host key

Khi kết nối qua bastion, client vẫn xác minh host key của target.

Lần đầu:

The authenticity of host ... can't be established

Đừng gõ yes theo thói quen trên hệ thống quan trọng. Xác minh fingerprint qua console/provider hoặc kênh tin cậy.

Không dùng:

StrictHostKeyChecking no

như cấu hình mặc định để “đỡ lỗi”. Điều đó làm yếu chống man-in-the-middle.

SSH agent forwarding có cần không?

ProxyJump không yêu cầu agent forwarding cho use case thông thường.

Tránh bật:

ForwardAgent yes

trừ khi bạn hiểu rủi ro và thực sự cần SSH tiếp từ shell trên bastion.

Agent forwarding cho phép process có quyền phù hợp trên bastion sử dụng agent socket để yêu cầu ký. Nó không copy private key file, nhưng vẫn mở thêm bề mặt tấn công.

ProxyJump trực tiếp từ client thường an toàn và đơn giản hơn.

Dùng ssh -v để debug

Khi lỗi:

ssh -vvv web01

Log debug giúp xác định:

  • key nào được thử;
  • host config nào được áp dụng;
  • kết nối tới bastion có thành công không;
  • forwarding tới target có lỗi không;
  • target từ chối auth hay network.

Không paste full debug log công khai nếu có hostname/IP nhạy cảm.

SCP qua bastion

Với config ProxyJump trong ~/.ssh/config, scp cũng có thể dùng host alias:

scp app.tar.gz web01:/tmp/

Hoặc command line:

scp -o ProxyJump=admin@203.0.113.10 app.tar.gz ubuntu@10.10.0.21:/tmp/

Rsync qua bastion

rsync -av -e 'ssh -J admin@203.0.113.10' ./build/ ubuntu@10.10.0.21:/var/www/app/

Với automation production, CI/CD nên dùng deploy user riêng thay vì key cá nhân.

Xem bài Deploy VPS bằng GitHub Actions.

Ansible qua bastion

Ansible dùng OpenSSH nên có thể tận dụng ProxyJump.

Ví dụ inventory/group var có thể cấu hình SSH common args phù hợp, hoặc đơn giản hơn dùng ~/.ssh/config trên control node.

Nếu bạn quản lý nhiều VPS, xem Quản lý nhiều VPS bằng Ansible.

Có nên dùng bastion hay Tailscale?

Bastion phù hợp khi

  • muốn một entry point rõ ràng;
  • target nằm trong private subnet;
  • sử dụng OpenSSH thuần;
  • cần audit/central control theo jump host.

Tailscale phù hợp khi

  • muốn mesh network giữa nhiều thiết bị;
  • admin cần truy cập nhiều service private;
  • muốn identity-based network access;
  • không muốn phụ thuộc một jump host duy nhất.

Có thể kết hợp: bastion chỉ reachable qua Tailscale.

Bastion có phải single point of failure không?

Có thể.

Nếu chỉ có một bastion và nó down, admin mất đường SSH dù ứng dụng vẫn chạy.

Với hạ tầng quan trọng, cân nhắc:

  • console out-of-band;
  • hai bastion ở failure domain khác nhau;
  • private VPN path dự phòng;
  • automation không phụ thuộc một host duy nhất.

Đừng mở lại SSH public trên toàn fleet chỉ để “dự phòng” mà không có kiểm soát.

Logging trên bastion

Nên theo dõi:

sudo journalctl -u ssh --since '24 hours ago'

hoặc log auth tùy distro.

Centralized logging giúp bạn tìm:

  • ai đăng nhập;
  • từ IP nào;
  • auth fail tăng bất thường;
  • thời điểm bastion bị scan.

Có thể xem bài Thu thập log tập trung bằng Grafana Loki và Alloy.

Hardening bastion

Checklist tối thiểu:

  • SSH key only;
  • disable root SSH trực tiếp;
  • allowlist source IP/VPN nếu có thể;
  • package update định kỳ;
  • không chạy Docker/app/database trên bastion nếu không cần;
  • filesystem/log monitoring;
  • MFA thông qua lớp truy cập ngoài nếu kiến trúc hỗ trợ;
  • key rotation;
  • backup config;
  • console recovery.

Sai lầm thường gặp

Copy private key production vào bastion

Nếu bastion bị compromise, attacker lấy được key.

Mở bastion SSH cho toàn Internet nhưng không harden

Bạn chỉ chuyển bề mặt tấn công từ nhiều máy về một máy cực kỳ quan trọng.

Bật agent forwarding mặc định

Không cần với ProxyJump và tăng rủi ro.

Xóa public SSH target trước khi test

Có thể tự khóa khỏi server.

Bastion dùng chung account root

Khó audit và tăng blast radius.

Quy trình triển khai an toàn

  1. tạo bastion;
  2. cấu hình SSH key;
  3. thiết lập private network;
  4. test SSH bastion → target;
  5. test ssh -J từ laptop;
  6. thêm ~/.ssh/config;
  7. allow SSH target chỉ từ bastion;
  8. test lại từ terminal mới;
  9. mới xóa rule SSH public target;
  10. thiết lập monitoring/logging.

FAQ

ProxyJump có copy private key lên bastion không?

Không. OpenSSH client có thể dùng key trên máy local để xác thực target qua kết nối proxy.

Bastion có cần public IP không?

Không bắt buộc. Bastion có thể chỉ reachable qua VPN/Tailscale hoặc corporate network.

Có thể dùng nhiều bastion không?

Có. ProxyJump hỗ trợ nhiều jump host nối tiếp, nhưng topology phức tạp hơn.

Bastion có thay firewall không?

Không. Target vẫn nên firewall chỉ cho nguồn cần thiết; bastion cũng cần firewall riêng.

Có nên dùng agent forwarding?

Không mặc định. ProxyJump thường không cần. Chỉ bật khi use case thực sự yêu cầu và hiểu rủi ro.

Kết luận

SSH bastion + ProxyJump là cách đơn giản để giảm số VPS phải mở SSH trực tiếp ra Internet. Bạn vẫn dùng OpenSSH quen thuộc nhưng gom quyền truy cập về một entry point có thể kiểm soát và giám sát tốt hơn.

Điểm quan trọng nhất là không biến bastion thành “server chứa mọi private key”. Hãy giữ key ở client, giới hạn firewall, dùng account riêng và luôn có console recovery trước khi đóng public SSH trên target.

Nếu bạn đang xây dựng cụm nhiều VPS cho web, API hoặc database, có thể tham khảo các dịch vụ VPS tại HUONG CLOUD và thiết kế private network/access model phù hợp ngay từ đầu.

Nguồn tham khảo

Kết luận

Nếu chưa chắc cấu hình hoặc loại dịch vụ nào phù hợp, hãy gửi nhu cầu thực tế để đội ngũ hỗ trợ tư vấn trước khi mua.

Chưa biết nên chọn gói nào?

Xem bảng giá VPS hoặc liên hệ đội ngũ hỗ trợ để chọn cấu hình phù hợp.

Xem bảng giá VPS →