Peios Learn
Products
PePeios pkpekit PvProvium UDUniversal Directory TrTrail PrProject WiWispist
Using Peios Security Basics Technical Documentation Source
Using Peios Security Basics Technical Documentation Source
Peios

Networking

Single-page view · as markdown

Networking

Peios / Using Peios / Networking

A Peios machine's network is described in the registry and made real by one service, netd. There is no ifconfig step, no interface file, no daemon-specific configuration format: what the network should be is written under Machine\System\Network, and netd keeps the kernel matching it.

This page explains the model. Configuring profiles covers writing the configuration; The net command covers looking at the result.

The registry is the truth #

netd is a reconciler. It reads the desired state — profiles from the registry, plus whatever leases its DHCP clients currently hold — compares it with what the kernel reports over rtnetlink, and applies the difference. It does this on start, whenever the kernel reports a change (a cable plugged in, an interface appearing), whenever the registry changes, and whenever a DHCP lease arrives or expires.

Two consequences follow, and both are deliberate:

  • A manual change to a managed interface is reverted. Adding an address by hand lasts until the next reconcile. The way to change the network is to change the registry.
  • Restarting netd changes nothing visible. It re-derives the same desired state, finds the kernel already matches, and does nothing. Interfaces do not flap.

netd owns what it configured and nothing else. Addresses on a managed interface are all netd's; routes are netd's only when they carry its routing-protocol tag, so a route another program adds for itself is left alone.

Profiles match interfaces #

Configuration is not written per interface, because interface names are not stable across kernels and an image is built before its hardware is known. Instead a profile is a match rule with the configuration to apply to whatever it matches: by name, MAC address, bus path, driver or type, with one * wildcard allowed. netd evaluates every profile against every interface, highest priority first, and the first whose match keys all hold wins.

Nothing is "activated". A profile that matches two interfaces configures both; an interface no profile matches is left alone. A default profile shipped with the image claims every Ethernet interface for DHCP, at a priority low enough that anything you write outranks it.

The inventory #

netd writes what it finds under Machine\System\Network\Interfaces\<ifid>: the kernel name, MAC, bus path, driver, type, and which profile won. The interface id is derived from the bus path and MAC, so the same card in the same slot keeps the same key across boots however the kernel names it. One value there is yours: Enabled, which takes an interface down and keeps it down regardless of its profile.

Nothing transient is stored in the registry — not leases, not link state, not learned DNS servers. net status shows those.

Addresses #

A profile gets its addresses three ways, and they combine:

  • DHCPv4, on by default. netd runs its own client on each interface once it has carrier. The lease's address, gateway, classless routes, DNS servers and MTU are applied; the address is remembered on disk so the next boot asks for the same one first.
  • Static addresses in CIDR form, with an optional gateway that overrides DHCP's.
  • Link-local (169.254/16), self-assigned when DHCP discovery goes unanswered, so two machines on a cable with no server can still talk. Discovery continues, and the link-local address is dropped when a lease arrives.

When a lease expires and cannot be renewed the address is dropped by default: the server may have given it to someone else, and an address conflict is worse than no address. A profile can choose to keep it instead.

Readiness is a level, not a boolean #

"The network is up" means different things to different services. netd reports each interface at one of four levels — absent, link (up with carrier), addressed (has an address), routed (has a default route) — and the machine's level is the highest among its managed interfaces. net wait routed blocks until there is a default route; a service definition will be able to declare which level it needs.

What netd does not do #

  • Names. netd never answers a DNS query. It tells resolvd, live, what each interface contributes — servers, search domains, addresses — and resolvd routes every name to one interface's servers. Nothing is written to /etc/resolv.conf or /etc/hosts; see name resolution.
  • Firewalling. Traffic policy is a separate component.
  • Port ownership. Who may bind a port is a kernel decision under Machine\System\Network\TcpIp\PortReservations.
  • WiFi association. A wireless supplicant brings the link up; netd treats the result like any other interface.
  • IPv6 autoconfiguration. The kernel's own router-advertisement handling applies for now.

Where to start #

  • Configuring profiles — write a profile, static or DHCP, and see it take effect.
  • The net command — status, levels, renewals.
  • regman Machine\System\Network on a Peios machine documents every key netd reads.

Configuring profiles

Peios / Using Peios / Networking

A profile is a subkey of Machine\System\Network\Profiles. Its Match subkey says which interfaces it claims; Address and DNS say what to do with them. netd watches the subtree, so a change takes effect within a moment of the write — no restart, no reload command.

Every key and value is documented on the machine: regman Machine\System\Network\Profiles.

See what you have #

net status
net profile list
reg ls Machine/System/Network/Profiles

net status shows each interface with the profile that claimed it. An image's default profile, ethernet, claims every Ethernet interface for DHCP at priority 10.

A static address #

Claim the interface by its bus path (from net status, stable across boots) and give it an address and gateway:

reg new Machine/System/Network/Profiles/office
reg set Machine/System/Network/Profiles/office Priority dword:100
reg new Machine/System/Network/Profiles/office/Match
reg set Machine/System/Network/Profiles/office/Match Path pci-0000:00:03.0
reg new Machine/System/Network/Profiles/office/Address
reg set Machine/System/Network/Profiles/office/Address DHCP4 dword:0
reg set Machine/System/Network/Profiles/office/Address Static multi:10.0.0.5/24
reg set Machine/System/Network/Profiles/office/Address Gateway 10.0.0.1
reg new Machine/System/Network/Profiles/office/DNS
reg set Machine/System/Network/Profiles/office/DNS Servers multi:10.0.0.1

Priority 100 outranks the default profile's 10, so office wins for that interface and DHCP stops. net status shows the new address and level routed once the default route is in place.

Match keys #

Every value present under Match must hold; a profile with no match keys matches nothing. Comparison ignores case and allows one *.

ValueMatchesExample
Namethe kernel's interface nameenp*
MACthe hardware address52:54:00:*
Paththe bus path from the inventorypci-0000:00:03.0
Driverthe kernel drivervirtio_net
Typeether, wlan, loopback, otherether

Prefer Path or MAC for a specific machine and Type or Driver for a class. Name is the least stable: the kernel may call the same card something else after a hardware change.

DHCP with adjustments #

The default profile is DHCP with everything from the lease. To keep DHCP but pin DNS, or to hold the address across an outage:

reg set Machine/System/Network/Profiles/ethernet/DNS UseFromDHCP dword:0
reg set Machine/System/Network/Profiles/ethernet/DNS Servers multi:1.1.1.1,9.9.9.9

Two more DNS values decide which names an interface's servers are asked for, which matters the moment a second interface appears — typically a VPN:

reg set Machine/System/Network/Profiles/vpn/DNS SearchDomains multi:corp.example
reg set Machine/System/Network/Profiles/vpn/DNS DNSDefaultRoute dword:1
reg set Machine/System/Network/Profiles/vpn/DNS DNSExclusive dword:1

SearchDomains sends names under corp.example to this interface's servers. DNSDefaultRoute sends every other name there too (unset, an interface claims that only when it carries the default route). DNSExclusive goes further: while this interface is up, no other interface's servers are consulted for anything — the "ultimate protection" a VPN wants, and the setting that stops a hostile LAN from advertising the VPN's own domain. See name resolution. reg set Machine/System/Network/Profiles/ethernet/Address OnLeaseExpiry Keep


`OnLeaseExpiry Keep` trades the risk of an address conflict for continuity; the default `Drop` is the safe choice.

## Prefer a cable over WiFi

Both interfaces get a default route; the metric decides which is used. Wired defaults to 100 and wireless to 600, so no configuration is needed. To invert it, set `RouteMetric` on the profiles.

## Hand an interface to something else

`Managed` off means netd never touches a matched interface — no addresses, no routes, no link changes, no DHCP:

reg new Machine/System/Network/Profiles/leave-alone reg set Machine/System/Network/Profiles/leave-alone Priority dword:200 reg new Machine/System/Network/Profiles/leave-alone/Match reg set Machine/System/Network/Profiles/leave-alone/Match Name tap0 reg set Machine/System/Network/Profiles/leave-alone Managed dword:0


## Take an interface down

`Enabled` in the inventory is the persistent switch, independent of the profile:

reg set Machine/System/Network/Interfaces/ Enabled dword:0


The interface id is in `net status`. Set it back to 1 to bring the interface up again.

## Set the hostname

reg set Machine/System/Network Hostname workshop


netd applies it on the next pass. A profile with `AcceptHostname` on adopts a DHCP-supplied name when this value is unset.

## Where to go next

- [The net command](~peios/networking/the-net-command) — read back what netd did.
- [Networking](~peios/networking/overview) — the model behind these keys.

The net command

Peios / Using Peios / Networking

net talks to netd over /run/netd/control.sock. It shows state and pokes the daemon; it does not change configuration — that is a registry write, and Configuring profiles covers it.

Commands #

CommandDoes
net statusHostname, the machine's readiness level, and every interface: profile, link state, level, hardware identity, addresses, gateway, DNS, lease.
net wait <level> [seconds]Block until the machine reaches link, addressed or routed, or the timeout (default 60) passes. For scripts that need the network.
net renew <interface>Renew the DHCP lease now. Accepts a kernel name or an interface id.
net reconcileRe-run the reconciler immediately rather than waiting for an event.
net profile listThe profiles in the registry with their priorities.

Reading net status #

hostname  workshop
level     routed

enp0s3  [3f2a…]
  profile   ethernet
  state     up, carrier
  level     routed
  hardware  52:54:00:12:34:56 pci-0000:00:03.0 virtio_net
  address   10.0.2.15/24
  gateway   10.0.2.2
  dns       10.0.2.3
  lease     bound from 10.0.2.2, 86395s left

level is the readiness level: absent (down or no carrier), link, addressed, routed. The machine's level is the highest among managed interfaces. state also reports unmanaged (the profile has Managed off) or disabled (Enabled is 0 in the inventory).

The bracketed value after the name is the interface id — the inventory key under Machine\System\Network\Interfaces.

Who may run it #

The control object is a security descriptor: Machine\System\Network\ControlSecurity, or a compiled default when that is unset. status, wait and profile list need NETWORK_QUERY, which the default grants to everyone. renew and reconcile need NETWORK_CONTROL, which the default grants to SYSTEM and Administrators. A denied request reports access denied.

Exit status #

CodeMeaning
0Done; for wait, the level was reached.
1netd refused or could not be reached; for wait, the timeout passed.
2Usage error.

See also #

  • Networking
  • Configuring profiles
  • regman Machine\System\Network on the machine, for every key netd reads.

Name resolution

Peios / Using Peios / Networking

Every name a program asks for on a Peios machine is answered by one process: resolvd, the stub resolver. It is a DNS client — it does not recurse and it is not a server — and it is the only source of host resolution, the way authd is the only source of identity.

Three doors #

A program reaches resolvd one of three ways, and gets the same answer by each:

  • getaddrinfo — glibc's hosts database is fixed to libnss_peios_net.so.2, which forwards to resolvd. There is nothing to configure in nsswitch.conf and nothing behind it: no files, no dns.
  • DNS on 127.0.0.53 — for programs that resolve without libc (a Go binary, a musl program). /etc/resolv.conf is a constant file pointing here; it is never regenerated and carries no server list.
  • The native socket — /run/resolvd/resolv.sock, for Peios tools and resolv, which get records with TTLs, where the answer came from, and a validation state.

A bare printer typed into a Go program is expanded with the same search domains, sent to the same server and cached in the same place as one from a C program.

Where the servers come from #

netd tells resolvd what each interface contributes — servers, search domains, addresses, whether it carries the default route — over its control socket, live. Nothing about that is in the registry, and nothing is in a file. resolv status shows the picture:

hostname   workshop
netd       connected
cache      12 entries

eth0  metric 100  [default-route]
  server   10.0.2.3
  domain   lan
  subnet   10.0.2.15/24

A name goes to one interface's servers, never to all of them:

  1. an exclusive interface, if one is up (a VPN with DNSExclusive = 1 takes everything);
  2. the interface whose search domain the name ends with — git.corp goes to the VPN that supplied corp;
  3. for a reverse lookup, the interface whose subnet holds the address;
  4. otherwise the interface with the default route.

That is what stops a VPN's names leaking to the coffee-shop network. Only when no interface supplies servers does resolvd use Machine\System\Network\Resolver Servers.

A single-label name is only ever asked with a search domain appended; with none to apply it is simply not found, and no query leaves the machine. A name with a dot in it is never expanded.

Static names #

There is no /etc/hosts. Put static names in the registry:

reg new Machine/System/Network/Resolver/Hosts
reg set Machine/System/Network/Resolver/Hosts printer 10.0.2.9

resolvd answers printer at every door — including the DNS door, so the Go binary sees it too — and 10.0.2.9 reverses to printer. An entry here wins over DNS. localhost, the machine's own hostname, and their reverses are answered without configuration.

.local names are never sent to a DNS server (they belong to mDNS, which resolvd does not yet speak), and LLMNR is never used.

The resolv command #

CommandWhat it does
resolv statusScopes, servers (with any currently demoted), cache size, counters.
resolv query <name> [type]One question. Prints the outcome, the source (synthetic, hosts, cache, dns via which server on which interface), and the records. Exit 0 found, 2 not found, 3 unavailable.
resolv lookup <name>The addresses of a name as getaddrinfo sees them, with the canonical name.
resolv reverse <address>The names of an address.
resolv flushDrop the cache (administrators).

resolv query tells you three things dig cannot: whether the answer was cached, which interface's server gave it, and — once resolvd validates — whether it was DNSSEC-secure. Today every network answer reports unvalidated.

Not found versus unavailable #

resolvd keeps two things apart that /etc/hosts-era stacks blur. A name that a server says does not exist is not found, and is remembered for a few minutes. A name that could not be resolved because every server timed out or refused is unavailable: it is never cached, and programs see "try again" rather than "no such host", so an outage is not remembered as a fact.

What is not there yet #

DNSSEC validation, DNS over TLS and mDNS are not in this version; Resolver\Policy is reserved for them. Per-program resolution policy is not either — the native socket knows who is asking, so it can be added without changing the wire.

Peios Learn — documentation for the Peios project.

Built with Trail.