Markdown

Publishing

Network tunnels

A tunnel lets MainPath reach servers behind a firewall or NAT without exposing SSH to the internet.

On this page

Setup, deployments (project images and Docker apps), and installing monitoring all need SSH access to the server. If the server sits on a company network, behind NAT, or behind a firewall that does not open port 22, a public host is not enough. In the Servers tab, under Network tunnels, you create a tunnel and assign it to the server.

Several servers may share the same tunnel, for example one company VPN for many internal hosts. An organization can have at most five tunnels. The private network of workspaces stays separate; do not mix Tailscale there with these tunnels.

Which type to use

Type Good fit when
SSH jump / bastion You already have a publicly reachable jump host through which internal hosts are reachable over SSH
Reverse SSH The target server must not accept inbound SSH and opens the connection itself
WireGuard MainPath should join your existing WireGuard network as a client
OpenVPN MainPath should join your existing OpenVPN network as a client

The server Host is then the address behind the tunnel, for example 10.0.1.20 or a name on the LAN. HTTP and HTTPS on the server stay public if you serve websites from it.

Creating a tunnel

  1. Open Servers in the sidebar.
  2. Under Network tunnels, click Add tunnel.
  3. Enter a name and a short id, choose the type, and fill in the fields.
  4. Save. Test connection checks whether the tunnel is up; the card shows connected, connecting, or error.

Only organization administrators create or change tunnels. OpenVPN and WireGuard configuration plus the OpenVPN username are visible to admins; passwords and jump keys stay write-only. An update replaces them.

A failed test shows a short summary and, under Technical details, the OpenVPN log.

SSH jump

Enter the bastion host, port, and user, and store the private key (recommended) or a password. MainPath jumps through that host to the internal server.

Reverse SSH

The server on your network starts the connection. After saving, MainPath shows a ready-made command. You see the private key only once; copy it to the server and run the command there (for example as a systemd unit). While that process runs, MainPath can reach the internal SSH service.

WireGuard and OpenVPN

Paste the client configuration (.conf or .ovpn). For OpenVPN you can also store a username and password if your server requires them. MainPath connects as a client; you do not need to install a VPN service on the app server itself.

Assigning a server

When you create or edit an SSH, cloud, or managed server, choose the tunnel under Access via tunnel (optional). Without an assignment MainPath keeps using direct public SSH.

Once a tunnel is set, MainPath addresses on a public SSH port are no longer required if SSH stays closed to the internet. The optional SSH firewall and the tunnel complement each other: the firewall limits who may knock on the public port; the tunnel is the path when that port does not exist.

Monitoring

Monitor server installs the agent through the same tunnel. Afterwards the agent connects outbound to monitoring on its own; the tunnel is no longer needed for that as long as HTTPS from your network to MainPath is allowed.

CLI and agent

mp platform servers tunnels list
mp platform servers tunnels get <tunnel-id>
mp platform servers tunnels test <tunnel-id>
mp platform servers tunnels test <tunnel-id> --dest-host 10.0.1.20 --dest-port 22
mp platform servers tunnels create --type ssh --slug office-jump --name "Office Jump" \
  --configuration-json '{"sshKind":"jump","jumpHost":"bastion.example","jumpPort":"22","jumpUser":"jump","jumpAuthMethod":"key","jumpPrivateKey":"<private-key>"}'
mp platform servers update <server-id> \
  --configuration-json '{"tunnelId":"<tunnel-id>"}'

Set tunnelId to none to clear the assignment. The same steps are available to the agent as platform_tunnels_*; deletion requires confirm=true. CLI details are under CLI and agent plugin.