Tự dựng
tmux, mosh và Tailscale: bộ công cụ tự dựng để chạy agent lập trình từ điện thoại
Cách kinh điển để chạy Claude Code hay Codex từ điện thoại là một ứng dụng terminal, một mạng riêng, một kết nối chịu được việc chuyển mạng, và một phiên chịu được mọi thứ còn lại. Mỗi thành phần đều miễn phí và đã được hiểu rõ. Dưới đây là cách thiết lập với lệnh cụ thể, cùng một cái nhìn thẳng thắn về những chỗ nó trở nên khó chịu.
Trả lời nhanh
Cài Tailscale trên máy chủ và điện thoại, rồi bật tailscale set --ssh để máy chủ chỉ truy cập được qua tailnet riêng của bạn. Chạy agent trong tmux new -A -s main để nó sống lâu hơn kết nối. Thêm set -g allow-passthrough on và các dòng extended-keys vào ~/.tmux.conf cho Claude Code. Kết nối bằng mosh (mosh dev@server -- tmux new -A -s main) từ Blink, Termius hoặc Termux. Cách này chạy tốt. Điểm yếu của nó là một TUI toàn màn hình trên màn hình nhỏ và không có thông báo đẩy trừ khi bạn thêm hook.
Nếu bạn từng tìm cách dùng Claude Code từ điện thoại, hẳn bạn đã thấy bộ công cụ này trong cả chục bài blog. Đó là vì nó chạy được. Tailscale cho điện thoại một đường kết nối riêng, được mã hóa tới máy chủ mà không cần mở cổng. mosh giữ kết nối sống khi bạn chuyển từ Wi-Fi sang 4G hay khóa màn hình. tmux giữ agent chạy tiếp khi kết nối có rớt thật. Dưới đây là cách ghép ba thứ này lại cho đúng.
Bộ công cụ
| Tầng | Công cụ | Giải quyết vấn đề gì | Bỏ qua nếu… |
|---|---|---|---|
| Mạng | Tailscale (Tailscale SSH) | Truy cập máy chủ một cách riêng tư, kể cả sau NAT; không có cổng SSH công khai; quyền truy cập gắn với SSO | Máy chủ đã có SSH công khai được bảo mật kỹ và bạn hài lòng với nó |
| Truyền tải | mosh | Chịu được chuyển mạng, chế độ ngủ và sóng yếu; local echo che độ trễ | Bạn chỉ kết nối từ một mạng ổn định |
| Phiên | tmux | Agent vẫn chạy khi bạn ngắt kết nối; nhiều cửa sổ cho mỗi dự án | Không bao giờ. Đây là tầng quan trọng nhất. |
| Client | Blink, Termius, Termux… | Một terminal trên điện thoại | — |
Thiết lập tmux
Cài đặt và khởi chạy một phiên có tên để bạn attach lại từ bất cứ đâu:
sudo apt install tmux # Debian/Ubuntu (dnf / apk elsewhere)
tmux new -A -s main # attach to "main", or create it
cd ~/src/my-app && claude # or: codex, agy, opencode…
# detach with Ctrl-b then d — the agent keeps running
-A giúp cùng một lệnh chạy được cả lần đầu lẫn mọi lần sau, nên rất đáng lưu thành snippet trong ứng dụng terminal trên điện thoại. Sau đó, cho tmux các cài đặt mà agent cần. Tài liệu cấu hình terminal của Anthropic cho biết bên trong tmux, Shift+Enter sẽ gửi tin nhắn thay vì xuống dòng, và thông báo không bao giờ tới được terminal bên ngoài, trừ khi bạn thêm các dòng này:
# ~/.tmux.conf
set -g allow-passthrough on
set -s extended-keys on
set -as terminal-features 'xterm*:extkeys'
# quality of life on a phone
set -g mouse on # scroll and pick panes with your finger
set -g history-limit 50000 # agents print a lot
Áp dụng bằng tmux source-file ~/.tmux.conf. Kể cả khi đã bật extended keys, nhiều bàn phím điện thoại hoàn toàn không gửi được Shift+Enter. Claude Code cũng nhận Ctrl+J, hoặc \ rồi Enter, để xuống dòng, và cả hai đều chạy trong mọi terminal.
Dùng một cửa sổ tmux cho mỗi dự án hoặc mỗi agent. Ctrl-b c mở cửa sổ mới và Ctrl-b n chuyển sang cửa sổ kế tiếp. Với nhiều phiên trên cùng một repository, cho mỗi phiên một git worktree riêng. Hướng dẫn 24/7 trình bày phần đó và chuyện gì xảy ra khi khởi động lại. tmux session không sống sót qua một lần khởi động lại.
mosh hay ssh
SSH thuần chạy trên một kết nối TCP duy nhất. Khi điện thoại đổi mạng, hoặc iOS tạm dừng ứng dụng một lúc, kết nối đó chết, và bạn phải kết nối lại rồi attach lại. mosh đăng nhập qua SSH, khởi động mosh-server trên máy chủ, rồi chuyển sang giao thức UDP riêng, vốn vẫn tiếp tục qua các lần đổi IP và chế độ ngủ. Nó còn hiển thị cục bộ những gì bạn gõ, nên một đường truyền 200 ms vẫn cho cảm giác phản hồi nhanh.
# on the server
sudo apt install mosh # Fedora: sudo dnf install mosh · Alpine: apk add mosh
# from a client
mosh dev@my-server -- tmux new -A -s main
mosh dùng các cổng UDP 60000–61000. Qua IP công khai, bạn sẽ phải mở các cổng đó trên tường lửa, chẳng hạn bằng sudo ufw allow 60000:61000/udp cộng với tường lửa của nhà cung cấp cloud. Qua Tailscale, lưu lượng nằm trong tailnet, nên không cần cổng công khai nào. Một giới hạn: mosh chỉ đồng bộ phần màn hình đang thấy, nên bản thân mosh không có scrollback. Chính tài liệu của mosh khuyên dùng tmux hoặc screen để xem lịch sử, thêm một lý do để chạy cả hai.
Tailscale SSH
Tailscale đặt máy chủ và điện thoại của bạn vào một mạng WireGuard riêng (gọi là tailnet). Tailscale SSH tiến thêm một bước: Tailscale xử lý xác thực SSH bằng danh tính tailnet của bạn, nên bạn hoàn toàn không phải phân phối khóa SSH.
# on the server (Linux)
curl -fsSL https://tailscale.com/install.sh | sh
sudo tailscale up # log in to your tailnet
sudo tailscale set --ssh # enable Tailscale SSH
Theo tài liệu của Tailscale, tailscale set --ssh khiến tailscaled tiếp quản cổng 22 cho lưu lượng đến từ tailnet của bạn. Khi đó, mọi SSH client thông thường đều kết nối được bằng ssh dev@my-server, dùng tên MagicDNS của máy. Vài chi tiết:
- Check mode. Chính sách mặc định dùng
"action": "check", nên thỉnh thoảng bạn sẽ được yêu cầu xác thực lại trong trình duyệt. Một URL đăng nhập hiện ra trong terminal là chuyện bình thường. - Nền tảng máy chủ. Linux được hỗ trợ đầy đủ. Trên macOS, chỉ bản build CLI mã nguồn mở
tailscale+tailscaledmới làm máy chủ Tailscale SSH được, nên một chiếc Mac mini dùng ứng dụng từ App Store nên dùng SSH thông thường qua tailnet. - Đóng cổng công khai. Khi đã chắc chắn truy cập được máy qua tailnet, hãy đóng cổng 22 công khai trên tường lửa của nhà cung cấp. Làm đúng thứ tự đó, và giữ mở một phiên thứ hai, để không tự khóa mình ở ngoài.
Trên điện thoại, cài ứng dụng Tailscale, đăng nhập vào cùng tailnet và để nó luôn kết nối. Khi đó ứng dụng terminal của bạn tới được my-server như thể nó nằm trong mạng nội bộ.
Client trên iOS và Android
| Client | Nền tảng | mosh | Ghi chú |
|---|---|---|---|
| Blink Shell | iPhone, iPad | Có | Xây dựng xoay quanh mosh; hỗ trợ bàn phím rời rất tốt trên iPad. $19.99/năm sau hai tuần dùng thử, theo blink.sh. |
| Termius | iOS, Android, desktop | Có | Gói Starter miễn phí có SSH và mosh; đồng bộ giữa các thiết bị nằm trong Pro ($10/tháng khi thanh toán theo năm, theo termius.com/pricing) |
| Termux | Android | Có (pkg install openssh mosh) | Một userland Linux đầy đủ trên điện thoại; miễn phí và mã nguồn mở |
| JuiceSSH | Android | Có | Được liệt kê là client mosh trên mosh.org |
Dù chọn client nào, hãy thiết lập một hàng phím phụ có Esc, Ctrl, Tab và các phím mũi tên. Claude Code dùng Esc để ngắt và Shift+Tab để xoay vòng các chế độ quyền, và bàn phím điện thoại mặc định không có phím nào trong số đó.
Những chỗ nó gãy
Bộ công cụ này đáng tin cậy. Rắc rối nằm ở mọi thứ xung quanh sự đáng tin cậy đó.
- Một TUI desktop trên màn hình 6 inch. Claude Code, Codex và agy được thiết kế cho 100+ cột. Trên điện thoại, bạn đọc diff bị ngắt dòng, cuộn output của công cụ bằng ngón cái và mò tìm dòng nhập liệu.
- Không có thông báo đẩy. Khi agent xong việc hoặc cần phê duyệt, không có gì báo cho bạn trừ khi bạn thêm hook. Terminal chỉ thông báo khi ứng dụng đang ở trên màn hình. Hướng dẫn phê duyệt yêu cầu từ điện thoại của chúng tôi trình bày các hook ntfy mà mọi người hay gắn thêm.
- Yêu cầu phê duyệt bị chìm trong scrollback. Một yêu cầu cấp quyền chỉ là vài dòng trong một pane đầy chữ. Nếu bạn quay lại sau một giờ, bạn phải tìm nó, đọc nó và trả lời bằng phím mũi tên.
- Vấn đề chạy nền. iOS tạm dừng ứng dụng terminal ngay sau khi bạn rời khỏi chúng. mosh khôi phục khi bạn quay lại, nhưng ứng dụng không thể theo dõi phiên thay bạn khi đang chạy nền.
- Sao chép và dán. Chọn văn bản xuyên qua tmux, mosh và một terminal trên điện thoại rất khổ sở. URL dài, như link đăng nhập, là trường hợp tệ nhất.
- Nhiều máy chủ, nhiều agent. Mỗi máy mới là thêm một node Tailscale, thêm một mục host và thêm một bố cục tmux phải nhớ.
Không điều nào ở trên là lý do để tránh bộ công cụ này. Nó miễn phí, dùng được với mọi agent, và bạn kiểm soát từng thành phần. Đó chỉ là lý do để bạn biết mình sẽ phải đối mặt với những gì. Bài so sánh ứng dụng terminal SSH và Maude của chúng tôi đi sâu vào sự đánh đổi này.
Hoặc dùng một ứng dụng làm riêng cho việc này
Với công việc của agent, Maude thay thế tầng client và tầng phiên. Một daemon nhỏ trên máy chủ sở hữu các phiên, nên chúng vẫn chạy mà không cần tmux, và ứng dụng hiển thị chúng dưới dạng chat, với thẻ công cụ, diff, thông báo đẩy có nút Cho phép/Từ chối, và một hộp thư. Bạn có thể giữ Tailscale: Maude chạy được với máy chủ trong tailnet và mạng LAN vì máy chủ chủ động kết nối tới relay của Maude, với SSH là phương án dự phòng. Và khi cần shell, mỗi phiên đều có một terminal thật. Maude dùng được với Claude Code, Codex, OpenCode, Grok Build và Antigravity.
Câu hỏi thường gặp
Nên dùng tmux hay screen cho Claude Code?
allow-passthrough và extended-keys), tmux chia pane và viết script dễ hơn, và hầu hết hướng dẫn dùng terminal trên điện thoại đều mặc định dùng nó.