tailscale
Compare original and translation side by side
🇺🇸
Original
English🇨🇳
Translation
ChineseTailscale - Complete API Reference
Tailscale - 完整API参考文档
Share local services via Tailscale Serve (private) and Funnel (public internet access).
通过Tailscale Serve(私有访问)和Funnel(公网访问)共享本地服务。
Chat Commands
聊天命令
Share Local Services (Private)
共享本地服务(私有)
/tailscale serve 3000 Share port on tailnet
/tailscale serve 3000 --path /api Share at specific path
/tailscale serve stop 3000 Stop sharing port
/tailscale serve status View active shares/tailscale serve 3000 在Tailnet中共享端口
/tailscale serve 3000 --path /api 在指定路径下共享
/tailscale serve stop 3000 停止共享端口
/tailscale serve status 查看活跃共享状态Public Access (Funnel)
公网访问(Funnel)
/tailscale funnel 3000 Expose to internet
/tailscale funnel 3000 --https Force HTTPS
/tailscale funnel stop 3000 Stop public access
/tailscale funnel status View funnels/tailscale funnel 3000 暴露至公网
/tailscale funnel 3000 --https 强制使用HTTPS
/tailscale funnel stop 3000 停止公网访问
/tailscale funnel status 查看Funnel状态Network Status
网络状态
/tailscale status Network status
/tailscale ip Show Tailscale IP
/tailscale peers List connected peers
/tailscale ping <peer> Ping a peer/tailscale status 网络状态
/tailscale ip 查看Tailscale IP
/tailscale peers 列出已连接的节点
/tailscale ping <peer> Ping指定节点File Transfer
文件传输
/tailscale send <file> <peer> Send file to peer
/tailscale receive Receive incoming files/tailscale send <file> <peer> 向节点发送文件
/tailscale receive 接收传入文件TypeScript API Reference
TypeScript API参考
Create Tailscale Client
创建Tailscale客户端
typescript
import { createTailscaleClient } from 'clodds/tailscale';
const tailscale = createTailscaleClient({
// Auth (optional if already logged in)
authKey: process.env.TAILSCALE_AUTHKEY,
// Socket path
socketPath: '/var/run/tailscale/tailscaled.sock',
});typescript
import { createTailscaleClient } from 'clodds/tailscale';
const tailscale = createTailscaleClient({
// 认证(若已登录则可选)
authKey: process.env.TAILSCALE_AUTHKEY,
// Socket路径
socketPath: '/var/run/tailscale/tailscaled.sock',
});Serve (Private Sharing)
Serve(私有共享)
typescript
// Share local port on tailnet
await tailscale.serve({
port: 3000,
protocol: 'https', // 'http' | 'https'
});
console.log(`Shared at: https://${tailscale.hostname}:3000`);
// Share at specific path
await tailscale.serve({
port: 8080,
path: '/api',
protocol: 'https',
});
// Share with custom hostname
await tailscale.serve({
port: 3000,
hostname: 'clodds', // clodds.tailnet-name.ts.net
});
// Stop sharing
await tailscale.serveStop(3000);
// Get serve status
const serves = await tailscale.serveStatus();
for (const serve of serves) {
console.log(`Port ${serve.port} → ${serve.url}`);
}typescript
// 在Tailnet中共享本地端口
await tailscale.serve({
port: 3000,
protocol: 'https', // 'http' | 'https'
});
console.log(`共享地址: https://${tailscale.hostname}:3000`);
// 在指定路径下共享
await tailscale.serve({
port: 8080,
path: '/api',
protocol: 'https',
});
// 使用自定义主机名共享
await tailscale.serve({
port: 3000,
hostname: 'clodds', // clodds.tailnet-name.ts.net
});
// 停止共享
await tailscale.serveStop(3000);
// 获取Serve状态
const serves = await tailscale.serveStatus();
for (const serve of serves) {
console.log(`端口 ${serve.port} → ${serve.url}`);
}Funnel (Public Internet)
Funnel(公网访问)
typescript
// Expose to public internet
await tailscale.funnel({
port: 3000,
protocol: 'https',
});
console.log(`Public URL: https://${tailscale.hostname}.ts.net`);
// With custom domain (if configured)
await tailscale.funnel({
port: 3000,
hostname: 'api.example.com',
});
// Stop funnel
await tailscale.funnelStop(3000);
// Get funnel status
const funnels = await tailscale.funnelStatus();
for (const funnel of funnels) {
console.log(`Port ${funnel.port} → ${funnel.publicUrl}`);
}typescript
// 暴露至公网
await tailscale.funnel({
port: 3000,
protocol: 'https',
});
console.log(`公网地址: https://${tailscale.hostname}.ts.net`);
// 使用自定义域名(需提前配置)
await tailscale.funnel({
port: 3000,
hostname: 'api.example.com',
});
// 停止Funnel
await tailscale.funnelStop(3000);
// 获取Funnel状态
const funnels = await tailscale.funnelStatus();
for (const funnel of funnels) {
console.log(`端口 ${funnel.port} → ${funnel.publicUrl}`);
}Network Status
网络状态
typescript
// Get status
const status = await tailscale.status();
console.log(`Hostname: ${status.hostname}`);
console.log(`IP: ${status.ip}`);
console.log(`Tailnet: ${status.tailnet}`);
console.log(`Online: ${status.online}`);
// List peers
const peers = await tailscale.peers();
for (const peer of peers) {
console.log(`${peer.hostname} (${peer.ip})`);
console.log(` OS: ${peer.os}`);
console.log(` Online: ${peer.online}`);
console.log(` Last seen: ${peer.lastSeen}`);
}
// Ping peer
const ping = await tailscale.ping('other-machine');
console.log(`Latency: ${ping.latencyMs}ms`);typescript
// 获取状态
const status = await tailscale.status();
console.log(`主机名: ${status.hostname}`);
console.log(`IP地址: ${status.ip}`);
console.log(`Tailnet网络: ${status.tailnet}`);
console.log(`在线状态: ${status.online}`);
// 列出节点
const peers = await tailscale.peers();
for (const peer of peers) {
console.log(`${peer.hostname} (${peer.ip})`);
console.log(` 操作系统: ${peer.os}`);
console.log(` 在线状态: ${peer.online}`);
console.log(` 最后上线时间: ${peer.lastSeen}`);
}
// Ping节点
const ping = await tailscale.ping('other-machine');
console.log(`延迟: ${ping.latencyMs}ms`);File Transfer
文件传输
typescript
// Send file to peer
await tailscale.sendFile({
file: '/path/to/file.zip',
peer: 'other-machine',
});
// Receive files (returns when file received)
const received = await tailscale.receiveFile({
savePath: '/downloads',
timeout: 60000,
});
console.log(`Received: ${received.filename}`);
console.log(`From: ${received.sender}`);
console.log(`Size: ${received.size} bytes`);typescript
// 向节点发送文件
await tailscale.sendFile({
file: '/path/to/file.zip',
peer: 'other-machine',
});
// 接收文件(文件接收完成后返回)
const received = await tailscale.receiveFile({
savePath: '/downloads',
timeout: 60000,
});
console.log(`已接收: ${received.filename}`);
console.log(`发送方: ${received.sender}`);
console.log(`文件大小: ${received.size} 字节`);Get Tailscale IP
获取Tailscale IP
typescript
const ip = await tailscale.getIP();
console.log(`Tailscale IP: ${ip}`); // 100.x.x.xtypescript
const ip = await tailscale.getIP();
console.log(`Tailscale IP地址: ${ip}`); // 100.x.x.xServe vs Funnel
Serve与Funnel对比
| Feature | Serve | Funnel |
|---|---|---|
| Access | Tailnet only | Public internet |
| Auth | Tailscale identity | None (public) |
| URL | machine.tailnet.ts.net | machine.ts.net |
| Use case | Internal tools | Public APIs |
| 特性 | Serve | Funnel |
|---|---|---|
| 访问范围 | 仅Tailnet网络 | 公网 |
| 认证方式 | Tailscale身份认证 | 无(公开访问) |
| 地址格式 | machine.tailnet.ts.net | machine.ts.net |
| 使用场景 | 内部工具 | 公开API |
URL Formats
地址格式说明
| Type | Format |
|---|---|
| Serve | |
| Funnel | |
| Custom domain | |
| 类型 | 格式 |
|---|---|
| Serve | |
| Funnel | |
| 自定义域名 | |
Use Cases
使用场景
Share Dev Server
共享开发服务器
typescript
// Share local dev server with team
await tailscale.serve({ port: 3000 });
// Team can access at https://your-machine.tailnet.ts.net:3000typescript
// 与团队成员共享本地开发服务器
await tailscale.serve({ port: 3000 });
// 团队成员可通过 https://your-machine.tailnet.ts.net:3000 访问Expose Webhook Endpoint
暴露Webhook端点
typescript
// Make webhook publicly accessible
await tailscale.funnel({ port: 3000, path: '/webhooks' });
// External services can POST to https://your-machine.ts.net/webhookstypescript
// 使Webhook可被公网访问
await tailscale.funnel({ port: 3000, path: '/webhooks' });
// 外部服务可向 https://your-machine.ts.net/webhooks 发送POST请求Share Bot with Phone
与手机共享Bot服务
typescript
// Access bot from phone while away from desk
await tailscale.serve({ port: 18789 });
// Open https://your-machine.tailnet.ts.net:18789/webchat on phonetypescript
// 离开工位时通过手机访问Bot服务
await tailscale.serve({ port: 18789 });
// 在手机上打开 https://your-machine.tailnet.ts.net:18789/webchat 即可访问Requirements
要求
- Tailscale installed and running
- Logged into a Tailnet
- For Funnel: Funnel enabled in Tailscale admin
- 已安装并运行Tailscale
- 已登录至某个Tailnet网络
- 使用Funnel功能:需在Tailscale管理后台启用Funnel
Best Practices
最佳实践
- Use Serve for internal — Keep private services private
- Use Funnel sparingly — Only for truly public endpoints
- Add authentication — Funnel bypasses Tailscale auth
- Monitor access — Check who's connecting
- Stop when done — Don't leave services exposed
- 内部服务使用Serve — 确保私有服务仅内部可访问
- 谨慎使用Funnel — 仅用于真正需要公开的端点
- 添加认证机制 — Funnel会绕过Tailscale的身份认证
- 监控访问情况 — 查看谁在连接你的服务
- 使用后及时停止 — 不要让服务长期暴露在外