# How to Set Up Cloud Tunnels for Remote Access in OmniRoute: A Complete Guide

> Learn to set up cloud tunnels for remote access with OmniRoute using Cloudflare Quick Tunnel, Ngrok, or Tailscale Funnel. Get secure remote access to your local HTTP API.

- Repository: [Diego Rodrigues de Sa e Souza/OmniRoute](https://github.com/diegosouzapw/OmniRoute)
- Tags: how-to-guide
- Published: 2026-08-01

---

**OmniRoute exposes its local HTTP API to the internet through three built-in tunnel backends—Cloudflare Quick Tunnel, Ngrok, and Tailscale Funnel—using child process management and REST API controls.**

The OmniRoute repository provides a complete tunnel subsystem that runs under `src/lib/` and `src/app/api/tunnels/`, allowing you to create secure public URLs for your local instance without complex network configuration.

## Architecture Overview

The tunnel implementation spans multiple modules designed for production reliability. According to the OmniRoute source code, each backend runs as a **child process** that forwards traffic from a public URL to your local HTTP port (default `20128`).

The core implementations reside in:
- **[`src/lib/cloudflaredTunnel.ts`](https://github.com/diegosouzapw/OmniRoute/blob/main/src/lib/cloudflaredTunnel.ts)** – Manages Cloudflare Quick Tunnel lifecycle
- **[`src/lib/ngrokTunnel.ts`](https://github.com/diegosouzapw/OmniRoute/blob/main/src/lib/ngrokTunnel.ts)** – Handles Ngrok authentication and connection management  
- **[`src/lib/tailscaleTunnel.ts`](https://github.com/diegosouzapw/OmniRoute/blob/main/src/lib/tailscaleTunnel.ts)** – Controls Tailscale Funnel daemon operations

Each module parses the child process stdout to capture the public URL, storing state in JSON files like [`quick-tunnel-state.json`](https://github.com/diegosouzapw/OmniRoute/blob/main/quick-tunnel-state.json). The REST API layer under `src/app/api/tunnels/` exposes this functionality through standardized endpoints, while the CLI (`omniroute tunnel`) provides a thin wrapper around these APIs as implemented in `bin/cli/commands/tunnel.mjs`.

## Prerequisites and Backend Selection

Before you set up cloud tunnels for remote access, choose the appropriate backend for your security requirements:

- **Cloudflare Quick Tunnel** – Requires no account or authentication token; ideal for temporary access
- **Ngrok** – Requires `NGROK_AUTHTOKEN` environment variable; offers persistent URLs and advanced traffic inspection
- **Tailscale Funnel** – Requires Tailscale account and device enrollment; integrates with your private mesh network

All backends respect OmniRoute's security model. The route guard in [`src/server/authz/routeGuard.ts`](https://github.com/diegosouzapw/OmniRoute/blob/main/src/server/authz/routeGuard.ts) enforces loopback-only access for sensitive operations, ensuring that OAuth callbacks and administrative functions remain inaccessible from the public tunnel URL.

## Setting Up Cloud Tunnels

### Cloudflare Quick Tunnel (No Account Required)

The fastest method to enable remote access uses Cloudflare's free Quick Tunnel service. This backend spins up a temporary HTTPS URL without registration.

Start via CLI:

```bash
omniroute tunnel create cloudflared

```

Or enable via REST API:

```bash
curl -X POST http://localhost:20128/api/tunnels/cloudflared \
  -H "Content-Type: application/json" \
  -d '{"action": "enable"}'

```

The response includes your public endpoint:

```json
{
  "tunnelUrl": "https://violet-cloud.trycloudflare.com",
  "apiUrl": "http://127.0.0.1:20128",
  "status": "running"
}

```

### Ngrok Tunnel (Authentication Required)

For production environments requiring persistent domains, use the Ngrok backend. First export your authentication token:

```bash
export NGROK_AUTHTOKEN="your_token_here"
omniroute tunnel create ngrok

```

The [`src/lib/ngrokTunnel.ts`](https://github.com/diegosouzapw/OmniRoute/blob/main/src/lib/ngrokTunnel.ts) module handles token validation and connection persistence. Check status programmatically:

```bash
curl http://localhost:20128/api/tunnels/ngrok

```

Response includes the assigned domain and process details:

```json
{
  "tunnelUrl": "https://abcd1234.ngrok.io",
  "apiUrl": "http://127.0.0.1:20128",
  "pid": 12345,
  "logPath": "/home/user/.omniroute/ngrok.log"
}

```

### Tailscale Funnel (Mesh Network Integration)

For teams already using Tailscale, the Tailscale backend in [`src/lib/tailscaleTunnel.ts`](https://github.com/diegosouzapw/OmniRoute/blob/main/src/lib/tailscaleTunnel.ts) manages the entire lifecycle—installation, login, and funnel enablement. This method exposes your API through your Tailscale network's public HTTPS endpoints while maintaining Zero Trust security policies.

## CLI Commands for Tunnel Management

The `omniroute tunnel` command family provides comprehensive control as defined in `bin/cli/commands/tunnel.mjs`:

```bash

# Display active tunnels with URLs, PIDs, and log locations

omniroute tunnel list

# Stop the currently running tunnel and clean up child processes

omniroute tunnel stop

# Rotate to a new URL (Cloudflare) or restart with existing config (Ngrok)

omniroute tunnel restart

```

These commands interact directly with the state files and process management logic in the `src/lib/` tunnel modules.

## REST API Endpoints

The tunnel subsystem exposes RESTful endpoints under `/api/tunnels/<backend>` supporting CRUD operations:

**Enable a tunnel:**

```http
POST /api/tunnels/cloudflared HTTP/1.1
Host: localhost:20128
Content-Type: application/json

{ "action": "enable" }

```

**Disable a tunnel:**

```http
POST /api/tunnels/ngrok HTTP/1.1
Host: localhost:20128
Content-Type: application/json

{ "action": "disable" }

```

**Check status:**

```http
GET /api/tunnels/tailscale HTTP/1.1
Host: localhost:20128

```

The dashboard automatically prefers the tunnel's public URL over hard-coded `NEXT_PUBLIC_BASE_URL` values when displaying API configuration, as documented in the Tunnels Guide.

## Programmatic Control

Import tunnel utilities directly for custom automation scripts:

```typescript
import { startCloudflaredTunnel, stopCloudflaredTunnel } from '@omniroute/tunnels';

// Start tunnel and await public URL
const { tunnelUrl } = await startCloudflaredTunnel();
console.log('Public URL →', tunnelUrl);

// Clean shutdown when application exits
await stopCloudflaredTunnel();

```

This pattern utilizes the same process management logic that powers the CLI and REST layers, ensuring consistent behavior across interfaces.

## Security Considerations

OmniRoute implements defense-in-depth for tunnel-exposed services. The route guard tier system documented in [`src/server/authz/routeGuard.ts`](https://github.com/diegosouzapw/OmniRoute/blob/main/src/server/authz/routeGuard.ts) restricts process-spawning endpoints (like OAuth callbacks) to `localhost` only, preventing external tunnel users from triggering sensitive operations.

Additionally, tunnel state files (e.g., [`quick-tunnel-state.json`](https://github.com/diegosouzapw/OmniRoute/blob/main/quick-tunnel-state.json)) store URL and PID information locally without exposing authentication credentials. The child process architecture isolates tunnel binaries from the main application runtime, limiting blast radius if a tunnel provider binary is compromised.

## Summary

- **OmniRoute supports three tunnel backends**: Cloudflare Quick Tunnel, Ngrok, and Tailscale Funnel, implemented in [`src/lib/cloudflaredTunnel.ts`](https://github.com/diegosouzapw/OmniRoute/blob/main/src/lib/cloudflaredTunnel.ts), [`src/lib/ngrokTunnel.ts`](https://github.com/diegosouzapw/OmniRoute/blob/main/src/lib/ngrokTunnel.ts), and [`src/lib/tailscaleTunnel.ts`](https://github.com/diegosouzapw/OmniRoute/blob/main/src/lib/tailscaleTunnel.ts).
- **Two control methods**: Use the CLI (`omniroute tunnel create`) or REST API (`POST /api/tunnels/<backend>`) to manage tunnels.
- **Security by default**: Loopback-only restrictions in [`src/server/authz/routeGuard.ts`](https://github.com/diegosouzapw/OmniRoute/blob/main/src/server/authz/routeGuard.ts) protect sensitive routes even when exposed via public URL.
- **Programmatic access**: Import tunnel modules directly for Node.js automation using `@omniroute/tunnels`.

## Frequently Asked Questions

### How do I choose between Cloudflare Quick Tunnel and Ngrok?

**Cloudflare Quick Tunnel** requires no account setup and provides instant temporary URLs, making it ideal for quick demos or debugging sessions. **Ngrok** requires an authentication token but offers persistent URLs, custom domains, and traffic inspection tools suitable for production webhooks. Choose Cloudflare for zero-configuration temporary access and Ngrok for stable, long-term integrations.

### Where does OmniRoute store tunnel state and logs?

The system stores tunnel metadata in JSON state files (such as [`quick-tunnel-state.json`](https://github.com/diegosouzapw/OmniRoute/blob/main/quick-tunnel-state.json)) located in your OmniRoute data directory, while process logs write to paths like `/home/user/.omniroute/ngrok.log` as indicated in API responses. These files contain the public URL, process PID, and connection status, but never store authentication tokens or sensitive credentials.

### Can I run multiple tunnels simultaneously?

The current architecture in `src/app/api/tunnels/` manages one active tunnel per backend type at a time. While you can switch between backends (Cloudflare, Ngrok, Tailscale), running multiple instances of the same backend simultaneously requires stopping the current tunnel first via `omniroute tunnel stop` or `POST {action: "disable"}` to prevent port conflicts on the local HTTP port 20128.

### Is remote access through tunnels secure for production use?

Yes, when combined with OmniRoute's route guard system. Even though the public tunnel exposes your API to the internet, sensitive endpoints that spawn child processes or handle OAuth flows remain restricted to `localhost` per [`src/server/authz/routeGuard.ts`](https://github.com/diegosouzapw/OmniRoute/blob/main/src/server/authz/routeGuard.ts). For production deployments, use Ngrok with authentication or Tailscale Funnel to maintain audit logs and access controls.