Migrating from Legacy Networking to systemd-networkd on Ubuntu 24.04

During a recent Ubuntu server upgrade, I migrated a production system from the legacy ifupdown networking stack to the modern systemd-networkd service. This migration was part of preparing several remote production servers for a smooth upgrade to Ubuntu 24.04, which relies heavily on systemd-managed components.
In this post, I’ll walk through the full migration process, how we automated it safely across multiple remote servers, and the lessons learned from implementing rollback and watchdog mechanisms for zero-downtime transitions.
Why migrate to systemd-networkd?
Ubuntu 24.04 uses systemd-networkd as the default backend for network management. The traditional ifupdown scripts (/etc/network/interfaces) are no longer the recommended way to configure networking. Some of the modern features enabled by systemd-networkd include:
- Predictable network interface naming (e.g., ens3, eth0, etc.)
- Built-in support for bridges, VLANs, and bonds
- Faster boot times with asynchronous network handling
- Unified configuration under /etc/systemd/network
Migrating now also avoids future compatibility issues and takes advantage of systemd’s integrated logging and management.
Step 1: Check the current setup
Before the migration, I confirmed the system was still using ifupdown:
ls /etc/network/interfaces
cat /etc/network/interfacesOutput showed legacy configuration similar to:
auto eth0
iface eth0 inet static
address 10.42.41.1
netmask 255.255.0.0Step 2: Install and enable systemd-networkd
Since systemd-networkd wasn’t already active, I installed and enabled it:
sudo apt install systemd-networkd systemd-resolved -y
sudo systemctl enable systemd-networkd
sudo systemctl enable systemd-resolvedThen, I stopped ifupdown to prevent conflicts.
Step 3: Create a network configuration file
Each interface now has its own .network file under /etc/systemd/network/.
DHCP-based interface:
# /etc/systemd/network/10-eth0.network
[Match]
Name=eth0
[Network]
DHCP=yesStatic interface:
# /etc/systemd/network/20-eth1.network
[Match]
Name=eth1
[Network]
Address=10.42.41.1/16
Gateway=10.42.0.1
DNS=8.8.8.8
DNS=1.1.1.1Step 4: Configure systemd-resolved
This step ensures your system’s DNS resolver works correctly with systemd-networkd.
systemd-resolved listens locally on 127.0.0.53 and handles DNS resolution, caching, and per-interface settings.
Link your system’s /etc/resolv.conf to use it:
sudo ln -sf /run/systemd/resolve/stub-resolv.conf /etc/resolv.confThen to verify:
resolvectl statusIf we skip this, the system might lose DNS resolution after reboot. Applications like apt, curl, and ping may fail to resolve hostnames even though interfaces are up.
Restart and verify
Restart both services:
sudo systemctl restart systemd-networkd
sudo systemctl restart systemd-resolvedCheck active links:
networkctl listDetailed view for one interface:
networkctl status eth0Sample output:
● 2: eth0
Type: ether
State: routable (configured)
Address: 10.42.41.1/16
Gateway: 10.42.0.1
DNS: 8.8.8.8Test:
ping -c 3 8.8.8.8
ping -c 3 google.comStep 6: Reboot and confirm
Reboot once to ensure everything persists. After the reboot,
systemctl status systemd-networkd
systemctl status systemd-resolvedand confirm interface and DNS are still functional.
Handling remote migration and downtime risks
Performing this migration remotely on production systems without physical console access required special care. I prepared several layers of protection to prevent accidental lockouts.
-
Console or IPMI verification: Ensured each node had out-of-band access in case SSH connectivity was lost.
-
Timed rollback safety script: A background process automatically reverted to legacy networking if the new configuration didn’t come up within a few minutes.
#!/bin/bash sleep 300 if ! ping -c1 8.8.8.8 &>/dev/null; then systemctl disable systemd-networkd systemctl enable networking reboot fi
Automating the migration and rollback process
To streamline upgrades across multiple servers, I created automation scripts that handle migration, rollback, and ongoing monitoring.
migrate_to_systemd_networkd.sh
This script performs a complete, logged migration with built-in validation and rollback. It checks for valid .network files, disables legacy services, enables systemd-networkd, tests connectivity, and if all retries fail, restores the old configuration automatically.
Key features
- Validates configuration syntax using systemd-analyze verify
- Masks conflicting services (
ifup@eth*, NetworkManager) - Performs up to three connectivity tests
- Restarts SSH and dependent services
- Schedules a controlled reboot or user-confirmed one
- Rolls back cleanly if connectivity fails
upgrade_watchdog.sh
During do-release-upgrade, networking may restart multiple times. This watchdog script runs in the background to ensure systemd-networkd remains active and services like SSH come back automatically.
- Executes every 10 minutes
- Verifies /etc/systemd/network/*.network exists and services are running as expected if it fails, this script restarts the service
- Restarts systemd-networkd, ssh, and dependent services
Together, both scripts allowed us to perform fully remote OS upgrades with zero manual downtime and consistent recovery paths.
Conclusion
Migrating to systemd-networkd modernizes Ubuntu servers and simplifies long-term maintenance. With the automation scripts and safety mechanisms in place, we successfully migrated multiple remote servers with no downtime and automatic rollback protection.
This upgrade not only prepares infrastructure for Ubuntu 24.04 but also integrates cleanly with our automation and monitoring systems, ensuring reliable networking for years ahead.
ubuntu systemd Networking linux migration devops
Comments