Skip to main content

Secure Tunnels to Private Networks

Tunnels let you access databases, APIs, and services that are behind NAT, in private subnets, or otherwise unreachable from the internet — without a VPN, without exposing public IPs.

How It Works

You (public IP)

│ TCP connection to edge.entryguard.io:41234

Edge Service (public)
│ 1. Check your IP against active sessions
│ 2. Find the agent WebSocket for this tunnel
│ 3. Open a multiplexed stream

Agent (customer's private network)
│ 4. Dial the local target (10.0.1.50:5432)
│ 5. Bidirectional byte proxying

Target Service (10.0.1.50:5432)
  1. An admin creates a tunnel resource pointing to a private target (e.g., 10.0.1.50:5432)
  2. EntryGuard allocates a permanent TCP port on edge.entryguard.io (e.g., port 41234)
  3. The agent in the private network connects outbound to the edge via WebSocket
  4. When a user starts a session, their IP is allowed on that tunnel port
  5. The user connects to edge.entryguard.io:41234 — traffic is proxied through the agent to the target
  6. When the session expires, the IP is revoked and all active connections are terminated
Same access control as everything else

Tunnels use the exact same session model as cloud firewall resources. Time-bounded access, role-based permissions, automatic cleanup, full audit trail.

Prerequisites

  • EntryGuard Paid plan (Free: 0 tunnels, Paid: usage-based at EUR 6/tunnel/mo)
  • Agent version v0.5.3 or later (earlier versions have a stream registration bug that causes connections to drop)
  • An agent running in the private network with tunnel mode enabled
  • An API key with the agent:connect scope

Setup

1. Install and Initialize the Agent

Follow the standard Agent Installation & Setup to install eg-agent and run eg-agent init.

2. Configure the Agent

To enable tunnel mode, edit the config file at /etc/eg-agent/config.yml (Linux) or C:\eg-agent\config.yml (Windows) and add the tunnel section:

server:
url: "https://app.entryguard.io/api/v1"
api_key: "eg_..."

agent:
name: "prod-agent"

tunnel:
enabled: true
edge_url: "wss://edge.entryguard.io"
One agent, multiple capabilities

A single agent handles both script commands and tunnel connections concurrently. Script commands are polled from EntryGuard (with script directories configured per resource), while tunnel streams flow through a WebSocket connection to the edge service. Each mode operates independently.

3. Restart the Agent

sudo systemctl restart eg-agent

You should see in the logs:

[tunnel] connecting to edge at wss://edge.entryguard.io
[tunnel] connected to edge at wss://edge.entryguard.io
[tunnel] targets updated: [10.0.1.50:5432]

4. Create a Tunnel Resource in EntryGuard

In the dashboard:

  1. Go to Resources → Add Resource
  2. Select provider: AGENT
  3. Select resource type: Tunnel
  4. Select your agent credential
  5. Enter a name (e.g., production-db)
  6. Fill in the config:
    • Target Host: The private IP or hostname (e.g., 10.0.1.50)
    • Target Port: The port to connect to (e.g., 5432)
  7. Click Create

EntryGuard will allocate a permanent TCP port on edge.entryguard.io. The connection string appears in the resource list:

edge.entryguard.io:41234 → 10.0.1.50:5432

5. Assign to a Role

Add the tunnel resource to a role so users can access it through sessions:

  1. Go to Roles → Edit Role
  2. Add the tunnel resource
  3. Assign users to the role

6. Connect

Start a session (dashboard, CLI, or API), then connect to the tunnel:

# Start a session
eg session start --duration 4

# Connect to the tunnel
psql -h edge.entryguard.io -p 41234 -U myuser -d mydb

The CLI shows tunnel connection details:

✓ Session started

Tunnel resources:
production-db edge.entryguard.io:41234

Session expires in 4h 0m

One Agent, Multiple Tunnels

A single agent can serve multiple tunnels. Each tunnel gets its own port:

Private network 10.0.1.0/24
├── PostgreSQL 10.0.1.50:5432 → edge.entryguard.io:41234
├── Redis 10.0.1.51:6379 → edge.entryguard.io:41235
└── Internal API 10.0.1.100:8080 → edge.entryguard.io:41236


Single Agent ── WebSocket ──→ Edge Service

Each tunnel is a separate resource — assign them to different roles to control who can access what.

Connection String Never Changes

The port allocated to a tunnel is permanent. It stays the same regardless of agent restarts, edge restarts, or configuration changes. Your connection strings and tooling configs are stable.

Static IP Rules & Guest Access on Tunnels

Tunnels support all access methods — not just sessions:

  • Sessions — Users start a session and their auto-detected IP is allowed on the tunnel
  • Static IP Rules — Permanently allow an IP or CIDR range on a tunnel (e.g., 0.0.0.0/0 for open access, or 10.0.0.0/8 for a VPN range)
  • Guest Access — Grant temporary access to a specific IP or CIDR range

CIDR ranges work with tunnels. For example, creating a static rule with 0.0.0.0/0 on a tunnel resource allows all IPs to connect — useful for development environments or resources behind an additional authentication layer.

Combining access methods

Static IP rules on tunnels are great for always-on access for CI/CD runners or monitoring systems, while sessions handle dynamic developer access. Both can coexist on the same tunnel.

Session Expiry Behavior

When a session expires or is stopped:

  1. The IP is immediately removed from the tunnel's allowlist
  2. All active TCP connections from that IP are terminated — the user sees a connection reset
  3. New connections from that IP are silently rejected

This matches EntryGuard's promise of time-bounded access. Database clients handle disconnections gracefully — start a new session and reconnect.

Security

LayerProtection
IP allowlistOnly IPs with active sessions can connect to tunnel ports
Role-based accessUsers only see tunnels assigned to their roles
Agent target allowlistThe agent only dials targets configured as tunnels — prevents network scanning
TLSAgent ↔ Edge communication is encrypted (WebSocket over TLS)
Forced terminationActive connections are killed on session expiry
User ↔ Edge is raw TCP

The connection between the user and the edge service is raw TCP. Encryption is the application's responsibility (e.g., PostgreSQL sslmode=require, Redis TLS, HTTPS for APIs).

Troubleshooting

Agent can't connect to edge

Check that the agent can reach edge.entryguard.io:443 outbound:

curl -v https://edge.entryguard.io/health

Common issues:

  • Corporate proxy blocking WebSocket upgrades
  • Firewall blocking outbound port 443
  • Incorrect edge_url in config (must be wss://, not https://)

Connection refused on tunnel port

  • Verify the agent is connected (check agent status in the dashboard)
  • Verify you have an active session
  • Check your public IP matches the session IP

Connection resets immediately

  • Agent version too old — versions before v0.5.3 have a race condition where the first data packet is dropped, causing the connection to fail silently. Upgrade to v0.5.3+
  • Session may have expired — check remaining time
  • The target service may be down — agent logs will show dial failures