tui-tools

tui-network

Links, addresses, routes and DNS, with every change previewed before it runs

A terminal UI (TUI) for networkctl, dnsmasq and kea-dhcp4 on Linux: the machine's network.

v0.3.2betanetworkMIT
The links table: state, type, address, gateway and who manages each link
The links table: state, type, address, gateway and who manages each link

A terminal UI for the machine's network. It shows the links you have — state, type, addresses, gateway, MAC, MTU and driver — with the routing table, what systemd-resolved uses for DNS, and the .network file behind each link.

Open a link and you get the whole picture in one screen: its addresses and where each came from, its routes, DNS servers and search domains, DHCP lease, the .network file that configures it, and what systemd-networkd said about it in the journal.

Changes are previewed. Bringing a link up or down, reconfiguring it, renewing a lease, setting DNS at runtime, and editing a .network file — a unified diff, then an install and a reload — all go through a confirm dialog carrying the exact command line. A link systemd-networkd does not manage is shown read-only with the reason.

The D screen reads the router's DHCP server — dnsmasq, Kea or networkd's own [DHCPServer] — with its pools, leases and reservations, w switches the default route or fails over, and V builds a VLAN or a bridge as a .netdev unit.

Run tui-network --demo to drive a sample machine: every key works, every command is previewed for real, and nothing touches your system.

Keys

KeyAction
enterOpen the selected link
u / dBring the link up or take it down
cReconfigure the link from its .network file
nRenew the link's dynamic lease
eEdit the link's .network file, with a diff to confirm
VCreate a VLAN or a bridge: a .netdev unit and its member .network lines
XRemove the selected VLAN or bridge, if tui-network wrote its unit
s / SSet the link's DNS servers or search domains
DOpen the router's DHCP screen: pools, reservations and leases
a / xOn the DHCP screen: add or remove a reservation (dnsmasq, systemd-networkd)
pOn the DHCP screen: adjust a pool's range (dnsmasq, systemd-networkd)
oSet advertised DHCP options and, on systemd-networkd, the lease time
wOpen the Gateways screen: the machine's uplinks and the default route
s / xOn the Gateways screen: set the default route or fail over to a standby uplink
POn the Gateways screen: make an uplink's priority persistent (networkd drop-in)
fFlush the resolver cache
rReload the networkd configuration files
/Filter links across every column
RRe-read the network
?Help
qQuit

Press ? inside the tool for the full help screen, which is generated from the same action table as the key map.

Compatibility

This tool is a face on the program below, so its version matters. Tested is not a claim: a version lands there only after the tool's own suite passed against it on a real machine in the lab, and the run is kept as evidence in the repository. At startup the tool probes the backend once and says what it found in its header — a version nobody has run against is shown as (untested) in the warning colour, one older than the minimum as (below minimum) in the error colour. Neither stops it: the backend still refuses what it cannot do, in its own words.

systemd-networkd

networkctl ≥ 245
Binary
networkctl
Minimum
245
Probed with
networkctl --version
Tested
255257259261

Needs a version this new

  • json-statussince 249
  • link-up-downsince 249
  • dhcp-server-leasessince 246
  • dhcp-static-leasesince 249

What changes on older versions

  • systemd-networkd <249

    networkctl --json does not exist, so the columns of networkctl list and the Key: value block of networkctl status are parsed instead; addresses carry no prefix length there, and the DHCP lease clock is not reported at all

  • systemd-networkd <249

    networkctl up and down do not exist; the keys are dropped from the hint bar and reconfigure is offered in their place

  • systemd-networkd >=245

    no released systemd emits JSON from resolvectl status, so DNS servers and search domains are read from the text output of resolvectl dns and resolvectl domain

  • systemd-networkd >=245

    the Gateways screen (w) reads the default routes from ip -j route (multipath expanded per next hop) and reachability from ip -j route get; the default-route switch and failover run ip route replace live, and a managed link also gets a persistent [Route] drop-in reloaded with networkctl

  • systemd-networkd >=245

    VLANs and bridges (V) are written as a .netdev unit under /etc/systemd/network plus a VLAN= or Bridge= line in each member's .network file, previewed as one multi-file diff, installed with install -m 644 and applied with a single networkctl reload; X removes a unit tui-network wrote with rm -f

  • systemd-networkd >=245

    the DHCP screen (D) also reads systemd-networkd's own DHCP server, the one a [DHCPServer] section in a .network unit turns on: the pool derived from Address= with PoolOffset=/PoolSize=, the lease time, the advertised DNS, NTP, router and domain, and the static leases

  • systemd-networkd >=245

    a change to that server is written to a drop-in of the tool's own (<unit>.network.d/50-tui-network-dhcp.conf), rendered whole and applied with networkctl reload; the unit itself is never rewritten, and each advertised list is cleared before it is set because a drop-in's DNS= adds to the unit's

  • systemd-networkd >=245

    [DHCPServer] has no key for the domain (EmitDomains= belongs to [IPv6SendRA]), so tui-network emits it as the raw option it is, SendOption=15:string:<domain>

  • systemd-networkd <246

    networkctl status does not print the "Offered DHCP leases" list (systemd 246 added it), so a networkd DHCP server shows its pool and its static leases but no live ones

  • systemd-networkd <249

    [DHCPServerStaticLease] does not exist (systemd 249 added it), so a static lease written on an older systemd is read back by the screen but ignored by the server

dnsmasq

dnsmasq ≥ 2.80
Binary
dnsmasq
Minimum
2.80
Probed with
dnsmasq --version
Tested
No recorded run yet. The tool still runs and reports the version it found as untested.

What changes on older versions

  • dnsmasq >=2.80

    the DHCP screen reads the lease file (/var/lib/misc/dnsmasq.leases), the dhcp-range pools and dhcp-host reservations from the configuration, and dnsmasq serves DNS and DHCP from one process, so the resolver view on the links screen is only what systemd-resolved reports

  • dnsmasq >=2.80

    reservations tui-network adds are written to a drop-in of its own (/etc/dnsmasq.d/tui-network.conf) and applied with systemctl reload dnsmasq; a pool range change needs systemctl restart dnsmasq, which briefly interrupts DNS and DHCP

  • dnsmasq >=2.80

    Advertised DHCP options (DNS, gateway, domain) and upstream server= forwarders are edited through the tool's own drop-in (/etc/dnsmasq.d/50-tui-network.conf), regenerated whole; lines the tool does not own are never touched. Applying restarts dnsmasq.

kea

kea-dhcp4 ≥ 2.0.0
Binary
kea-dhcp4
Minimum
2.0.0
Probed with
kea-dhcp4 -V
Tested
No recorded run yet. The tool still runs and reports the version it found as untested.

What changes on older versions

  • kea >=2.0.0

    the DHCP screen reads Kea's pools and host reservations from its JSON config (/etc/kea/kea-dhcp4.conf, // and /* */ comments stripped) and its leases from the memfile CSV (/var/lib/kea/kea-leases4.csv); Kea is read-only here, so the add, remove and pool-range keys are not offered

Maintain systemd-networkd, dnsmasq or kea? You are welcome to help shape this tool. About → maintainers

Install

Once per machine, then every tool in the family is one pacman away.

Add the repository
$ curl -fsSL https://pkgs.tui.tools/install.sh | sh
Or run the same thing yourself, one command at a time

A family whose whole promise is preview before you run is not going to insist you pipe a script into a shell. These are the commands that script runs.

The one-time setup, by hand
$ curl -fsSL -o /tmp/tui-tools.asc https://pkgs.tui.tools/pubkey.asc
  sudo pacman-key --add /tmp/tui-tools.asc
  sudo pacman-key --lsign-key \
    "$(gpg --show-keys --with-colons /tmp/tui-tools.asc | awk -F: '/^fpr:/{print $10; exit}')"
  printf '[tui-tools]\nServer = https://pkgs.tui.tools/arch/$arch\n' \
    | sudo tee -a /etc/pacman.conf
  sudo pacman -Sy
Arch Linux · tui-network
$ sudo pacman -S tui-network

Upgrades then arrive with the rest of your system updates.

What it can do to your machine

  • Preview, then confirm

    Every change is shown as an exact command line and confirmed before it runs. The dialog and the runner receive the same value, so the preview cannot drift from what executes.

  • Escalates for actions

    Reads are unprivileged: networkctl list, resolvectl dns and ip route answer to any user. Escalation is sudo -n, which never prompts: the 0640 .network file netplan renders, and every change — up/down, reconfigure, renew, DNS, install, remove a .netdev unit, reload.

  • No daemon, no state of its own

    Nothing keeps running after you quit, and nothing is installed to run later. The system is the source of truth; the tool re-reads it after every change.

  • No network access

    The tool opens no network connection of its own. No telemetry, no update check, no phone home.

  • Static binary

    Released statically linked, with no runtime dependencies to install.

  • Signed release, with provenance

    checksums.txt carries a keyless cosign signature from this repository's release workflow, every archive has a CycloneDX SBOM, and every archive, package and the checksum file carry SLSA build provenance. The security page shows the three commands that check it.

Reporting

Report a security issue privately, through GitHub's private vulnerability reporting on the repository's Security tab. The family-wide policy, and what counts as in scope, is on the security page.

Downloads

v0.3.2 · 2026-09-25
FileSizeSHA-256
checksums.txt1 KB—
checksums.txt.sigstore.json10 KB—
provenance.intoto.jsonl12 KB—
tui-network-0.3.2-1-aarch64.pkg.tar.zst1.9 MB2af9e4afc7059d8b35d2fee9884c194abb6dbe22a78cbd84991a068749715789
tui-network-0.3.2-1-x86_64.pkg.tar.zst2.1 MBd88957c18c5cec27c41a8bc119267fd5c2655350ff8a5ddf553bc451435e3e39
tui-network-0.3.2-1.aarch64.rpm1.9 MB54e7bd32e5b43fa5821119b372bf6718ff1a62345f281b0b062cddb03e66d267
tui-network-0.3.2-1.x86_64.rpm2.0 MB529ce81c397a03b27e190642878821ddf9b9fe8a88e1f4eea57a06d7fadde1f1
tui-network_0.3.2_amd64.deb2.0 MBa109b1e40e187c5ee874ef5573fa67919b7e5c869e7ffc8d074ba0373dfd6ee4
tui-network_0.3.2_arm64.deb1.9 MB144695b599cfbf7cab30e9677a317240144ab3b41b92ee68b6a3a433bf9d2bdf
tui-network_0.3.2_linux_amd64.tar.gz2.0 MB6954ea8fcb2198e0b91149b56264a66a6116588b094b652675fe759fc13e05ff
tui-network_0.3.2_linux_amd64.tar.gz.cyclonedx.json24 KB781010663a49c41ec73bcd45588ccbd91264b64263247fd36a79062ea77e2eef
tui-network_0.3.2_linux_arm64.tar.gz1.9 MBf9c16ce89be6d2ab6f307d5936b00ffe3fd1c45085e1e51686653da15c649a67
tui-network_0.3.2_linux_arm64.tar.gz.cyclonedx.json24 KBbf0aefc5ce6f6b3f56765ceeeb87095009ce290805ee564759272d3dea2c10b6

Every release ships a checksums.txt. Download it next to the archive and run sha256sum -c checksums.txt --ignore-missing. See verifying a download.

Releases

v0.3.2

2026-09-25
## tui-network v0.3.2

tui-network 0.3.2: tui-kit v0.4.4

tui-network 0.3.2 moves to tui-kit v0.4.4: every networkctl, resolvectl and ip command now runs in its own session without a controlling terminal, so a step that would prompt fails at once instead of hanging behind the UI, and a failed step reports its meaningful line, cleaned of escape codes. Command previews are POSIX shell-quoted (a routing-only domain now reads as `'~corp.test'`), the README screenshots are re-rendered with continuous box borders, and the README banner now carries the kit's stability markers.

Built by this repository's CI on the tag itself. Each archive ships a
CycloneDX SBOM, `checksums.txt` carries a keyless cosign signature, and
every file has SLSA build provenance — see the README's "Verify a
download" for the two commands that check them.

The commits in this release:

## Changelog
* f5f016bfd562bdbd5e7e8ad4010d4c45122d0d06 0.3.2: tui-kit v0.4.4 (#23)
* e1439a5408d4f5b74a59583074a0fd262bf508d1 Bump anchore/sbom-action/download-syft (#4)
* b0d67073e621af67f17b0ba3524bdd96ee743ecf Bump anchore/sbom-action/download-syft in the github-actions group (#20)
* 062b650ca39f8b7a1db0f05c1080108012c08378 Bump the github-actions group with 4 updates (#22)
* f4b3c970089e346bc396cd92f3f51baff0d7d918 README: link the tool's page on tui.tools (#19)
* d87236ab410080218b9b6d9f499f1e63ad936dd4 README: point the install snippet at the current release (#18)

v0.3.1

2026-09-02
## tui-network v0.3.1

Manage the DHCP server systemd-networkd runs, not just dnsmasq and Kea.

Also: tui-kit v0.3.0 — dialogs wrap and scroll instead of clipping the
command preview, and the picker filters as you type.

Built by this repository's CI on the tag itself. Each archive ships a
CycloneDX SBOM, `checksums.txt` carries a keyless cosign signature, and
every file has SLSA build provenance — see the README's "Verify a
download" for the two commands that check them.

The commits in this release:

## Changelog
* cd962f628498c2479de06184dd8aa4e01104089d Bump tui-kit to v0.3.0 (#17)
* b372c6271ea48a3f713d0cbb4b8d45d5d158770a Manage the DHCP server systemd-networkd runs, not just dnsmasq and Kea (#16)

v0.3.0

2026-09-01
## tui-network v0.3.0

Manage, not view (wave 3): create what does not exist, edit what does; lab-validated.

Built by this repository's CI on the tag itself. Each archive ships a
CycloneDX SBOM, `checksums.txt` carries a keyless cosign signature, and
every file has SLSA build provenance — see the README's "Verify a
download" for the two commands that check them.

The commits in this release:

## Changelog
* 87f6ebd8078e27dcab39c6e2596e37762f17265a Create VLANs and bridges from the TUI (#15)

v0.2.0

2026-09-01
## tui-network v0.2.0

Manage, not view: create and edit from the TUI (wave 1), lab-validated on the router image.

Built by this repository's CI on the tag itself. Each archive ships a
CycloneDX SBOM, `checksums.txt` carries a keyless cosign signature, and
every file has SLSA build provenance — see the README's "Verify a
download" for the two commands that check them.

The commits in this release:

## Changelog
* 600ead8c142ed75ae11c904677bcd201dde725c8 A code of conduct that fits on one screen (#10)
* f81a933fe4ad40a47bdf3181cee87275c47676f4 Add --report, and a bug form that asks for it (#11)
* 2bfe7f2eee64cc1f5e41cac496415b2b58e059f6 Add DHCP and DNS server screen for the router profile (#12)
* 2c5b802b4428fd96688be4aa1c996f049262f4ba Add a Gateways screen: switch the default route and fail over between uplinks (#13)
* c3a6d8d55b99e5a57dde42e53fc254e95df3d061 Carry the OpenSSF Best Practices badge (#8)
* fa4cdd084162cd9cddffec77a11dfa829e30abd3 DHCP advertised options and upstream DNS from the UI (#14)
* 9907cb45ee872d275413fb7d66739ee7de8462d9 Fetch the tag annotation before releasing (#6)
* 34a70f7675aa650675e783d8c87fedc720e0f737 Pin what CI runs, fuzz the parsers, and say the releases are signed (#3)
* 809e2c4887bdacad75b44c28659af41876afc43c Print the whole tag message, not only its body (#7)
* 6bbd1da20825c815f961b0ddaed106ef1783c674 Say beta once (#5)
* 7466b4adbde06341ef6d0471172f6b0f3f0cfbcd Take tui-kit v0.2.8: hashed pip install, provenance bundle on the release (#9)

v0.1.2

2026-08-30
## Changelog
* b8fcd816702e9c4271d9206a311a913b8e23fc3b Drop cross-repo dispatch; the package repo and the site poll releases
* b0dbfdfd416fe0aade5b5ed8de1ae1c9fc2802b1 Gate the release on a security job, and sign what it publishes (#2)
* d463b6ea6308324a7a9f839cbbfd83df5de7547d Stop telling readers the packages are unpublished

v0.1.1

2026-08-30
## Changelog
* ccdb2902d759995b7ee43ce29d09bcffe1804a97 Bump the github-actions group with 5 updates (#1)
* a2f49b8122405212975e1d32dbc85d9f212779d9 Packages are available from pkgs.tui.tools
* 9a04b3e925fa33db0f32006d011c699603784bb7 Point the install line at v0.1.0
* a1816df47018de2a0ffabae96d8605de3b0fe15e Re-pin the kit at v0.2.3
* 7c36585f99c3fc9f347113c05d3da44fda406715 Read the .network file netplan hides, and prove it on three machines
* 8d5b3ddc0937100dba0afc4a4cae62416f21cc50 Ship the tool as a .deb, an .rpm and a pacman package
* 0e1fca0d9294a83ab72a2b75d2e6dc0ba130db3b Trim needs_sudo back under the manifest's 300-character cap

v0.1.0

2026-08-30
## Changelog
* 11031373f2496eaf83ff162a27d9d549a04e88bd Give it a face: the branding, six frames and the README
* 8d28b3cd0fcbba62e61c0405d6f6c81f4c5f52c1 Initial commit
* 85ba4845f42a4dd8d438a32a2ded0e7d044ee81b Keep the sudo note inside what the schema allows
* dab17731572c36decbcd75e39d506c94a5bcba66 Prove it against a real machine, and record which one
* 234f591f987db4673aa800d4a991d95d855b8b7f Read the network: the model, the backend and its parsers
* 82dcc79151c850bd5501e5799144e8528eded661 Start tui-network from the family template
* e146699e26eef235870a2a662e6b490064006efb The screens: a link list, a link in full, and one confirm dialog