Docs / Networking

Networks

Bridges are what guests attach to, and everything else on this section assumes one exists. Creating external and internal networks, what reconciliation does, and the properties you can only set once.

Every guest attaches to a bridge. The bridge decides which subnet the guest gets an address from, whether that address is handed out by DHCP, what search domain its name lives in, and whether the network is carried across the cluster.

So this page comes first: firewall rules name a bridge, and DNS records are derived from one.

Two kinds of network

The choice is made once, with --type, and it decides who routes the traffic.

--type external --type internal
Guests sit on your physical LAN a subnet private to this host
Addresses from your existing range from a range you define
Gateway your existing router the host itself
Needs a --child-interface yes, the uplink no
Reachable from the LAN directly only through the host

External is a bridge over a real NIC: guests appear on the office network like physical machines. Internal makes the host the gateway for a private subnet — the default for guests that should not be visible on the LAN, and what the installer sets up as hoster-internal.

Internal networks are also the ones worth marking --route-over-wg, so a private subnet on one host can reach a private subnet on another.

Looking at what exists

hoster network list           # the configured networks
hoster network list --json
hoster network status         # desired vs actual, with drift
hoster network status --json

list shows the configuration. status shows the reconciliation state — for each bridge: whether it should be enabled, whether it actually exists, its operational state, any drift between the two, and warnings. It ends with the last apply’s timestamp, mode, and error if there was one.

That distinction is the useful part. list tells you what you asked for; status tells you what the kernel actually has, and drift is the gap between them.

Screenshot

Take a screenshot of `hoster network list` and `hoster network status` on a host with an internal and an external network, ideally with one bridge showing drift.

Creating a network

An external bridge over a physical NIC:

hoster network create \
  --type external \
  --name office-lan \
  --bridge-address 192.168.118.214 \
  --gateway 192.168.118.254 \
  --subnet 192.168.118.0/24 \
  --range-start 192.168.118.215 \
  --range-end 192.168.118.225 \
  --child-interface eno1 \
  --dns-server 1.1.1.1 \
  --dns-server 8.8.8.8 \
  --dns-search-domain office.lan \
  --description "Office LAN"

An internal, routed one:

hoster network create \
  --type internal \
  --name hoster-private \
  --bridge-address 10.0.5.254 \
  --subnet 10.0.5.0/24 \
  --range-start 10.0.5.10 \
  --range-end 10.0.5.200 \
  --dns-search-domain private.lan \
  --dhcp \
  --route-over-wg \
  --description "Private guest network"

--name and --subnet are required; everything else has a default or is optional.

Flag Default Notes
--type external external or internal
--name required; the bridge interface name
--subnet required; CIDR, e.g. 10.0.5.0/24
--bridge-address the host’s own address on this network
--gateway ignored for internal networks, which gateway themselves
--range-start / --range-end the pool guests are allocated from
--child-interface uplink; repeat the flag for several
--dns-server repeat the flag for several
--dns-search-domain the domain guest names live in
--dhcp off run a DHCP server for this network
--route-over-wg off carry this network across the cluster mesh
--default-gateway off make this bridge the host’s default route
--stp off spanning tree, for a bridge with several uplinks
--enabled on create it without bringing it up with --enabled=false
--description shown in list

Rules that are checked

Validation runs before anything touches the host, and the messages name the field:

  • The bridge name must be a valid Linux interface name — alphanumerics, hyphens and underscores, within the length limit.
  • The bridge address, the gateway, and both ends of the range must all fall inside the subnet.
  • The range start must come before the range end.

Internal networks gateway themselves

Create one with --type internal and the host becomes the gateway: the network’s gateway is set to the bridge address, and the address is applied to the bridge whether you asked for it or not. Passing --gateway on an internal network is pointless — it gets overwritten.

What create actually does

It is not just a configuration write. In one command:

  1. Validate the bridge, and the change against the existing configuration.
  2. Persist it.
  3. Reconcile the host: create the bridge, enslave the child interfaces, apply addresses, and adjust the default route if this bridge claims it.
  4. Reload the services that depend on it — DHCP and DNS.

It rolls back if the apply fails

If reconciliation fails partway, the previous configuration is restored, host networking is reverted to it, and the dependent services are reloaded again. You get the original error back. If the rollback itself fails, the error says so explicitly rather than leaving you guessing which state you are in.

That is a real difference from the firewall, which applies immediately with no rollback. Networking gets you back; the firewall does not. Both are still worth a console when you are working over the link you are changing.

For a preview before committing to anything, reconcile everything as a dry run:

hoster network init --dry-run    # print the planned changes
hoster network init              # bring all configured bridges to their desired state

init is also what makes a fresh boot come up correctly — it reconciles every bridge from the configuration rather than depending on what survived.

Changing one afterwards

This is the part to read before designing your networks.

hoster network enable  office-lan
hoster network disable office-lan
hoster network delete  office-lan
hoster network set     office-lan --stp=true

hoster network set can only change STP. It takes exactly one flag, --stp. The subnet, the DHCP range, the DNS search domain, the DNS servers, the child interfaces, --route-over-wg, --default-gateway and the description are all create-time only on the CLI.

UpdateNetworkBridge exists in HosterLib and the agent API exposes a full update at /api/v1/host/network/config/, so Control Center can edit any of it. From a terminal, changing a network means editing the host network configuration by hand, or deleting and recreating the bridge — which detaches the guests on it.

This bites hardest on the search domain: a bridge with no search domain generates no DNS records at all, and adding one to an existing bridge is the fix — with no CLI to apply it.

Plan the search domain and the routing flags at creation, not afterwards.

One-off addresses outside the range

hoster network add-ip hoster-internal 10.0.5.240

Adds a single allowed address to a bridge without widening the allocation range — for the one guest that has to have a specific address that sits outside the pool. It is idempotent and says so when the address is already allowed.

Where the CLI stops short of the model

Three properties exist in the network model and in the reconciler, with no flag to set them:

Workload isolation has no CLI flag, and CLI-created networks never get it. A network carries an isolation_mode of disabled, observe or enforce, with reconciliation and dedicated API endpoints behind it. hoster network create never writes the field, and the persistence layer only normalises it when it is already set — so a network created from the CLI is persisted with no mode and resolves to disabled. The same network created through Control Center can be typed and enforced.

Two paths to the same object with different security postures, and nothing in the CLI output says which one you got.

--type uses a different vocabulary from the stored model. The flag accepts internal or external; the model’s network_type is internal_shared, internal_private or external. create never writes network_type at all — it only sets the “I am the gateway” boolean, and the type is inferred back from that, which can only ever produce internal_shared. internal_private is unreachable from the CLI.

--vlan-id does not exist. The reconciler fully supports an access VLAN — given a VLAN id and exactly one child interface it creates the parent.id interface and enslaves that — but there is no flag to set the id, so VLAN-backed bridges cannot be created from the CLI.

And one flag that does nothing:

--apply-address is ignored. Whatever you pass, persistence overwrites it: forced on for internal networks, and set to “is there a bridge address” for external ones. --apply-address=false on a bridge with an address does not stop the address being applied.

When a network is not working

hoster network status          # start here — drift and warnings name the bridge
hoster network init --dry-run  # what reconciliation would change
hoster network init            # make it so

In order:

  1. Is the bridge enabled and does it exist? status answers both, separately — a bridge that is desired but absent is a different problem from one that exists and is down.
  2. Does the child interface exist? A bridge with a missing uplink comes up with no path out. VLAN parents are checked by name and fail explicitly.
  3. Is the address inside the subnet? Validation catches this at create time, but a hand-edited configuration file will not have been through it — run hoster network init --dry-run.
  4. Did the last apply fail? status prints the last error under the table.
  5. Are guests getting addresses? That is DHCP, which is reloaded when a network changes — hoster service restart dhcp.
  6. Do names resolve? See when names do not resolve; the first check there is the search domain that lives on this bridge.

Next

  • Firewall — the rules that decide what may cross the network you just built.
  • DNS and the WireGuard mesh — where the search domain and --route-over-wg set here actually take effect.
  • Your first VM — attaching a guest with --network.

Something unclear on this page?

Ask about this specific page and we will come back to you. Your question arrives with a link to it, so you do not have to describe where you were.