SSD Nodes Learn 🎉 VPS từ $4.99/tháng
Hướng dẫn Matt ConnorBởi Matt Connor

Truy cập agent Hermes từ điện thoại qua VPS

Truy cập Hermes trên VPS bằng Tailscale, HTTPS hoặc SSH từ điện thoại. Bài viết chỉ rõ khác biệt bảo mật và cách revoke quyền khi làm mất điện thoại.

Ba cách truy cập agent Hermes từ điện thoại

Để truy cập agent Hermes từ điện thoại, bạn dùng web dashboard của nó. Quyết định thực sự là thành phần nào nằm phía trước dashboard đó. Cách một là dùng private mesh network. Dashboard chỉ lắng nghe trên địa chỉ Tailscale và không có cổng nào expose ra Internet. Cách hai là dùng public endpoint phía sau reverse proxy có TLS (transport layer security) và login. Khi đó, login là lớp duy nhất bảo vệ terminal truy cập vào server của bạn. Cách ba là dùng SSH (secure shell) từ terminal app. Cách này cần ít thiết lập nhất nhưng cấp quyền truy cập nhiều nhất.

Hướng dẫn này bắt đầu từ phần chạy agent Hermes trên VPS của riêng bạn. Agent đã được cài đặt, phản hồi trên command line, và giờ bạn muốn truy cập nó từ điện thoại.

Các lệnh bên dưới dùng tag v2026.8.3, được phát hành ngày 3 August 2026 và được ghi là v0.20.0 trong release notes. Hermes thường xuyên phát hành phiên bản mới, vì vậy hãy pin máy vào một tag thay vì theo dõi main. Installer chấp nhận một commit:

curl -fsSL https://hermes-agent.nousresearch.com/install.sh | bash -s -- --commit 3c27eb6234bf
hermes version

hermes version in ra phiên bản thực sự đã được cài đặt. Hãy so sánh nó với tag trước khi tin dùng bất kỳ flag nào trên trang này.

Kho mã phát hành những gì và không phát hành những gì

Kho mã Hermes không có ứng dụng iOS hoặc Android. Client native là hermes desktop (bí danh hermes gui), một ứng dụng Electron cho macOS, Windows và Linux. Ứng dụng này có thể kết nối đến agent từ xa thay vì agent cục bộ: đặt remote URL thành http://<server-address>:9119 trong Settings, mục Gateway, hoặc export HERMES_DESKTOP_REMOTE_URL=http://<server-address>:9119 trước khi khởi chạy. Cách này giải quyết nhu cầu dùng laptop thứ hai. Nó không hỗ trợ điện thoại.

Giao diện bạn dùng trên điện thoại là hermes dashboard, tức giao diện trên trình duyệt. Giao diện này quản lý cấu hình, session, cron job, skill, log và các nền tảng nhắn tin. Nó cũng tích hợp terminal: server khởi chạy hermes --tui phía sau một PTY (pseudo-terminal), rồi stream output vào trang web. Trên màn hình hẹp, bộ chuyển session thu gọn thành một panel trượt vào, nên layout vẫn hiển thị được trên điện thoại.

Theo mặc định, dashboard listen trên 127.0.0.1:9119 và mở một tab trình duyệt ngay trên server. Cách này không hữu ích trên VPS (virtual private server) headless. Hãy khởi động dashboard mà không mở trình duyệt, rồi kiểm tra socket:

hermes dashboard --no-open
ss -lntp | grep 9119

Listener trên 127.0.0.1:9119 chỉ có thể truy cập từ server. Listener trên 0.0.0.0:9119 có thể truy cập từ mọi network mà máy được kết nối, bao gồm cả network public. Chỉ một dòng đó quyết định mức độ exposed của bạn, vì vậy hãy đọc nó thay vì tự suy đoán.

Lựa chọn 1: mesh riêng với Tailscale

Chọn cách này trừ khi bạn có lý do không dùng. Tailscale là mesh VPN (virtual private network) xây dựng trên WireGuard. Mỗi thiết bị được thêm vào mesh sẽ nhận một địa chỉ ổn định và kết nối trực tiếp với các thiết bị khác. Điện thoại của bạn cũng tham gia cùng mesh, nên dashboard hoàn toàn không cần mở public port.

Trên server:

curl -fsSL https://tailscale.com/install.sh | sh
sudo tailscale up
tailscale ip -4

Cài ứng dụng Tailscale trên điện thoại và đăng nhập bằng cùng một account. tailscale status trên server sẽ liệt kê điện thoại theo tên. Bây giờ bind dashboard vào địa chỉ mà tailscale ip -4 đã in ra:

hermes dashboard --host 100.101.102.103 --port 9119 --no-open

Bind vào địa chỉ mesh thay vì 0.0.0.0 nghĩa là listening socket chỉ tồn tại trên Tailscale interface. Port scan vào public IP của bạn sẽ không tìm thấy gì trên 9119 vì không có tiến trình nào listening tại đó. Khi đó firewall không còn là lớp bảo vệ duy nhất của bạn. Xác nhận lại bằng ss -lntp | grep 9119.

Địa chỉ bind cũng quyết định cơ chế authentication, và đây là phần nhiều người bỏ sót. Trên 127.0.0.1, dashboard không có login. Với mọi địa chỉ khác, auth gate là bắt buộc. Nếu chưa cấu hình provider, server sẽ từ chối khởi động. Project gọi cách này là fail closed. Hãy chạy ứng dụng ở chế độ tương tác trong lần đầu. Ứng dụng sẽ đề nghị bạn thiết lập username và password ngay lúc đó. Kết quả được ghi vào ~/.hermes/.env:

HERMES_DASHBOARD_BASIC_AUTH_USERNAME=you
HERMES_DASHBOARD_BASIC_AUTH_PASSWORD_HASH=scrypt$16384$8$1$...
HERMES_DASHBOARD_BASIC_AUTH_SECRET=a-long-random-string

Tạo secret bằng openssl rand -hex 32 rồi giữ nguyên secret đó. Secret dùng để ký session cookie, nên thay đổi nó sẽ đăng xuất mọi thiết bị. File này cũng chứa các model API key của bạn, vì vậy hãy bảo vệ nó bằng chmod 600 ~/.hermes/.env.

Kiểm tra auth gate từ một máy khác trong mesh trước khi tin tưởng cấu hình này:

curl -s http://100.101.102.103:9119/api/status | jq '.auth_required, .auth_providers'

true tiếp theo là ["basic"] nghĩa là auth gate đã bật và password provider đang xử lý yêu cầu. Tài liệu riêng của project nói rõ về provider này: nó dành cho trusted network hoặc VPN, không phù hợp với dashboard public Internet. Với mesh, đó chính là tình huống của bạn.

Để dùng HTTPS bên trong tailnet, giao port cho Tailscale:

sudo tailscale serve --bg localhost:9119
sudo tailscale serve status

Tailscale terminate TLS bằng certificate được cấp cho MagicDNS name của máy. Vì vậy trình duyệt không còn cảnh báo, còn session cookie sẽ nhận Secure flag của nó. Trước tiên, bật MagicDNS và HTTPS Certificates trên trang DNS trong Tailscale admin console. Hãy đọc phần xác nhận ở đó: tên máy và tailnet DNS name của bạn sẽ được publish vào public certificate transparency ledger, nơi bất kỳ ai cũng có thể đọc.

Chi phí thực tế của cách này là coordination server. Traffic giữa điện thoại và VPS được mã hóa end to end và không đi qua Tailscale. Tuy nhiên, account quyết định thiết bị nào thuộc mesh không nằm trên phần cứng của bạn. Nếu điều này quan trọng, hãy tự vận hành control plane bằng Headscale, control server Tailscale tự host, rồi trỏ client vào đó bằng tailscale up --login-server https://headscale.example.com. Nếu muốn bỏ mesh và tự cấu hình peer, phần so sánh giữa WireGuard thuần và Tailscale giải thích những gì bạn phải đánh đổi.

Tùy chọn 2: endpoint HTTPS public và cái bẫy bên trong

Đôi khi không thể dùng mesh. Điện thoại công việc có thể không cho phép cài VPN client. Khi đó, hãy đặt dashboard phía sau reverse proxy. Giữ dashboard chỉ bind trên loopback và để Caddy quản lý certificate:

hermes.example.com {
  reverse_proxy 127.0.0.1:9119
}

Caddy tự lấy và gia hạn certificate. reverse_proxy của Caddy chuyển tiếp WebSocket upgrade mà không cần thêm directive nào. Đây là yêu cầu của terminal tích hợp trong dashboard. Với nginx, bạn phải tự thêm các header UpgradeConnection. Cấp certificate Let’s Encrypt bằng Certbot trên nginx trình bày phần TLS của quy trình đó. Khai báo public name với Hermes để callback đăng nhập trỏ đến đúng host:

dashboard:
  public_url: "https://hermes.example.com"

Bây giờ là cái bẫy. Auth gate dựa vào bind address, không dựa vào địa chỉ gửi request. Dashboard bind trên 127.0.0.1 phía sau proxy sẽ thấy loopback, cho rằng không cần đăng nhập, rồi phục vụ bất kỳ ai được proxy cho phép đi qua. Kiểm tra chính xác những gì bạn đã public:

curl -s https://hermes.example.com/api/status | jq '.auth_required'

Nếu lệnh in ra false, Internet chỉ cách terminal trên server của bạn một URL. Không cần exploit và log cũng không báo lỗi. Có 2 cách khắc phục, và bạn nên dùng ít nhất 1 cách. Hoặc đặt cơ chế xác thực trong proxy, dùng Authentik làm nhà cung cấp single sign-on tự host phía trước thông qua forward auth; hoặc cấu hình OIDC (OpenID Connect) provider của chính dashboard:

HERMES_DASHBOARD_OIDC_ISSUER=https://auth.example.com/application/o/hermes/
HERMES_DASHBOARD_OIDC_CLIENT_ID=hermes-dashboard
HERMES_DASHBOARD_OIDC_SCOPES="openid profile email"

Ngay cả khi cấu hình đúng, tùy chọn này vẫn có một giới hạn không thể hạ thấp hơn. Trang đăng nhập public là trang bất kỳ ai cũng có thể truy cập và tấn công, còn phía sau trang đó là shell trên VPS của bạn. Username và password là lớp bảo vệ mỏng đối với trường hợp này. Vì vậy tài liệu khuyến nghị OAuth hoặc OIDC khi bind public. Hãy rate limit việc đăng nhập, giữ ufw chỉ cho phép proxy ports và SSH, chặn mọi thứ khác, rồi thỉnh thoảng đọc access log.

Tùy chọn 3: SSH và mosh từ terminal trên điện thoại

Đây là cách ít tốn công nhất: cài một ứng dụng terminal trên điện thoại, nạp SSH key vào đó và dùng giao diện text của agent.

ssh you@vps.example.com
tmux new -A -s phone
hermes --tui

tmux new -A -s phone kết nối vào session có tên phone hoặc tạo session nếu chưa có. Vì vậy agent vẫn tiếp tục chạy khi kết nối bị ngắt, và lần sau bạn sẽ quay lại đúng vị trí đó. Cách này cũng giống cách dùng điều khiển Claude Code từ điện thoại.

SSH thuần qua mạng di động khá bất tiện vì kết nối bị ngắt mỗi khi điện thoại đổi địa chỉ hoặc chuyển sang trạng thái ngủ. Mosh khắc phục vấn đề đó. Mosh chạy trên UDP (user datagram protocol) và đồng bộ trạng thái terminal thay vì một byte stream. Vì vậy session vẫn tồn tại khi bạn di chuyển từ Wi-Fi sang mạng di động:

sudo apt install -y mosh
sudo ufw allow 60000:61000/udp

Trên điện thoại, chạy mosh you@vps.example.com. Mosh khởi động mosh-server thông qua SSH login hiện có, sau đó chuyển session sang UDP trong khoảng 60000 đến 61000. Vì vậy phải mở khoảng cổng này.

Chi phí bảo mật là vấn đề cơ bản: một SSH session là một shell, còn shell có toàn bộ quyền mà account đó được phép dùng. Khi đó, các prompt phê duyệt của agent là lớp bảo vệ cuối cùng giữa một chiếc điện thoại bị đánh cắp nhưng chưa khóa và các file của bạn. Hãy dùng một account non-root riêng cho việc này, chỉ dùng key, và thực hiện hardening SSH trên VPS trước khi lưu key trên thiết bị bạn thường mang theo.

Điều gì bị gián đoạn trên mạng di động

Có 4 vấn đề, và không vấn đề nào có thể khắc phục chỉ bằng cấu hình.

Dashboard đăng xuất khi bạn không để ý. Access token có TTL (time to live) là 15 phút và API contract hiện tại không có refresh token. Khi token hết hạn, trang nhận phản hồi 401 rồi chuyển về /login. Bạn mở dashboard, bỏ điện thoại vào túi trong 20 phút, rồi quay lại màn hình đăng nhập; nội dung đang nhập sẽ mất. Không có gì bị hỏng. Hãy đăng nhập lại.

Terminal nhúng không duy trì được khi tab chạy nền. Server khởi chạy TUI (text user interface) phía sau một PTY và dọn dẹp tiến trình đó khi tab đóng. Khi mở lại, server khởi chạy một phiên mới. Trình duyệt di động loại bỏ các tab chạy nền để giải phóng bộ nhớ, nên chuyển sang ứng dụng khác đủ lâu sẽ kết thúc terminal đó. Lịch sử chat vẫn an toàn vì session được lưu trên server và hermes sessions list vẫn hiển thị chúng. Tuy nhiên, bạn không thể attach lại vào chính terminal đó. Nếu cần một session vẫn tồn tại, hãy dùng tmux qua SSH.

Kết nối nhàn rỗi bị ngắt mà không có thông báo. Nhà mạng di động loại bỏ các kết nối TCP nhàn rỗi để giải phóng entry trong bảng NAT (network address translation), còn điện thoại gần như ngừng xử lý network khi màn hình tắt. WebSocket không có lưu lượng trong một thời gian thường đã chết khi bạn mở khóa điện thoại, và trang chỉ reconnect sau khi bạn chạm vào màn hình. Đây là lý do mosh hoạt động tốt hơn SSH trên điện thoại: mosh vốn không phụ thuộc vào một kết nối có thể bị mất.

Không có notification nào được đẩy đến điện thoại. Dashboard và session SSH đều không thể đánh thức điện thoại. Trên thiết bị không có ứng dụng Hermes, nên không có đường kết nối đến push service của nền tảng. Một agent chạy lâu kết thúc, và bạn chỉ biết khi kiểm tra lại.

Thông báo đến qua messaging gateway

Cách xử lý vấn đề cuối cùng là dùng gateway. Đây là một cách hoàn toàn khác để kết nối với agent. hermes gateway kết nối agent với các nền tảng messaging như Telegram, Discord, Slack, WhatsApp, Signal và email. Bạn có thể trao đổi với agent ngay trong một app đã có sẵn push channel trên điện thoại, tự xử lý việc gửi nền ở background và tiếp tục hoạt động khi mạng bị gián đoạn.

hermes gateway setup
hermes gateway install
hermes gateway status

hermes gateway install đăng ký gateway thành một systemd service để gateway tự khởi động lại sau reboot. Trình cài đặt Hermes không tự tạo service unit, vì vậy hermes dashboard sẽ không tự chạy lại sau khi restart. Hãy viết một unit cho từng thành phần mà bạn phụ thuộc vào. Viết systemd service và timer trên VPS trình bày cách tạo file đó.

Một scheduled job cũng có thể gửi kết quả theo cách tương tự mà không cần có cuộc trò chuyện:

hermes send -t telegram -s "Backup report" -f /home/you/report.txt

Cơ chế authorisation ở đây mặc định là từ chối. Khi chưa cấu hình allowlist và GATEWAY_ALLOW_ALL_USERS chưa được thiết lập, mọi user đều bị từ chối. Đây là trạng thái khởi đầu phù hợp. Khai báo các account được phép trong ~/.hermes/.env:

TELEGRAM_ALLOWED_USERS=123456789
GATEWAY_ALLOWED_USERS=123456789

Bạn cũng có thể bật ghép nối bằng code thay vì dán numeric ID bằng cách đặt unauthorized_dm_behavior: pair trong ~/.hermes/config.yaml. Khi một account không xác định gửi tin nhắn cho agent, account đó sẽ nhận được một code gồm tám ký tự. Agent sẽ không làm gì thêm cho đến khi bạn phê duyệt code đó:

hermes pairing list
hermes pairing approve telegram ABC12DEF
hermes pairing revoke telegram 123456789

Code hết hạn sau một giờ. Mỗi user chỉ có thể yêu cầu một code sau mỗi mười phút. Năm lần thử không thành công sẽ khóa account đó.

Giới hạn phạm vi ảnh hưởng khi điện thoại bị đánh cắp

Điện thoại có thể kết nối đến agent cũng có thể chạy lệnh trên máy chủ của bạn, và điện thoại có thể bị thất lạc. Hãy quyết định ngay người đang giữ điện thoại đó được phép làm gì.

Hãy bật cơ chế phê duyệt. approvals.mode mặc định là smart; tùy chọn này dùng một model phụ để đánh giá rủi ro và chỉ tự động phê duyệt các lệnh có rủi ro thấp. Đặt thành off tương đương với chạy mọi thứ bằng --yolo, còn HERMES_YOLO_MODE=1 thực hiện việc đó thông qua environment. Không mang theo điện thoại kết nối đến agent khi đang ở trạng thái đó. Đặt approvals.cron_mode: deny để các scheduled job không thể tự phê duyệt trong lúc bạn ngủ.

approvals:
  mode: smart
  cron_mode: deny

Hãy giới hạn phạm vi mà agent có thể tác động. terminal.backend: docker chạy lệnh trong một container, loại bỏ mọi Linux capability ngoại trừ một danh sách ngắn, đặt no-new-privileges và giới hạn số lượng process. Nhờ đó, container trở thành ranh giới bảo vệ thay vì prompt. terminal.cwd cố định working directory. HERMES_WRITE_SAFE_ROOT giới hạn write_filepatch vào các directory bạn chỉ định; thao tác ghi ra ngoài các directory đó sẽ bị chặn và không có cơ chế phê duyệt nào có thể ghi đè.

export HERMES_WRITE_SAFE_ROOT=/home/you/projects:/home/you/.hermes

Hermes đã chặn việc ghi vào ~/.ssh, ~/.aws, ~/.kube/etc/sudoers, từ chối ghi các file .env ở bất kỳ vị trí nào trên disk, đồng thời từ chối một danh sách cứng các lệnh có tính phá hoại bất kể cài đặt phê duyệt của bạn là gì. Hãy xem đây là mức bảo vệ tối thiểu, không phải kế hoạch bảo mật hoàn chỉnh. Chạy agent bằng user thường, tuyệt đối không chạy bằng root. Lập luận tương tự cũng áp dụng cho mọi coding agent được để chạy không giám sát, và chạy Claude Code an toàn trên VPS trình bày chi tiết hơn về cách này.

Sau đó, hãy ghi lại các bước thu hồi quyền trước khi cần dùng đến. Xóa thiết bị trong Tailscale admin console sẽ lập tức ngắt quyền truy cập mesh. Thay đổi HERMES_DASHBOARD_BASIC_AUTH_SECRET rồi restart sẽ vô hiệu hóa mọi dashboard session trên tất cả thiết bị, vì giá trị đó dùng để ký session cookie. Xóa public key của điện thoại khỏi ~/.ssh/authorized_keys sẽ chấm dứt SSH. hermes pairing revoke telegram <user-id> sẽ xóa một messaging account. Nếu thiết bị đã lưu bất kỳ dữ liệu nào có thể đọc provider key của bạn, hãy thu hồi chúng bằng hermes auth logout <provider> và cấp key mới ở upstream.

Hãy kiểm tra kết quả thay vì mặc định cho rằng mọi thứ đã đúng. Đây là các lệnh chạy trên máy của bạn; nội dung chúng in ra sẽ phụ thuộc vào setup:

tailscale status
hermes pairing list
hermes logs gateway -n 100
hermes status --deep

Log nằm trong ~/.hermes/logs/. Hãy đọc chúng sau sự cố, và thỉnh thoảng đọc cả khi chưa xảy ra sự cố.

FAQ

Có ứng dụng Hermes chính thức cho iOS hoặc Android không?

Không. Repository Hermes cung cấp CLI, web dashboard và client desktop Electron cho macOS, Windows và Linux. Không có bản build iOS hoặc Android chính thức từ đội ngũ phát triển. Trên điện thoại, bạn dùng web dashboard trong trình duyệt, SSH client hoặc một nền tảng nhắn tin được kết nối qua hermes gateway. Có các mobile client của bên thứ ba, nhưng đó là code của bên thứ ba có thể giữ credential truy cập agent của bạn, vì vậy hãy đọc source trước khi cài đặt.

Vì sao Hermes dashboard tự đăng xuất trên điện thoại?

Access token có TTL 15 phút và API contract hiện tại không có refresh token. Khi token hết hạn, trang nhận phản hồi 401 rồi chuyển đến /login. Việc đưa trình duyệt xuống nền trên điện thoại làm lỗi này dễ thấy hơn, vì chuyển sang ứng dụng khác trong 20 phút là đủ để token hết hạn. Đặt HERMES_DASHBOARD_BASIC_AUTH_SECRET thành một giá trị ngẫu nhiên ổn định để session signing key không thay đổi sau mỗi lần restart. Việc này loại bỏ nguyên nhân thứ hai khiến bạn bị đăng xuất.

Tôi có thể đưa Hermes dashboard lên public Internet một cách an toàn không?

Chỉ khi bạn đã tự xác minh cơ chế authentication. Auth gate được bật dựa trên bind address, nên dashboard bind vào 127.0.0.1 phía sau reverse proxy sẽ không yêu cầu người dùng Internet đăng nhập. Chạy curl -s https://your-host/api/status | jq '.auth_required' rồi đọc kết quả trả về. Dùng OAuth hoặc OIDC thay vì username và password, vì tài liệu của project nói password provider chỉ dành cho trusted network và VPN. Private mesh loại bỏ hoàn toàn vấn đề này, nên đây là lựa chọn mặc định tốt hơn.

Tôi có cần tài khoản Tailscale không, hay có thể tự host control plane?

Bạn có thể tự host control plane. Headscale là bản triển khai mở của Tailscale coordination server, và Tailscale client chính thức có thể kết nối với nó bằng tailscale up --login-server https://headscale.example.com. Khi đó, bạn tự quản lý danh sách device được phép tham gia mesh. Đổi lại, bạn phải vận hành và backup server đó. Trong thời gian server bị down, bạn không thể enrol hoặc re-authenticate device.

Làm cách nào để nhận thông báo trên điện thoại khi agent hoàn tất một job?

Dùng messaging gateway. Dashboard và SSH không có cách đánh thức điện thoại, vì trên device không có Hermes app để nhận push notification. Kết nối agent với Telegram, Signal, Discord hoặc nền tảng được hỗ trợ khác bằng hermes gateway setup, rồi để app của nền tảng đó gửi thông báo. Cron job cũng có thể push một message duy nhất bằng hermes send -t telegram -s "Job done" -f /path/to/report.txt. Cách này gửi message mà không gọi model.

#hermes#mobile#remote-access#tailscale#ai-agents