tailscale

Compare original and translation side by side

🇺🇸

Original

English
🇨🇳

Translation

Chinese

Tailscale - 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.x

typescript
const ip = await tailscale.getIP();
console.log(`Tailscale IP地址: ${ip}`);  // 100.x.x.x

Serve vs Funnel

Serve与Funnel对比

FeatureServeFunnel
AccessTailnet onlyPublic internet
AuthTailscale identityNone (public)
URLmachine.tailnet.ts.netmachine.ts.net
Use caseInternal toolsPublic APIs

特性ServeFunnel
访问范围仅Tailnet网络公网
认证方式Tailscale身份认证无(公开访问)
地址格式machine.tailnet.ts.netmachine.ts.net
使用场景内部工具公开API

URL Formats

地址格式说明

TypeFormat
Serve
https://machine.tailnet-name.ts.net:port
Funnel
https://machine.ts.net
Custom domain
https://your-domain.com

类型格式
Serve
https://machine.tailnet-name.ts.net:port
Funnel
https://machine.ts.net
自定义域名
https://your-domain.com

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:3000
typescript
// 与团队成员共享本地开发服务器
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/webhooks
typescript
// 使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 phone

typescript
// 离开工位时通过手机访问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

最佳实践

  1. Use Serve for internal — Keep private services private
  2. Use Funnel sparingly — Only for truly public endpoints
  3. Add authentication — Funnel bypasses Tailscale auth
  4. Monitor access — Check who's connecting
  5. Stop when done — Don't leave services exposed
  1. 内部服务使用Serve — 确保私有服务仅内部可访问
  2. 谨慎使用Funnel — 仅用于真正需要公开的端点
  3. 添加认证机制 — Funnel会绕过Tailscale的身份认证
  4. 监控访问情况 — 查看谁在连接你的服务
  5. 使用后及时停止 — 不要让服务长期暴露在外