Trang chủ › Docs (dev)
Tài liệu · Lập trình viên

Tích hợp entry.io.vn vào hệ thống của bạn

Một trang gom đủ: lấy API token, gọi REST API, chạy tunnel trong Docker / docker-compose / Kubernetes / CI, và cho AI agent tự dùng qua MCP. Mọi thứ chỉ cần ssh + 1 token — không SDK, không cài agent riêng.

SSH keytunnel (ssh -R)https://<tên>.entry.io.vn  ·  API tokenREST API / MCP
1

API token

Mở DashboardAPI tokens. Mỗi tài khoản có sẵn một token mặc định (xem lại được bất cứ lúc nào); bấm tạo token để có thêm token riêng cho từng máy/CI/agent — chuỗi entry_… của token mới chỉ hiện một lần.

Gắn vào header Authorization theo chuẩn Bearer:

curl -H "Authorization: Bearer entry_xxxxxxxx" https://app.entry.io.vn/v1/me

Trả về tài khoản, hạn mức, domain tunnel và cổng SSH:

{ "user": { "email": "ban@example.com", "plan": "free", "plan_label": "Free", "status": "active" }, "tunnel_domain": "entry.io.vn", "ssh_port": 2222, "limits": { "concurrent": 3, "reserved": 1 } }
🔑 Token = toàn quyền tài khoản (mở/đóng tunnel, thêm SSH key, sửa DDNS…). Đừng commit vào repo — để trong biến môi trường / secret. Lộ token → Dashboard ▸ thu hồi (hoặc xoay token mặc định), token cũ chết ngay.
💡 Token dùng cho API & MCP. Còn mở tunnel thì xác thực bằng SSH key (Dashboard ▸ Public SSH Keys) — hai thứ tách nhau, đừng nhầm.
2

REST API

Base URL https://app.entry.io.vn · JSON · auth Authorization: Bearer entry_… (sai/thu hồi token → 401).

ViệcEndpoint
Tài khoản, hạn mứcGET /v1/me
Tunnel đang chạy (+ số slot còn lại)GET /v1/tunnels
Cưỡng ép đóng tunnel đang chạyPOST /v1/tunnels/:subdomain/close
Mức dùng 30 ngày (bytes, requests)GET /v1/usage
SSH key: xem / thêm / xoáGET POST /v1/ssh-keys · DEL /v1/ssh-keys/:id
Subdomain giữ chỗ (tên cố định)GET POST /v1/reserved · DEL /v1/reserved/:id
Giới hạn IP cho subdomain (allowlist)GET /v1/tunnel-acl · PUT DEL /v1/tunnel-acl/:subdomain
DDNS: xem / tạo / xoá / xoay tokenGET POST /v1/ddns · DEL /v1/ddns/:pid · POST /v1/ddns/:pid/rotate-token
Mạng riêng (VPN): thiết bị, trạng tháiGET /v1/vpn/devices · /v1/vpn/status
Cổng TCP public còn trốngGET /v1/tcp-pool
Token: xem / tạo / xoáGET POST /v1/tokens · DEL /v1/tokens/:id
Thống kê nền tảng (không cần auth)GET /v1/stats

Thêm SSH key của máy (để máy đó mở được tunnel):

curl -X POST https://app.entry.io.vn/v1/ssh-keys \ -H "Authorization: Bearer $ENTRY_API_TOKEN" -H "content-type: application/json" \ -d "{\"public_key\": \"$(cat ~/.ssh/id_ed25519.pub)\", \"label\": \"ci-runner\"}"

Giữ chỗ subdomain cố định rồi mở tunnel vào đúng tên đó:

curl -X POST https://app.entry.io.vn/v1/reserved \ -H "Authorization: Bearer $ENTRY_API_TOKEN" -H "content-type: application/json" \ -d '{"subdomain":"myapp"}' ssh -p 2222 -R myapp:80:localhost:3000 entry.io.vn # → https://myapp.entry.io.vn

Cưỡng ép đóng tunnel đang chạy (máy cũ treo, đang giữ mất tên). Mặc định mode:"route" — chỉ đóng đúng tên đó, phiên SSH của máy vẫn sống; mode:"client" ngắt cả phiên SSH (mọi tunnel của máy đó rớt theo, response báo also_closed):

curl -X POST https://app.entry.io.vn/v1/tunnels/myapp/close \ -H "Authorization: Bearer $ENTRY_API_TOKEN" -H "content-type: application/json" \ -d '{"mode":"route"}' # → { "ok": true, "closed": [ { "subdomain": "myapp", "kind": "http", "mode": "route", "also_closed": 0 } ] }
♻️ Chỉ đóng được tunnel của chính bạn (khớp SSH key trong tài khoản) — tên của người khác trả 403.
route (mặc định) = tắt hẳn, KHÔNG tự mở lại. sish gỡ listener nhưng phiên SSH của máy vẫn sống, nên dịch vụ ngầm 24/7 không biết mà kết nối lại. Muốn mở lại phải restart dịch vụ trên máy đó (systemctl restart entry-tunnel · Windows: Start-ScheduledTask -TaskName entry-tunnel-<tên>).
client = ngắt phiên SSH → máy chạy ngầm TỰ kết nối lại sau ~5–15s và lấy lại tên. Dùng khi muốn reset kết nối treo, không phải để đóng hẳn. Muốn chặn hẳn một máy: xoá SSH key của nó, hoặc đặt IP allowlist cho subdomain (bên dưới).

Chỉ cho vài IP vào subdomain (allowlist — hợp cho staging nội bộ):

curl -X PUT https://app.entry.io.vn/v1/tunnel-acl/myapp \ -H "Authorization: Bearer $ENTRY_API_TOKEN" -H "content-type: application/json" \ -d '{"cidrs":["203.0.113.5","10.0.0.0/8"],"enabled":true}'
⏱️ /v1/tunnels lấy dữ liệu qua reconciler chạy mỗi ~5 giây — tunnel vừa mở có thể chưa xuất hiện ngay. Đừng poll gắt, đợi vài giây rồi gọi lại.
3

Dùng trong Docker

Có image sẵn nguyendinhsen/entry-tunnel (Alpine + autossh, chạy non-root, tự reconnect khi rớt mạng). Nó chỉ cần SSH private keyTARGET = host:port của service cần đưa ra.

Chạy nhanh — đưa app đang chạy ở cổng 3000 trên host ra internet:

docker run -d --name entry-tunnel \ --add-host=host.docker.internal:host-gateway \ -v $HOME/.ssh/id_ed25519:/keys/id_ed25519:ro \ -e TARGET=host.docker.internal:3000 \ -e SUBDOMAIN=myapp \ nguyendinhsen/entry-tunnel:latest # → https://myapp.entry.io.vn

docker-compose — tunnel làm sidecar cho service trong cùng network (trỏ thẳng tên service):

services: web: image: nginx:alpine # app của bạn tunnel: image: nguyendinhsen/entry-tunnel:latest restart: unless-stopped depends_on: [web] environment: TARGET: web:80 # tên service : cổng trong network SUBDOMAIN: myapp # bỏ trống = tên ngẫu nhiên volumes: - ~/.ssh/id_ed25519:/keys/id_ed25519:ro
Biến môi trườngMặc địnhÝ nghĩa
TARGETbắt buộcservice cần expose: web:80, host.docker.internal:3000, svc.ns.svc:8080
SUBDOMAINrỗngtên cố định (nên giữ chỗ trước qua API/Dashboard); rỗng = ngẫu nhiên
MODEhttphttp (web, có HTTPS) hoặc tcp (Postgres, SSH… → cấp 1 cổng public)
KEY_PATH/keys/id_ed25519chỗ mount private key
ENTRY_HOST / ENTRY_SSH_PORTentry.io.vn / 2222đổi khi tự host
EXTRA_COMMANDrỗngnâng cao, vd alias riêng tư tcp-aliases-allowed-users=SHA256:…
🔒 Image tự copy key ra /tmpchmod 600 nên mount :ro vẫn chạy. Nếu bạn tự viết Dockerfile gọi ssh trực tiếp, phải làm bước này — không thì ssh báo UNPROTECTED PRIVATE KEY FILE (volume read-only không chmod được).
💡 Không muốn mount key từ host? Dùng Docker secret rồi trỏ KEY_PATH=/run/secrets/entry_key.
4

Dùng trong Kubernetes

Cùng image đó, đóng gói thành Helm chart entry-tunnel — đưa một Service trong cụm ra HTTPS không cần LoadBalancer / Ingress công / IP public.

kubectl create secret generic entry-ssh-key --from-file=id_ed25519=$HOME/.ssh/id_ed25519 helm install myapp ./k8s/helm/entry-tunnel \ --set tunnel.target=my-svc.default.svc:80 \ --set tunnel.subdomain=myapp \ --set sshKey.existingSecret=entry-ssh-key # → https://myapp.entry.io.vn

TCP (vd Postgres nội bộ): thêm --set tunnel.mode=tcp --set tunnel.target=postgres.db.svc:5432. Một tunnel = một Service; nhiều Service → nhiều release.

5

Dùng trong CI/CD

Ví dụ GitHub Actions: dựng app rồi mở tunnel để chạy test E2E từ ngoài / gửi preview URL cho reviewer. Key nằm trong repo secret ENTRY_SSH_KEY (public key của nó đã thêm vào tài khoản).

- name: Mở tunnel env: ENTRY_SSH_KEY: ${{ secrets.ENTRY_SSH_KEY }} run: | printf '%s' "$ENTRY_SSH_KEY" > /tmp/k && chmod 600 /tmp/k ssh -i /tmp/k -p 2222 -o StrictHostKeyChecking=accept-new \ -o ExitOnForwardFailure=yes \ -R pr-${{ github.event.number }}:80:localhost:3000 \ entry.io.vn "sleep infinity" & sleep 5 echo "PREVIEW=https://pr-${{ github.event.number }}.entry.io.vn" >> $GITHUB_ENV
⚠️ Không dùng cờ -N — sish cần một remote command để đăng ký tunnel, có -N thì tunnel không được tạo. Chạy nền thì dùng "sleep infinity" & như trên.
6

Dùng trong AI agent (MCP)

MCP (Model Context Protocol) là chuẩn để agent gọi tool. MCP server của entry.io.vn chạy stdio ngay trên máy agent, auth bằng API token ở bước 1 — cho Claude (Code/Desktop) hay bất kỳ MCP client nào tự mở tunnel, quản DDNS / SSH key / subdomain / VPN.

Claude Code — một lệnh:

claude mcp add entry-io-vn -e ENTRY_API_TOKEN=entry_xxxxxxxx -- npx -y github:NguyenSen/entry-mcp-server

Claude Desktopclaude_desktop_config.json:

{ "mcpServers": { "entry-io-vn": { "command": "npx", "args": ["-y", "github:NguyenSen/entry-mcp-server"], "env": { "ENTRY_API_TOKEN": "entry_xxxxxxxx" } } } }

Cần Node ≥ 18. Biến tuỳ chọn: ENTRY_BASE_URL (mặc định https://app.entry.io.vn), ENTRY_SSH_HOST (entry.io.vn), ENTRY_SSH_PORT (2222) — đổi khi tự host.

23 tool agent gọi được:

NhómTool
Tunnelentry_tunnel_open, entry_tunnel_close, entry_tunnels, entry_tunnels_local, entry_tunnel_acl_get/_set/_clear, entry_tcp_pool
DDNSentry_ddns_list, entry_ddns_create, entry_ddns_delete, entry_ddns_update_ip
SSH keyentry_ssh_keys, entry_ssh_key_add, entry_ssh_key_delete
Subdomainentry_reserved, entry_reserve_subdomain, entry_reserved_delete
VPNentry_vpn_devices, entry_vpn_status
Tài khoảnentry_whoami, entry_stats, entry_usage
“Đưa app cổng 3000 ra internet”entry_tunnel_openhttps://abc.entry.io.vn 🌍
🔒 entry_tunnel_open spawn ssh -R nền trên máy chạy agent → máy đó cần có ssh và SSH key đã thêm vào tài khoản (agent tự thêm được bằng entry_ssh_key_add). Tunnel sống tới khi entry_tunnel_close hoặc tắt MCP.
7

DDNS API

Tạo tên qua API (trả về fqdn + token + update_url):

curl -X POST https://app.entry.io.vn/v1/ddns \ -H "Authorization: Bearer $ENTRY_API_TOKEN" -H "content-type: application/json" \ -d '{"label":"nas"}' # → { "fqdn": "nas.ddns.entry.io.vn", "token": "…", "update_url": "https://entry.io.vn/nic/update?hostname=nas.ddns.entry.io.vn" }

Cập nhật IP theo giao thức DynDNS (router cắm thẳng, hoặc cron trên máy) — Basic auth: user = label, pass = token. Bỏ myip thì server lấy IP nguồn của request:

curl -u nas:DDNS_TOKEN "https://entry.io.vn/nic/update?hostname=nas.ddns.entry.io.vn" # hoặc chỉ định IP: ...&myip=203.0.113.9 (IPv6 cũng được)
💡 Token DDNS khác API token — nó chỉ sửa được đúng một record. Lộ thì POST /v1/ddns/:pid/rotate-token để xoay.
8

Gotchas — đọc trước khi debug