LofentaLofenta/Docs

Reference

Lofenta Private Network (LPN)

An LPN is a private, encrypted network for your projects. Services on the same network reach each other by name, never over the public internet, even when they run on different nodes or in different regions. You can also connect to an LPN from your own computer over WireGuard, so your local machine reaches your projects as if it were on the same LAN.

New to LPN? Read the plain-language introduction at What is LPN first. This page is the detailed technical reference.


Addressing plan

Every LPN is carved out of 100.64.0.0/10, the RFC 6598 range set aside for carrier-grade private addressing. It does not overlap with your home or office LAN, and it is deliberately separate from Lofenta's own internal range, 10.0.0.0/8, so an LPN address can never be mistaken for a Lofenta-internal one at the packet level.

Each network gets a fixed-size slice of that pool, and each slice is broken down further by node and by purpose:

Pool

The full 100.64.0.0/10 range, shared across every network on the platform.

Per network

A /24, up to 16,384 networks in total.

Per node

A /27 block inside the network's /24, one per node that hosts a member of that network, up to 7 node blocks per network.

Client block

The 8th /27 in the network (.224/27) is reserved for client devices, 29 usable addresses from .225 to .254.

Inside a node's /27

.1 is the gateway, that node's private bridge, .2 to .30 are member projects on that node, .31 is broadcast.

Cross-node routing

Reaching another project on the same node is a single hop, project to bridge to project. Reaching a project on a different node crosses machines, and that is where the routed WireGuard mesh does the work.

Every node hosting at least one member of a network runs a dedicated WireGuard interface for that network, wired to a local Docker bridge carrying that node's member addresses. Nodes peer with each other over that interface, and each peer's AllowedIPs is set to the remote node's /27 block, not a single address. WireGuard treats AllowedIPs as a routing table: when node A needs to reach a member IP that falls inside node B's block, it already knows that block belongs to node B's peer and sends the packet straight there, encrypted, without any routing your application has to think about.

Add or remove a node from a network and the reconcile loop rewrites the peers on every node. The addressing scheme is what keeps that routing correct without manual tables.

DNS naming

Create a named network (for example prod), then attach your projects to it. Every attached project gets a fixed name on that network, in one form:

worker.prod.lpn.lofenta.internal

That name works the same whether both projects run on the same node or on two different nodes entirely, and it resolves for any client connected to the network too. It is DNS, not a proxy or a symlink: each node's local resolver for the network maps the name straight to the member's 100.64 address. A project keeps its normal public URL as well, the private name is additive, not a replacement.

Client access model

You do not have to be a Lofenta project to join an LPN. From a network's page in the dashboard you can add a client, a device identity with its own WireGuard keypair and a 100.64 address from the network's reserved client block.

Key handling is one-shot by design: the server generates the keypair, returns the full config, including the private key, exactly once, and stores only the public key and the assigned IP afterward. If you lose the file you cannot recover the private key, you regenerate it, which issues a new keypair and revokes the old one.

A downloaded config looks like this:

[Interface]
PrivateKey = <yours, shown once>
Address = 100.64.12.230/32
DNS = 100.64.12.1

[Peer]
PublicKey = <node A public key>
Endpoint = <node A public IP>:51900
AllowedIPs = 100.64.12.0/27
PersistentKeepalive = 25

[Peer]
PublicKey = <node B public key>
Endpoint = <node B public IP>:51905
AllowedIPs = 100.64.12.32/27
PersistentKeepalive = 25

Notice there is one [Peer] entry per node that hosts a member of the network, not one entry for the whole network. Each peer's endpoint is that node's public IP and WireGuard listen port, and its AllowedIPs is scoped to that node's own /27. Your computer does not funnel every packet through one central gateway, traffic to a project on node A goes straight to node A, traffic to a project on node B goes straight to node B. Every node carrying a member of the network is a gateway into it, and adding a node to the network appends a peer the next time you regenerate your config.

IP allowlist

The WireGuard listen ports nodes use for LPN (one per network per node, in the 51900 to 52899 range) are not open to the whole internet. A node only completes a handshake with a client whose source IP is on that client's allowlist, every other source is dropped before WireGuard ever sees the packet.

When you add a client, the dashboard can detect your current public IP and prefill it. If your ISP rotates your address later, a one-click "update my IP" on that client keeps the tunnel working, and you can list more than one CIDR if you connect from more than one place. This sits on top of WireGuard's own key-based authentication, not instead of it, a stolen config still cannot be used from an unlisted network.

Isolation model

LPN traffic is isolated on two axes: from Lofenta's own infrastructure, and from every other tenant's network.

From 10.0.0.0/8

Tenant containers are firewall-blocked from 10.0.0.0/8, where Lofenta's own control plane, databases, and mesh live. A matching node rule drops 100.64.0.0/10 → 10.0.0.0/8 outright, so this holds for client traffic too, not only container traffic.

Tenant to tenant

Each node runs an nftables table with a chain per network that only accepts traffic between that network's own bridge and its own WireGuard interface, with a catch-all drop underneath. Two networks can share a node and never reach each other.

Client scoping

Client peers enter through that same isolated pair, and a client's AllowedIPs only ever contains the blocks of networks it was added to. Even before the firewall rule applies, the client's own routing table has no path to another tenant's addresses.

Plans and limits

LPN is free and included on every plan, there is no paywall on the feature itself:

  • Hobby: 3 networks
  • Developer: 5 networks
  • Team: 20 networks
  • Enterprise: 100 networks

Need more than your plan includes, extra networks are available from the add-on marketplace.

Connect a device, step by step

  1. Open the network you want to reach in the dashboard, under LPN.
  2. Click Connect and name the device, for example "My computer".
  3. Confirm or edit the allowlisted IP. The dashboard prefills your current public IP, add more if you connect from elsewhere.
  4. Download the config. This is the only time the private key is shown, save the file somewhere safe.
  5. Import the file into the WireGuard app for your OS and turn the tunnel on.
  6. Confirm it works, for example ping worker.prod.lpn.lofenta.internal or connect a database client straight to a member's private address.
  7. If the tunnel stops working later, click Update my IP on that client in the dashboard, most likely your ISP rotated your address.

Revoke a device from the same client list at any time. Revoking drops its peer from every node immediately.

Set up your first network

Create an LPN, attach your projects, and add a client for your computer, all from the dashboard.