Back to Blog
Technical July 15, 2026

Zero Inbound Ports: Inside the Mezite Reverse Tunnel Architecture

A technical exploration of why Mezite agents use reverse tunnels to connect to the control plane, eliminating inbound firewall rules and simplifying cluster deployments.

When designing an infrastructure access platform, the first challenge you encounter is connectivity. How does a user’s terminal reach a server sitting deep inside a private network, behind layers of firewalls and NAT?

The traditional approach requires opening an inbound port on the target node’s firewall and routing traffic through a bastion host. This forces administrators to manage complex, ever-changing firewall rules, inadvertently exposing their infrastructure to potential network scans.

We refuse to accept this operational tax. For Mezite, we mandate a zero-trust network model where target nodes never expose listening ports to the outside world. Instead, we use a reverse tunnel architecture.

Here is a technical look at why we made this decision and how we implement it securely in Go.

The Friction of Inbound Connectivity

Requiring inbound ports creates immediate friction for deployment and security.

First, it breaks the principle of least privilege at the network layer. If a node exposes port 22 to the internet or a wide internal subnet, it becomes a target for opportunistic scanning and zero-day exploitation.

Second, it complicates multi-cloud and hybrid environments. If your fleet spans AWS, GCP, and on-premise data centers, routing inbound traffic from a central proxy to those nodes requires managing complex VPC peering, VPNs, or exposing internal IPs.

These challenges create operational overhead that slows down engineering teams and increases the attack surface.

The Reverse Tunnel Solution

In the Mezite architecture, the lightweight node agent (mezd) never listens for incoming connections from the central proxy (mezhub). Instead, when the agent starts, it proactively dials out to the proxy.

This outbound connection becomes the transport layer for a reverse tunnel. The proxy multiplexes SSH sessions into this existing tunnel, pushing bytes down to the agent without ever needing to initiate a new TCP connection to the node.

The operational benefits are immediate:

  1. Zero inbound firewall rules. The node only needs outbound internet access to reach the central proxy.
  2. NAT traversal is free. Because the node initiates the connection, it works flawlessly across NAT gateways, egress proxies, and strict network boundaries.
  3. Hidden infrastructure. The node’s IP address remains entirely private. It does not exist on the public internet.

Multiplexing Over Reverse Tunnels

To make this work, we need a way to run multiple distinct SSH sessions over a single TLS connection. We cannot simply write raw bytes to the socket, because the proxy and agent must differentiate between concurrent sessions.

We rely on stream multiplexing. The agent connects to the proxy, authenticates, and establishes a secure TLS tunnel. Over this single underlying connection, the proxy can open multiple independent logical “channels.”

When a user initiates an SSH session to a node, the proxy looks up the active reverse tunnel for that node’s agent in its thread-safe tunnelRegistry.

server/proxy/tunnel_registry.go (Simplified) go
// tunnelRegistry is a thread-safe in-memory registry mapping hostnames to
// agent tunnel connections.
type tunnelRegistry struct {
mu     sync.RWMutex
agents map[string]*agentTunnel
}

To prevent security risks like hostname collisions (where a malicious actor might try to hijack a tunnel by claiming an existing hostname), the registry binds the agent’s identity to the tunnel at issue time.

server/proxy/tunnel_registry.go (Simplified) go
// agentTunnel represents a connected agent's reverse tunnel.
type agentTunnel struct {
hostname string
// agentID identifies the agent instance behind this tunnel.
agentID  string
sshConn  ssh.Conn
// ...
}

Once the proxy locates the correct agentTunnel, it opens a new logical stream over that tunnel and transparently copies bytes between the user’s connection and the agent stream.

Handling Reconnection and State

A reverse tunnel architecture pushes the burden of state management from the network layer into the application layer. The proxy must maintain a registry of active tunnels to route connections properly.

Furthermore, networks are inherently unreliable. Tunnels drop, load balancers terminate idle connections, and nodes reboot. The agent must handle these failures gracefully. We implement retry loops in the tunnel_client to ensure it continuously attempts to re-establish the tunnel if the connection drops.

server/agent/tunnel_client.go (Simplified) go
// The agent continuously attempts to connect to the proxy
for {
  err := c.connectAndServe(ctx)
  if err != nil {
      c.logger.Warn("tunnel disconnected, retrying", zap.Error(err))
  }

  // Exponential backoff before retrying
  time.Sleep(backoffDuration)
}

Meanwhile, the proxy actively monitors the health of the tunnels. If the proxy detects a dead tunnel, it prunes it from the registry, preventing new connections from hanging indefinitely.

The Edge Recording Advantage

An additional benefit of this architecture ties directly into our session recording design. As discussed in a previous post, Mezite pushes session recording to the edge (Node-mode recording).

Because the agent acts as the SSH server over the reverse tunnel, it natively controls the PTY and can capture a perfectly clean stream of terminal data at the edge. The proxy simply routes the encrypted packets, remaining a high-throughput router without the overhead of PTY parsing.

(Note: For agentless OpenSSH nodes that cannot use reverse tunnels, we fall back to proxy-mode recording, trading performance for compatibility.)

Conclusion

By reversing the direction of connection establishment, we eliminate the need for inbound firewall rules and simplify the deployment model of Mezite. The complexity of managing state and multiplexing is well worth the massive operational win for administrators. It transforms infrastructure access from a networking headache into a seamless, secure process.


MT

Mezite Team

Engineering