Giới thiệu
Triển khai ứng dụng SSH lên Internet có thể là một thử thách thú vị. Trong bài viết này, tôi sẽ chia sẻ cách tôi triển khai ứng dụng SSH của mình, lấy cảm hứng từ Terminal.shop. Mặc dù có một số khó khăn, nhưng quá trình này đã mang lại cho tôi nhiều bài học quý giá.
Tại Sao Lại Sử Dụng SSH?
SSH (Secure Shell) là một giao thức mạng cho phép bạn kết nối đến máy chủ từ xa một cách an toàn. Dưới đây là một số lý do tôi quyết định sử dụng SSH cho ứng dụng của mình:
- Hiệu suất cao: Ứng dụng SSH thường nhanh hơn các ứng dụng web truyền thống vì nó chỉ gửi các khối ký tự Unicode qua TCP mà không cần JavaScript hay hình ảnh.
- Thẩm mỹ retro: Ứng dụng SSH có thể mang lại trải nghiệm thú vị cho những ai yêu thích phong cách retro hoặc nghệ thuật ASCII.
- Bảo mật: Kết nối SSH đảm bảo an toàn cho dữ liệu của bạn khi truyền qua Internet.
Bubbletea và Wish
Bubbletea
Bubbletea là một framework TUI (Text User Interface) tuyệt vời cho Go, được phát triển bởi Charm. Nó rất dễ sử dụng và có nhiều tính năng mạnh mẽ. Tôi đã sử dụng Bubbletea trong nhiều dự án và rất thích nó. Đây cũng là một cách tốt để hiểu về cách xây dựng ứng dụng với kiến trúc Elm. Tuy nhiên, Go không có nhiều câu chuyện về quản lý trạng thái, và đôi khi tôi cảm thấy khó khăn trong việc quản lý trạng thái trong ứng dụng Bubbletea.
Wish
Wish là một framework dành cho việc xây dựng ứng dụng SSH. Vì Wish cũng được phát triển bởi Charm, nên việc tích hợp với Bubbletea là rất dễ dàng. Cấu trúc của Wish khá tương tự với các framework web mà tôi đã từng sử dụng, do đó, nếu bạn đã quen thuộc với routing, middleware, thì bạn sẽ thấy rất dễ dàng khi bắt đầu.
Ứng Dụng Của Tôi
Tôi đã tạo ra một ứng dụng portfolio đơn giản bằng các thư viện trên. Nếu bạn muốn trải nghiệm, hãy mở terminal và chạy lệnh sau:
ssh ssh.hiro.one
Khi lần đầu tiên kết nối, bạn sẽ được yêu cầu thêm máy chủ vào known_hosts
(đó là cách SSH hoạt động). Hãy nhấn "yes" để tiếp tục. Để thoát khỏi ứng dụng, bạn chỉ cần nhấn Ctrl+c
, Esc
, hoặc q
.
Việc xây dựng ứng dụng với Wish khá giống với xây dựng ứng dụng web. Tuy nhiên, xây dựng ứng dụng Bubbletea có chút khác biệt so với React. Tôi đã dành một tháng để hoàn thành và vẫn chưa biết cách điền dữ liệu vào textarea trong form liên hệ. Nhưng tôi sẽ tìm ra cách sau.
Triển Khai
Tôi có một thiết bị Raspberry Pi 4 tại nhà chạy Dokploy và Cloudflare Tunnel để công khai ứng dụng của mình. Thiết lập này giúp tôi tiết kiệm chi phí hạ tầng đám mây. Ban đầu, tôi dự định chạy ứng dụng SSH mới của mình trên Dokploy và công khai nó qua Cloudflare Tunnel. Tuy nhiên, Cloudflare Tunnel không hỗ trợ giao thức TCP (chỉ hỗ trợ HTTP/HTTPS). Về lý thuyết, bạn có thể sử dụng tunnel để công khai máy chủ SSH, nhưng điều đó có nghĩa là ứng dụng SSH sẽ trở thành một ứng dụng SSH dựa trên trình duyệt, điều mà tôi không muốn.
Sau nhiều ngày nghiên cứu, tôi đã quyết định sử dụng GCP Compute Engine với instance e2-micro (miễn phí mãi mãi nếu bạn ở trong giới hạn miễn phí). Mặc dù tôi cần phải trả phí lưu trữ hàng tháng, nhưng không tìm thấy cách nào khác rẻ hơn để đạt được mục tiêu của mình (việc công khai máy chủ tại nhà không được phép bởi ISP của tôi). Kế hoạch của tôi là đặt một VM trên GCP và sử dụng nó như một reverse proxy SSH, sau đó thực hiện reverse SSH từ máy chủ tại nhà đến VM và công khai cổng TCP tùy ý.
Sơ Đồ Triển Khai
Người dùng ----> | VM | ----> | Cầu nối SSH ----> Ứng dụng SSH |
-- Dokploy --
-- GCP -- -- NHÀ ------------------------
Vấn Đề Độ Trễ
GCP Compute Engine miễn phí chỉ khả dụng cho máy chủ ở khu vực Mỹ, trong khi tôi sống ở Tokyo. Khoảng cách giữa hai vị trí này gây ra độ trễ. Yêu cầu SSH của tôi phải đi từ Tokyo đến trung tâm dữ liệu ở Mỹ, sau đó đến máy chủ tại nhà ở Tokyo và cuối cùng là phản hồi lại. Tôi có thể thấy sự khác biệt giữa máy chủ phát triển cục bộ và máy chủ GCP reverse proxy. Thời gian di chuyển từ trang này đến trang khác khi nhấn phím mất khoảng 0.3-4 ms.
Vấn Đề Màu Sắc
Ứng dụng SSH của tôi sử dụng chủ đề màu catppuccin. Vấn đề là container Docker không có TTY được bật theo mặc định, dẫn đến ứng dụng chỉ hiển thị màu đen và trắng. Bạn có thể bật TTY bằng cách cung cấp cờ -t
hoặc --tty
. Tuy nhiên, khi bật PTY trên container Docker, nó không cung cấp khả năng hiển thị 256-bit màu. Màu sắc tôi thấy trên ứng dụng sản xuất có sự khác biệt so với môi trường phát triển cục bộ.
Lời Kết
Máy chủ của tôi được thiết lập như thế nào? Tôi chạy ứng dụng của mình như một container Docker trên VM. Về cơ bản, ứng dụng xây dựng bằng framework Wish không phải là một máy chủ SSH, mà chỉ là một ứng dụng terminal giao tiếp với máy khách từ xa qua giao thức SSH. Điều này có nghĩa là không có cách nào cho kẻ tấn công có thể truy cập shell trên máy của tôi. Ngay cả khi ứng dụng của tôi bị xâm phạm, nó vẫn an toàn vì container được cách ly.
Dù sao, nếu bạn quan tâm đến những gì tôi đã làm, bạn có thể truy cập vào trang SSH của tôi. Hy vọng bạn sẽ thích nó!
Các Thực Hành Tốt Nhất
- Bảo mật: Luôn cập nhật các bản vá bảo mật cho ứng dụng và máy chủ.
- Giám sát: Sử dụng công cụ giám sát để theo dõi hiệu suất và phát hiện sớm các vấn đề.
- Dự phòng: Thực hiện sao lưu định kỳ để tránh mất dữ liệu.
Những Cạm Bẫy Thường Gặp
- Thiếu bảo mật: Không sử dụng SSH key để bảo vệ kết nối.
- Cấu hình sai: Đảm bảo rằng máy chủ của bạn được cấu hình đúng để tránh các lỗ hổng bảo mật.
Mẹo Tối Ưu Hiệu Suất
- Sử dụng caching: Caching có thể cải thiện hiệu suất của ứng dụng.
- Tối ưu hóa mã: Đảm bảo mã của bạn được tối ưu để giảm thời gian phản hồi.
Câu Hỏi Thường Gặp (FAQ)
- Làm thế nào để tôi có thể triển khai ứng dụng SSH của mình?
Bạn cần một máy chủ có hỗ trợ SSH, có thể là VPS hoặc một máy chủ vật lý. - Tôi có thể sử dụng ứng dụng SSH trên thiết bị di động không?
Có, bạn có thể sử dụng ứng dụng SSH trên thiết bị di động thông qua các ứng dụng SSH client.
Đừng quên theo dõi các bài viết tiếp theo của tôi để tìm hiểu thêm về các dự án thú vị khác!