How To

Set a Static IP on ZimaOS and ZimaBoard (Dashboard, nmcli, VLAN)

A NAS that moves around the LAN breaks everything pointed at it: SMB mappings, app bookmarks, the reverse proxy entry, the backup job that talks to it at 2 a.m. ZimaOS takes a DHCP lease by default, so the fix is a ZimaOS static IP, and there are two ways to set one. The dashboard route takes a minute. The nmcli route is the one you need when the dashboard is out of reach, or when you want something the dashboard can’t do, like a VLAN.

Original content from computingforgeeks.com - post 172187

This guide sets a static IP address on a ZimaBoard 2 (paid link) from Settings > Network, then does the same with nmcli, adds a tagged VLAN 30 interface on the other port, and ends with rollback and recovery for a board that drops off the network. It picks up where our ZimaBoard 2 setup guide stops (SSH access comes from Developer mode in that guide). The same steps should carry over to a ZimaCube or ZimaBlade, since they run the same ZimaOS build (our ZimaBoard 2 even reports BOARD="ZimaCube" in /etc/os-release).

Ran all of this on our ZimaBoard 2 with ZimaOS 1.7.1 in September 2026, with a reboot after every change and one lockout we caused ourselves.

1. Check the current ZimaOS network settings

Pick the address before touching anything. It has to sit inside your LAN subnet and outside the router’s DHCP pool, or the router will eventually hand the same address to a phone. Our values:

SettingLAN portVLAN 30 (eth0)
IP address192.168.1.19172.20.30.19
Subnet mask255.255.255.0 (/24)255.255.255.0 (/24)
Gateway192.168.1.1none
DNS192.168.1.1none

Open the dashboard, click the gear icon for Settings, and choose Network. The Connection list shows each port with its link speed and addressing mode. On a fresh install the plugged port reads DHCP with the leased address next to it (192.168.1.106 on ours):

ZimaOS Settings Network page showing eth0 on DHCP 192.168.1.106

From an SSH session the same picture comes from NetworkManager. The Ethernet row you care about is the one with connected in the STATE column:

nmcli device status

eth0 was carrying the DHCP profile NetworkManager generated at boot, while eth1 had no cable yet. Docker, libvirt and ZeroTier interfaces fill the rest of the list:

DEVICE          TYPE      STATE                   CONNECTION
eth0            ethernet  connected               Wired connection 1
thunderboltbr0  bridge    connected               thunderboltbr0
zt3j2g3ido      tun       connected (externally)  zt3j2g3ido
lo              loopback  connected (externally)  lo
tun0            tun       connected (externally)  tun0
docker0         bridge    connected (externally)  docker0
virbr0          bridge    connected (externally)  virbr0
eth1            ethernet  unavailable             --                 

Remember that connection name, because it is the first thing that changes once you save a static address.

There are two ways to set the address, and you only need one. Option A in step 2 uses the dashboard. Option B in step 3 does the same job with nmcli from a console, for when you would rather skip the GUI or can’t reach it. Step 4 adds the VLAN, which only nmcli can do, and step 5 covers rollback for both options.

2. Option A: Set a static IP from ZimaOS Settings > Network

Click the three-dot menu at the right end of the Ethernet row for the port you’re on. A dialog titled eth0-Ethernet opens with separate IPv4 and IPv6 panels. Under Configure IPv4, switch from DHCP to Manual.

Manual mode pre-fills the fields with the current lease (IP, 255.255.255.0 mask, gateway and DNS all taken from DHCP), which saves typing. On our board only the IP needed changing. Type the new address, check the gateway and DNS, and leave IPv6 on DHCP unless you run static IPv6 on purpose:

ZimaOS eth0 Ethernet dialog set to Manual with static IP 192.168.1.19 gateway and DNS 192.168.1.1

Click Save. The change applies immediately, which the ZimaOS networking docs also warn about. Your browser is still talking to the old address, so the Save button spins forever. That spinner is not a failure. Open the new address in a fresh tab (http://192.168.1.19 for us) and log in again; our board answered there within about 30 seconds.

If the new address sits in a different subnet from your computer, you won’t reach it at all until the computer is on that subnet too. Double-check the numbers before saving.

Confirm the new address (the Network page lags)

The General page in Settings picked up the change straight away. The LAN line under the device name shows the static address:

ZimaOS Settings General page showing LAN IP 192.168.1.19 after the static IP change

The Network page is where this trips people up. It kept reading DHCP 192.168.1.106 for eth0 after the save, after logging out and back in, and after a hard page reload. That label is cached. The board really was on the new address the whole time:

ZimaOS Network page still showing DHCP 192.168.1.106 label after saving a static IP

Only a reboot refreshed it. After restarting from the power icon, the same row reads Static IP 192.168.1.19, and the address survived the reboot (the dashboard came back in about 35 seconds):

ZimaOS Network page showing eth0 Static IP 192.168.1.19 after reboot

Now the part the docs don’t mention. The dashboard doesn’t edit the existing “Wired connection 1” profile. It creates a brand new one called ZimaCube-eth0 (the name comes from ZimaCube, the NAS line ZimaOS was built for and still ships on the ZimaCube 2, and a ZimaBoard gets it too) and switches the port to it. Filter the connection list to the Ethernet profiles:

nmcli connection show | grep -E 'NAME|ethernet'

The old DHCP profile is still there, just no longer bound to a device:

NAME                UUID                                  TYPE      DEVICE
ZimaCube-eth0       dacced86-7295-4f8b-ae2a-cc13cdd26aea  ethernet  eth0
Wired connection 1  40b4ab85-42cc-3c69-980f-fbfd807b4a9d  ethernet  --
Wired connection 2  7943bbc5-a963-36cd-823a-1271c81b36a0  ethernet  --             

NetworkManager’s own audit log shows how the dashboard built it: one add, a string of modifies (addresses and method, then gateway, then DNS), then an activate. That’s the same sequence you would type by hand with nmcli:

sudo journalctl -u NetworkManager | grep -E 'op="connection-(add|update|activate)".*ZimaCube'

Seven calls in total. The add landed when we switched the dialog to Manual, and the other six hit in the same second after Save:

Sep 28 20:06:54 ZimaBoard2 NetworkManager[1145]: <info>  [1790622414.3829] audit: op="connection-add" uuid="dacced86-7295-4f8b-ae2a-cc13cdd26aea" name="ZimaCube-eth0" pid=44045 uid=0 result="success"
Sep 28 20:08:29 ZimaBoard2 NetworkManager[1145]: <info>  [1790622509.8705] audit: op="connection-update" uuid="dacced86-7295-4f8b-ae2a-cc13cdd26aea" name="ZimaCube-eth0" args="ipv4.addresses,ipv4.method" pid=44241 uid=0 result="success"
Sep 28 20:08:29 ZimaBoard2 NetworkManager[1145]: <info>  [1790622509.8977] audit: op="connection-update" uuid="dacced86-7295-4f8b-ae2a-cc13cdd26aea" name="ZimaCube-eth0" args="ipv4.gateway" pid=44246 uid=0 result="success"
Sep 28 20:08:29 ZimaBoard2 NetworkManager[1145]: <info>  [1790622509.9234] audit: op="connection-update" uuid="dacced86-7295-4f8b-ae2a-cc13cdd26aea" name="ZimaCube-eth0" pid=44251 uid=0 result="success"
Sep 28 20:08:29 ZimaBoard2 NetworkManager[1145]: <info>  [1790622509.9421] audit: op="connection-update" uuid="dacced86-7295-4f8b-ae2a-cc13cdd26aea" name="ZimaCube-eth0" args="ipv4.dns" pid=44256 uid=0 result="success"
Sep 28 20:08:29 ZimaBoard2 NetworkManager[1145]: <info>  [1790622509.9664] audit: op="connection-update" uuid="dacced86-7295-4f8b-ae2a-cc13cdd26aea" name="ZimaCube-eth0" pid=44261 uid=0 result="success"
Sep 28 20:08:29 ZimaBoard2 NetworkManager[1145]: <info>  [1790622509.9852] audit: op="connection-activate" uuid="dacced86-7295-4f8b-ae2a-cc13cdd26aea" name="ZimaCube-eth0" pid=44266 uid=0 result="success"

The profile is saved to disk, which is why it survives reboots. Read it back:

sudo cat /etc/NetworkManager/system-connections/ZimaCube-eth0.nmconnection

Plain keyfile format, with the four values from the dialog under [ipv4]:

[connection]
id=ZimaCube-eth0
uuid=dacced86-7295-4f8b-ae2a-cc13cdd26aea
type=ethernet
interface-name=eth0

[ethernet]

[ipv4]
address1=192.168.1.19/24
dns=192.168.1.1;
gateway=192.168.1.1
method=manual

[ipv6]
addr-gen-mode=default
method=auto

[proxy]

For an outbound check, use curl rather than ping. ICMP from the board returned nothing on our network while HTTPS worked fine, so a failed ping here tells you very little:

curl -sS -o /dev/null -w '%{http_code}\n' https://www.zimaspace.com/

A 200 means routing through the gateway and name resolution through the DNS server both work:

200

3. Option B: Set a ZimaOS static IP with nmcli

This is the alternative to step 2, not a follow-up, so skip it if the dashboard already gave you the static address. The console route matters when the dashboard can’t reach the board, when you’re scripting it, or when you want a setting the dialog doesn’t have. ZimaOS ships NetworkManager with nmcli, and your ZimaOS account is in wheel, so sudo works with your normal password (the id output in the setup guide shows the group). Plug in a monitor and keyboard, or SSH in as covered in the setup guide.

For this run our LAN cable was on the second port, eth1 (we moved it there after the lockout described in step 5). The one rule that matters: choose the profile by its DEVICE, never by its name. NetworkManager hands out the names “Wired connection 1”, “Wired connection 2” at boot, in port order, only to ports that have no saved profile. So the name follows whichever port is left over, not a fixed port. On our board the two names swapped ports:

BootSaved profileseth0 goteth1 got
Fresh installnoneWired connection 1Wired connection 2
After the dashboard static IPZimaCube-eth0ZimaCube-eth0Wired connection 1
After the nmcli static IP on eth1Wired connection 1 (eth1)Wired connection 2Wired connection 1

Copy an nmcli answer from a forum that says “modify Wired connection 1” onto a board where the dashboard already saved a profile, and you reconfigure the wrong port. Set the port once and let nmcli look the profile up:

export IFACE=eth1
export CON="$(nmcli -g GENERAL.CONNECTION device show "${IFACE}")"
echo "CON=${CON}"

Ours resolved to the DHCP profile generated at boot:

CON=Wired connection 1

An empty name means the port has no active profile at all. Skip ahead to the recovery section in that case, because there’s nothing to modify. Otherwise, set the address, gateway and DNS in one call:

sudo nmcli connection modify "${CON}" ipv4.method manual ipv4.addresses 192.168.1.19/24 ipv4.gateway 192.168.1.1 ipv4.dns 192.168.1.1

Nothing changes on the wire until you re-activate the profile. Over SSH this drops your session, because the address changes under it:

sudo nmcli connection up "${CON}"

On a local console you see the confirmation. Over SSH you won’t, so reconnect to the new address; ours answered in about three seconds:

Connection successfully activated (D-Bus active path: /org/freedesktop/NetworkManager/ActiveConnection/10)

The boot-generated profiles live in /run/NetworkManager/system-connections/, which is memory and disappears on reboot. The modify call moved ours to /etc/NetworkManager/system-connections/, so it’s now permanent. Confirm where it lives and what it holds:

nmcli -f NAME,DEVICE,FILENAME connection show --active | grep -E 'NAME|eth'

The FILENAME column now points under /etc:

NAME                DEVICE          FILENAME
Wired connection 1  eth1            /etc/NetworkManager/system-connections/Wired connection 1.nmconnection 

We rebooted to prove it, and the board came back on 192.168.1.19 in about 30 seconds. A new SSH session starts without your variables, so set them again before checking:

export IFACE=eth1
export CON="$(nmcli -g GENERAL.CONNECTION device show "${IFACE}")"

Then read the profile and the default route:

nmcli -f ipv4.method,ipv4.addresses,ipv4.gateway,ipv4.dns connection show "${CON}"; ip route | grep default

All four values stuck, and the route shows proto static instead of proto dhcp:

ipv4.method:                            manual
ipv4.addresses:                         192.168.1.19/24
ipv4.gateway:                           192.168.1.1
ipv4.dns:                               192.168.1.1
default via 192.168.1.1 dev eth1 proto static metric 100 

The dashboard’s Network page lags behind nmcli changes too (after one of ours it read “DHCP 192.168.1.19”, pairing the new mode with the old address), so trust nmcli until the next reboot. The same commands set a static IP on any NetworkManager distro, which our openSUSE Leap nmcli static IP guide and the nmcli primer for Ubuntu and Debian cover in more depth.

4. Add a ZimaOS VLAN interface on the other port

The dashboard has no VLAN option anywhere (the only “vlan” in the ZimaOS web UI code is Docker’s macvlan network driver), so this one is nmcli only. Our setup: the LAN stays on eth1, and eth0 goes to a switch port configured as a trunk carrying VLAN 30 tagged, subnet 172.20.30.0/24. The board gets 172.20.30.19 on that VLAN with no gateway and no DNS, so the default route stays on the LAN and the two ports never compete for it. If you’re still choosing a switch, our VLAN-capable gigabit switch picks cover the cheap managed options, and the Cisco VLAN configuration guide shows the trunk side on a Cisco switch.

The gotcha showed up the second the cable went in. A trunk usually carries the LAN as its untagged native VLAN, and eth0 still had its boot-time DHCP profile. So before we configured anything, eth0 grabbed a LAN lease by itself (192.168.1.106) and the board ended up with two default routes on the same subnet:

ip route | grep default

One static route through eth1, and a second DHCP route through eth0 one metric behind it:

default via 192.168.1.1 dev eth1 proto static metric 100 
default via 192.168.1.1 dev eth0 proto dhcp src 192.168.1.106 metric 101 

It works, but now the board answers on two LAN addresses, and the dashboard or an app can bind to the wrong one. The parent of a VLAN should carry no IP of its own. Point the variables at eth0 and look up its profile the same way as in step 3:

export IFACE=eth0
export CON="$(nmcli -g GENERAL.CONNECTION device show "${IFACE}")"
echo "CON=${CON}"

That’s the profile NetworkManager created for eth0 at the last boot, which matches the naming table above:

CON=Wired connection 2

Don’t delete the profile (step 5 shows what that does). Switch off IPv4 and IPv6 on it instead:

sudo nmcli connection modify "${CON}" ipv4.method disabled ipv6.method disabled
sudo nmcli connection up "${CON}"

Now add the tagged interface. NetworkManager names the device eth0.30, tags frames with 802.1Q ID 30, and stores the address in a new vlan30 profile:

sudo nmcli connection add type vlan con-name vlan30 ifname "${IFACE}.30" vlan.parent "${IFACE}" vlan.id 30 ipv4.method manual ipv4.addresses 172.20.30.19/24 ipv6.method disabled

New profiles autoconnect by default, so there’s no separate up step. The add confirms with the profile UUID:

Connection 'vlan30' (a1b3ef8c-bf68-43f6-8930-f8a2a30f925d) successfully added.

Check the kernel side. The -d flag prints the VLAN protocol and ID:

ip -d link show eth0.30

The vlan protocol 802.1Q id 30 line is the proof. The interface shares eth0’s MAC address, which is normal for VLAN subinterfaces:

9: eth0.30@eth0: <BROADCAST,MULTICAST,UP,LOWER_UP> mtu 1500 qdisc noqueue state UP mode DEFAULT group default qlen 1000
    link/ether 00:e0:4c:61:3b:78 brd ff:ff:ff:ff:ff:ff promiscuity 0 allmulti 0 minmtu 0 maxmtu 65535 
    vlan protocol 802.1Q id 30 <REORDER_HDR> addrgenmode none numtxqueues 1 numrxqueues 1 gso_max_size 65536 gso_max_segs 65535 tso_max_size 65536 tso_max_segs 65535 gro_max_size 65536 gso_ipv4_max_size 65536 gro_ipv4_max_size 65536 

Then the addressing and routes for both ports:

ip -br addr show eth0; ip -br addr show eth0.30; ip route | grep -E 'default|172.20'

eth0 is up with no address, eth0.30 holds 172.20.30.19, and exactly one default route is left. The VLAN subnet only gets its connected route:

eth0             UP             
eth0.30@eth0     UP             172.20.30.19/24 
default via 192.168.1.1 dev eth1 proto static metric 100 
172.20.30.0/24 dev eth0.30 proto kernel scope link src 172.20.30.19 metric 400 

To prove tagged frames actually cross the trunk, talk to something on VLAN 30. Our router has 172.20.30.1 on that VLAN. As in the confirmation under step 2, curl does the test (ping stays silent on this board), and the neighbour table shows whether ARP resolved over the tagged link:

curl -s -m4 -o /dev/null -w '%{http_code}\n' http://172.20.30.1/; ip neigh show dev eth0.30

A 301 redirect from the router’s web page and a REACHABLE neighbour entry. If curl times out instead, check that the VLAN ID matches on both ends and that the switch port is a trunk, not an access port:

301
172.20.30.1 lladdr 00:e0:67:2b:cd:43 REACHABLE

From a laptop on the LAN, http://172.20.30.19 opened the ZimaOS login through the router’s inter-VLAN routing, and after a reboot eth0.30 came back on its own with the same address. The profile is another plain keyfile:

sudo cat /etc/NetworkManager/system-connections/vlan30.nmconnection

The [vlan] section holds the parent and ID. flags=1 is the reorder-header default:

[connection]
id=vlan30
uuid=a1b3ef8c-bf68-43f6-8930-f8a2a30f925d
type=vlan
interface-name=eth0.30

[ethernet]

[vlan]
flags=1
id=30
parent=eth0

[ipv4]
address1=172.20.30.19/24
method=manual

[ipv6]
addr-gen-mode=default
method=disabled

[proxy]

Don’t expect to see any of this in the dashboard. The Network page doesn’t list eth0.30 at all, and it still labels eth0 as DHCP even though IPv4 is disabled on it:

ZimaOS Network page listing eth1 static IP and eth0 as DHCP with the VLAN 30 interface not shown

Leave eth0’s dialog alone from here on. Saving it would create a ZimaCube-eth0 profile with an address, exactly like step 2 did, and put a LAN IP back on the trunk parent. The same VLAN commands work on any NetworkManager system; our VLAN tagging guide for RHEL and Fedora covers the non-ZimaOS side.

5. Roll back to DHCP or recover a ZimaBoard that fell off the network

If you used option A, going back to DHCP from the dashboard is the reverse of step 2: open the port’s dialog, switch Configure IPv4 to DHCP, and Save. We tested it on eth1. The board picked up its old lease (192.168.1.185) straight away, and ZimaOS kept its ZimaCube-eth1 profile, only flipping it to method=auto. Browse to the DHCP address afterwards, since the page you were on points at the static one.

If you used option B, point the variables back at the LAN port first. Step 4 reused them for eth0, and rolling back the VLAN parent by mistake puts a LAN address back on the trunk:

export IFACE=eth1
export CON="$(nmcli -g GENERAL.CONNECTION device show "${IFACE}")"

Then clear the four fields in the same call that switches the method back:

sudo nmcli connection modify "${CON}" ipv4.method auto ipv4.addresses "" ipv4.gateway "" ipv4.dns ""
sudo nmcli connection up "${CON}"

Reconnect on the leased address and check the profile, the port and the route together:

nmcli -f ipv4.method,ipv4.addresses,ipv4.gateway,ipv4.dns connection show "${CON}"; ip -4 -br addr show "${IFACE}"; ip route | grep default

The profile reads as DHCP again, and the default route goes back to proto dhcp:

ipv4.method:                            auto
ipv4.addresses:                         --
ipv4.gateway:                           --
ipv4.dns:                               --
eth1             UP             192.168.1.185/24
default via 192.168.1.1 dev eth1 proto dhcp src 192.168.1.185 metric 100 

One way not to roll back: deleting the profile. We removed ZimaCube-eth0 expecting eth0 to fall back to DHCP, and the board vanished from the LAN. The NetworkManager journal shows why:

sudo journalctl -u NetworkManager --since 20:00 | grep -E 'connection-delete|connection-removed|created default wired'

NetworkManager only creates the default “Wired connection” profiles when it first sees a device (at boot, on hotplug, or when NetworkManager restarts), not when you delete one. So after the delete at 20:14, eth0 dropped to disconnected and stayed there. The next profile for eth0 only shows up at 20:30, after a reboot:

Sep 28 20:11:41 ZimaBoard2 NetworkManager[1111]: <info>  [1790622701.6048] settings: (eth1): created default wired connection 'Wired connection 1'
Sep 28 20:14:03 ZimaBoard2 NetworkManager[1111]: <info>  [1790622843.9067] device (eth0): state change: activated -> deactivating (reason 'connection-removed', managed-type: 'full')
Sep 28 20:14:03 ZimaBoard2 NetworkManager[1111]: <info>  [1790622843.9083] audit: op="connection-delete" uuid="dacced86-7295-4f8b-ae2a-cc13cdd26aea" name="ZimaCube-eth0" pid=2666 uid=0 result="success"
Sep 28 20:14:03 ZimaBoard2 NetworkManager[1111]: <info>  [1790622843.9536] device (eth0): state change: deactivating -> disconnected (reason 'connection-removed', managed-type: 'full')
Sep 28 20:30:27 ZimaBoard2 NetworkManager[1125]: <info>  [1790623827.3359] settings: (eth0): created default wired connection 'Wired connection 2'

We filtered from 20:00, the hour we made the change; use your own time. eth0 sat with no address for eight minutes until we moved the cable. If you land there, or the board goes missing after any network change, work through these in order:

  1. Move the cable to the other port. A port you never configured still has its boot-time DHCP profile. That’s how we got ours back: eth1 pulled a lease within nine seconds of plugging in. Find the new address in your router’s DHCP client list, or with ZimaClient, which the official reset page also points to.
  2. Reboot. A port with no saved profile gets a fresh DHCP profile at boot. On the next restart of our board, the journal showed (eth0): created default wired connection 'Wired connection 2' for the port we had stripped. Stock NetworkManager remembers a deleted “Wired connection” profile in /var/lib/NetworkManager/no-auto-default.state and never recreates it, but ZimaOS mounts /var as tmpfs, so that file is gone after every boot. If you can’t reboot, add a DHCP profile from the console instead: sudo nmcli connection add type ethernet ifname eth0 con-name eth0-dhcp ipv4.method auto.
  3. Plug in a monitor. The local console shows the IP (the ZimaOS docs point to the same screen after a network change), and you can run the nmcli steps above from there.
  4. Reset the network with a USB stick. The official ZimaOS network reset takes an exFAT stick with an empty file named _ResetNetwork (no extension) in its root. Insert it into the running board and wait about 20 seconds. The file disappears when the reset has run.

If you’d rather never deal with any of this, a DHCP reservation on the router pins the same address to the board’s MAC and leaves ZimaOS on DHCP. It’s the lowest-risk option when you control the router. The static IP is still the answer when the router isn’t yours, or when the board has to come up on a network with no DHCP server at all.

Keep reading

Configure Samba File Share on Debian 13 / 12 Debian Configure Samba File Share on Debian 13 / 12 Free CCNA 200-301 Practice Questions with Answers Networking Free CCNA 200-301 Practice Questions with Answers Backup and Restore Linux Systems with Timeshift Debian Backup and Restore Linux Systems with Timeshift Best 1U Rack Console Drawers and Rackmount KVM Switches Networking Best 1U Rack Console Drawers and Rackmount KVM Switches Best Synology NAS for Home, Plex and Backups: DS225+ vs DS425+ vs DS925+ vs DS1525+ Storage Best Synology NAS for Home, Plex and Backups: DS225+ vs DS425+ vs DS925+ vs DS1525+ Fix Intel i226-V Random NIC Drops on OPNsense Networking Fix Intel i226-V Random NIC Drops on OPNsense

Leave a Comment

Press ESC to close