Skill: caishu97/ztm-tunnel (version 1.0.0)

--- name: ztm-tunnel description: "Create and manage TCP/UDP tunnels between ZTM network endpoints. Use this to establish secure P2P port forwarding through the ZTM mesh network." metadata: { "openclaw": { "emoji": "🔌", "requires": { "bins": ["ztm"], "services": ["ztm-agent"], }, "install": [ { "id": "download", "kind": "download", "label": "Download ZTM from GitHub releases", "url": "https://github.com/flomesh-io/ztm/releases", }, ], "env": { "ZTM_AGENT": "http://localhost:7777", }, "config": { "path": "~/.ztm.conf", "fields": { "agent": "ZTM Agent URL (default: localhost:7777)", "mesh": "Default mesh name", }, }, }, } --- # ZTM Tunnel Skill Create and manage TCP/UDP tunnels between ZTM network endpoints. ## Prerequisites 1. **ZTM Agent must be running** ```bash ztm start agent ``` 2. **Join a mesh network** ```bash ztm join <mesh-name> --as <your-endpoint-name> --permit <permit-file.json> ``` 3. **Tunnel app must be installed** ```bash ztm app install tunnel ``` ## Concepts - **Inbound**: The local endpoint that listens for connections and forwards them to the remote - **Outbound**: The remote endpoint that receives connections and forwards them to target services - **Tunnel**: A complete connection consisting of inbound + outbound ## List Tunnels List all tunnels in the mesh: ```bash ztm tunnel get tunnel ``` List inbound tunnels (local listening ports): ```bash ztm tunnel get inbound ``` List outbound tunnels (remote targets): ```bash ztm tunnel get outbound ``` ## Create a Tunnel ### Scenario: Expose a local service to another endpoint **Step 1: On the remote endpoint (outbound)**, specify target services: ```bash ztm tunnel open outbound my-tunnel --targets 192.168.1.100:8080 ``` **Step 2: On the local endpoint (inbound)**, set up port forwarding: ```bash ztm tunnel open inbound my-tunnel --listen 0.0.0.0:9000 --exits <remote-endpoint-id> ``` This creates a tunnel where: - Local port `9000` listens for connections - Connections are forwarded to remote endpoint - Remote forwards to `192.168.1.100:8080` ### Quick One-Liner (Same Command on Both Ends) Create both ends at once by running on respective endpoints: ```bash # On endpoint A (listening side) ztm tunnel open inbound tunnel-name --listen 0.0.0.0:9000 --exits <endpoint-B-id> # On endpoint B (target side) ztm tunnel open outbound tunnel-name --targets 127.0.0.1:8080 ``` ## Delete a Tunnel Close the inbound end: ```bash ztm tunnel close inbound my-tunnel ``` Close the outbound end: ```bash ztm tunnel close outbound my-tunnel ``` ## Tunnel Details View detailed tunnel information: ```bash ztm tunnel describe tunnel tcp/my-tunnel ``` View inbound details: ```bash ztm tunnel describe inbound tcp/my-tunnel ``` View outbound details: ```bash ztm tunnel describe outbound tcp/my-tunnel ``` ## Common Use Cases ### Access Home Server from Anywhere ```bash # On home endpoint ztm tunnel open inbound home-server --listen 0.0.0.0:22 --exits <office-endpoint-id> # On office endpoint ztm tunnel open outbound home-server --targets 192.168.1.10:22 ``` ### Forward Web Service ```bash # Remote endpoint exposes local web service ztm tunnel open outbound web-tunnel --targets 192.168.1.100:80 # Local endpoint listens on port 8080 ztm tunnel open inbound web-tunnel --listen 0.0.0.0:8080 --exits <remote-endpoint-id> ``` ### UDP Tunnel (for DNS, VoIP, etc.) ```bash ztm tunnel open outbound dns-tunnel --targets 8.8.8.8:53 ztm tunnel open inbound dns-tunnel --listen 0.0.0.0:5300 --exits <remote-endpoint-id> ``` ## Troubleshooting Check if ZTM agent is running: ```bash curl http://localhost:7777/api/status ``` Check mesh status: ```bash ztm get mesh ztm get ep ``` Check installed apps: ```bash ztm get app ``` If tunnel app is not installed: ```bash ztm app install tunnel ``` View tunnel app logs: ```bash ztm log app tunnel ``` ## Configuration ZTM CLI config is stored in `~/.ztm.conf`: ```json { "agent": "localhost:7777", "mesh": "my-mesh-name" } ``` Or set via environment: ```bash export ZTM_AGENT=http://localhost:7777 export ZTM_MESH=my-mesh-name ``` ## API Reference For programmatic access, use the ZTM Agent HTTP API: ```bash # Get all tunnels curl http://localhost:7777/api/meshes/{mesh}/apps/ztm/tunnel/api/tunnel # Get inbound tunnels curl http://localhost:7777/api/meshes/{mesh}/apps/ztm/tunnel/api/inbound # Create inbound curl -X POST http://localhost:7777/api/meshes/{mesh}/apps/ztm/tunnel/api/inbound/tcp/tunnel-name \ -H "Content-Type: application/json" \ -d '{"listens":[{"ip":"0.0.0.0","port":9000}],"exits":["endpoint-id"]}' ```

path: README.md
content: # ZTM Tunnel Skills

> Create and manage TCP/UDP tunnels through ZTM's P2P mesh network.

OpenClaw Skill for managing TCP/UDP tunnels via ZTM (Zero Trust Mesh).

## What is this?

This is an **OpenClaw Skill** that provides tunnel management capabilities using ZTM's tunnel app. It allows you to create secure P2P port forwarding through the ZTM mesh network.

## What is ZTM?

**ZTM (Zero Trust Mesh)** is an open-source decentralized network software built on HTTP/2 tunnels. It provides:

- 🔒 End-to-end encrypted P2P connections
- 🌐 Cross-firewall/firewall NAT traversal
- 📡 No central server required (truly decentralized)
- 🚀 High performance (built on Pipy, written in C++)

Learn more: https://github.com/flomesh-io/ztm

## Features

- Create TCP/UDP tunnels between ZTM endpoints
- Expose local services to remote endpoints
- Port forwarding through the mesh network
- Access remote services as if they were local

## Prerequisites

1. **ZTM CLI** installed
2. **ZTM Agent** running and joined to a mesh
3. **Tunnel app** installed

## Quick Start

### Step 1: Install ZTM

```bash
# Run the installation script
./install.sh

# Or manually download from https://github.com/flomesh-io/ztm/releases
```

### Step 2: Start ZTM Agent

```bash
ztm start agent
```

### Step 3: Join a Mesh

```bash
# If you have a permit file
ztm join <mesh-name> --as <your-name> --permit permit.json

# Or create a new mesh
ztm start hub --listen 0.0.0.0:8888 --names your-public-ip:8888 --permit root.json
```

### Step 4: Install Tunnel App

```bash
ztm app install tunnel
```

### Step 5: Create a Tunnel

**Scenario:** Expose a local web service (port 8080) to another endpoint

```bash
# On the remote endpoint (where you want to access from)
# First, create outbound (target) side:
ztm tunnel open outbound my-web --targets 192.168.1.100:8080

# On the local endpoint (where the service is running)
# Create inbound (listening) side:
ztm tunnel open inbound my-web --listen 0.0.0.0:9000 --exits <remote-endpoint-id>
```

Now you can access the local service by connecting to port 9000 on the remote endpoint!

## Commands

### List Tunnels

```bash
# List all tunnels in mesh
ztm tunnel get tunnel

# List inbound (listening) tunnels
ztm tunnel get inbound

# List outbound (target) tunnels
ztm tunnel get outbound
```

### Create Tunnel

```bash
# Create inbound (listening) end
ztm tunnel open inbound <name> --listen <ip>:<port> --exits <endpoint-id>

# Create outbound (target) end  
ztm tunnel open outbound <name> --targets <host>:<port>
```

### Delete Tunnel

```bash
# Close inbound
ztm tunnel close inbound <name>

# Close outbound
ztm tunnel close outbound <name>
```

### Describe Tunnel

```bash
ztm tunnel describe tunnel tcp/<name>
```

## Use Cases

### Remote Access to Home Server

```bash
# On home endpoint
ztm tunnel open inbound home-ssh --listen 0.0.0.0:2222 --exits <office-endpoint-id>

# On office endpoint
ztm tunnel open outbound home-ssh --targets 192.168.1.10:22
```

### Forward Web Service

```bash
# Remote endpoint
ztm tunnel open outbound web --targets 192.168.1.100:80

# Local endpoint
ztm tunnel open inbound web --listen 0.0.0.0:8080 --exits <remote-endpoint-id>
```

### UDP Tunnel (DNS, VoIP, etc.)

```bash
ztm tunnel open outbound dns --targets 8.8.8.8:53
ztm tunnel open inbound dns --listen 0.0.0.0:5300 --exits <remote-endpoint-id>
```

## Configuration

ZTM CLI config is stored in `~/.ztm.conf`:

```json
{
  "agent": "localhost:7777",
  "mesh": "your-mesh-name"
}
```

Or use environment variables:

```bash
export ZTM_AGENT=http://localhost:7777
export ZTM_MESH=your-mesh-name
```

## Troubleshooting

```bash
# Check if agent is running
curl http://localhost:7777/api/status

# Check mesh status
ztm get mesh

# Check endpoints
ztm get ep

# Check installed apps
ztm get app

# View tunnel logs
ztm log app tunnel
```

## API Reference

For programmatic access, use the ZTM Agent HTTP API:

```bash
# Get all tunnels
curl http://localhost:7777/api/meshes/{mesh}/apps/ztm/tunnel/api/tunnel

# Get inbound tunnels
curl http://localhost:7777/api/meshes/{mesh}/apps/ztm/tunnel/api/inbound
```

## License

MIT License - see LICENSE file for details.

## Links

- [ZTM GitHub](https://github.com/flomesh-io/ztm)
- [ZTM Documentation](https://flomesh.io/ztm/docs)
- [OpenClaw](https://github.com/flomesh-io/openclaw)
- [Pipy](https://github.com/flomesh-io/pipy)


path: install.sh
content: #!/bin/bash
# ZTM Tunnel Skill Installation Script
# This script installs ZTM and configures it for use with the ztm-tunnel skill

set -e

# Colors
RED='\033[0;31m'
GREEN='\033[0;32m'
YELLOW='\033[1;33m'
BLUE='\033[0;34m'
NC='\033[0m' # No Color

echo -e "${BLUE}🔌 ZTM Tunnel Skill Installer${NC}"
echo "=================================="

# Check if running on macOS or Linux
OS=$(uname -s)
if [[ "$OS" != "Darwin" && "$OS" != "Linux" ]]; then
    echo -e "${RED}❌ Unsupported OS: $OS${NC}"
    exit 1
fi

# Detect architecture
ARCH=$(uname -m)
case "$ARCH" in
    x86_64)
        ZTM_ARCH="generic_linux-x86_64"
        ;;
    arm64|aarch64)
        ZTM_ARCH="generic_linux-arm64"
        ;;
    *)
        echo -e "${RED}❌ Unsupported architecture: $ARCH${NC}"
        exit 1
        ;;
esac

echo -e "${YELLOW}📦 Step 1: Checking ZTM installation...${NC}"

# Check if ztm is already installed
if command -v ztm &> /dev/null; then
    ZTM_VERSION=$(ztm version 2>/dev/null | head -1 || echo "unknown")
    echo -e "${GREEN}✅ ZTM already installed: $ZTM_VERSION${NC}"
else
    echo -e "${YELLOW}📥 Installing ZTM...${NC}"
    
    # Create temp directory
    TEMP_DIR=$(mktemp -d)
    cd "$TEMP_DIR"
    
    # Get latest version from GitHub
    LATEST_VERSION=$(curl -s https://api.github.com/repos/flomesh-io/ztm/releases/latest | grep -o '"tag_name":.*' | cut -d'"' -f4)
    
    if [[ -z "$LATEST_VERSION" ]]; then
        echo -e "${RED}❌ Could not get latest ZTM version${NC}"
        exit 1
    fi
    
    echo -e "${BLUE}   Latest version: $LATEST_VERSION${NC}"
    
    # Download
    FILENAME="ztm-aio-${LATEST_VERSION}-${ZTM_ARCH}.tar.gz"
    DOWNLOAD_URL="https://github.com/flomesh-io/ztm/releases/download/${LATEST_VERSION}/${FILENAME}"
    
    echo -e "${BLUE}   Downloading $DOWNLOAD_URL...${NC}"
    
    if curl -L -o "$FILENAME" "$DOWNLOAD_URL" 2>/dev/null; then
        # Extract
        tar -xzf "$FILENAME"
        
        # Install to /usr/local/bin (requires sudo)
        if [[ -w /usr/local/bin ]]; then
            mv bin/ztm /usr/local/bin/ztm
            chmod +x /usr/local/bin/ztm
        else
            echo -e "${YELLOW}   Note: Need sudo to install to /usr/local/bin${NC}"
            sudo mv bin/ztm /usr/local/bin/ztm
            sudo chmod +x /usr/local/bin/ztm
        fi
        
        echo -e "${GREEN}✅ ZTM installed successfully!${NC}"
    else
        echo -e "${RED}❌ Failed to download ZTM${NC}"
        exit 1
    fi
    
    # Cleanup
    cd /
    rm -rf "$TEMP_DIR"
fi

# Verify installation
echo -e "${YELLOW}🔍 Step 2: Verifying ZTM...${NC}"
ztm version

echo -e "${YELLOW}🚀 Step 3: Starting ZTM Agent...${NC}"

# Check if agent is already running
if curl -s http://localhost:7777/api/status &> /dev/null; then
    echo -e "${GREEN}✅ ZTM Agent is already running${NC}"
else
    echo -e "${BLUE}   Starting ZTM Agent on localhost:7777...${NC}"
    
    # Start agent in background
    ztm start agent
    
    # Wait for agent to be ready
    echo -e "${BLUE}   Waiting for agent to be ready...${NC}"
    for i in {1..30}; do
        if curl -s http://localhost:7777/api/status &> /dev/null; then
            echo -e "${GREEN}✅ ZTM Agent is ready!${NC}"
            break
        fi
        sleep 1
    done
    
    if ! curl -s http://localhost:7777/api/status &> /dev/null; then
        echo -e "${RED}❌ Failed to start ZTM Agent${NC}"
        exit 1
    fi
fi

echo -e "${YELLOW}📱 Step 4: Checking Tunnel App...${NC}"

# Install tunnel app if not already installed
ztm get app 2>/dev/null | grep -q "ztm/tunnel"
if [[ $? -eq 0 ]]; then
    echo -e "${GREEN}✅ Tunnel app is already installed${NC}"
else
    echo -e "${BLUE}   Installing tunnel app...${NC}"
    ztm app install tunnel
    echo -e "${GREEN}✅ Tunnel app installed!${NC}"
fi

echo -e "${YELLOW}⚙️  Step 5: Configuration...${NC}"

# Create default config if not exists
ZTM_CONF="$HOME/.ztm.conf"
if [[ ! -f "$ZTM_CONF" ]]; then
    echo -e "${BLUE}   Creating default config at $ZTM_CONF${NC}"
    cat > "$ZTM_CONF" << 'EOF'
{
  "agent": "localhost:7777",
  "mesh": ""
}
EOF
    echo -e "${GREEN}✅ Default config created${NC}"
else
    echo -e "${BLUE}   Config already exists at $ZTM_CONF${NC}"
fi

echo ""
echo -e "${GREEN}🎉 Installation complete!${NC}"
echo ""
echo "Next steps:"
echo "  1. Join a mesh network (if not already joined):"
echo "     ztm join <mesh-name> --as <your-name> --permit <permit-file.json>"
echo ""
echo "  2. List tunnels:"
echo "     ztm tunnel get tunnel"
echo ""
echo "  3. Create a tunnel:"
echo "     ztm tunnel open outbound my-tunnel --targets 192.168.1.100:8080"
echo "     ztm tunnel open inbound my-tunnel --listen 0.0.0.0:9000 --exits <endpoint-id>"
echo ""
echo "For more commands, see: ztm help"


Security scan verdicts — ClawScan: suspicious | static analysis:  | VirusTotal: clean | SkillSpector: suspicious (HIGH)