A server needs a predictable address so that DNS records, firewall rules and clients keep pointing at it. Linux distributions use different tools to manage network settings: Netplan on Ubuntu, NetworkManager on Rocky Linux and other RHEL-based systems, and ifupdown on Debian. In this tutorial you will configure a static IPv4 address, default gateway and DNS resolvers with each of them, apply the change safely on a remote server, and verify connectivity.

Prerequisites

To follow this guide you need:

  • A server running Ubuntu 24.04 LTS, Rocky Linux 9 or Debian 12, for example a CubePath VPS.
  • A non-root user with sudo privileges.
  • The address, prefix length and gateway you are allowed to use. On a hosted server these are assigned by your provider; using an address that is not routed to your server will cut it off the network.
  • Access to an out-of-band console (VNC or serial console in your provider's panel) in case a mistake drops your SSH session.

Throughout this guide, replace these example values with your own:

SettingExample value
Interfaceeth0
Address and prefix203.0.113.10/24
Gateway203.0.113.1
DNS resolvers1.1.1.1, 9.9.9.9

Step 1 - Recording the current configuration

Before you change anything, find the interface name and write down the settings that are working now. List the interfaces and their addresses:

ip -br addr
lo               UNKNOWN        127.0.0.1/8 ::1/128
eth0             UP             203.0.113.10/24 2001:db8::10/64 fe80::be24:11ff:fe12:3456/64

Show the default route, which contains the gateway:

ip route show default
default via 203.0.113.1 dev eth0 proto static

Check which network stack your system uses, so you know which section of this guide applies:

ls /etc/netplan/ 2>/dev/null
systemctl is-active NetworkManager systemd-networkd networking 2>/dev/null

If /etc/netplan/ contains YAML files, follow the Netplan section. If NetworkManager is active, follow the nmcli section. If only networking is active and there is no Netplan configuration, follow the ifupdown section.

Step 2 - Stopping cloud-init from overwriting the network

Cloud images (including most VPS images) use cloud-init, which can regenerate the network configuration at boot and undo your changes. If cloud-init is installed, tell it to stop managing the network:

sudo nano /etc/cloud/cloud.cfg.d/99-disable-network-config.cfg

Add this single line:

network: {config: disabled}

Your existing configuration stays in place; cloud-init simply no longer rewrites it. If the directory /etc/cloud does not exist, cloud-init is not installed and you can skip this step.

Option A - Netplan on Ubuntu 24.04

Netplan reads YAML files from /etc/netplan/ and generates the configuration for systemd-networkd (the default on Ubuntu Server). Files are processed in alphabetical order, and later files override earlier ones.

Writing the configuration

Look at the existing files first:

ls -l /etc/netplan/

On a cloud image you will typically see 50-cloud-init.yaml. Since cloud-init no longer manages the network, move it out of the way so there is only one source of truth, keeping a backup:

sudo mv /etc/netplan/50-cloud-init.yaml /root/50-cloud-init.yaml.bak

Create a new file:

sudo nano /etc/netplan/01-static.yaml

Add the following configuration, replacing the example values. YAML is indentation sensitive, so use spaces, never tabs:

network:
  version: 2
  renderer: networkd
  ethernets:
    eth0:
      dhcp4: false
      addresses:
        - 203.0.113.10/24
      routes:
        - to: default
          via: 203.0.113.1
      nameservers:
        addresses:
          - 1.1.1.1
          - 9.9.9.9

If your interface also has IPv6 addresses you want to keep, add them to the addresses list and a second route with the IPv6 gateway. The guide on configuring IPv6 on Linux covers that in detail.

Netplan refuses to use configuration files that other users can read, so restrict the permissions:

sudo chmod 600 /etc/netplan/01-static.yaml

Applying the configuration safely

Validate the syntax and generate the backend configuration without applying it:

sudo netplan generate

No output means the file is valid. Now apply it with netplan try, which rolls the change back automatically after 120 seconds unless you confirm it. This protects you from locking yourself out over SSH:

sudo netplan try
Do you want to keep these settings?

Press ENTER before the timeout to accept the new configuration

Changes will revert in 119 seconds

If your SSH session still responds, press ENTER to keep the settings. If it freezes, wait two minutes and the old configuration comes back.

Verifying

Confirm the address, route and resolvers:

ip -br addr show eth0
ip route show default
resolvectl dns eth0
eth0             UP             203.0.113.10/24 fe80::be24:11ff:fe12:3456/64
default via 203.0.113.1 dev eth0 proto static
Link 2 (eth0): 1.1.1.1 9.9.9.9

Then continue with the connectivity checks in Step 3.

Option B - NetworkManager with nmcli on Rocky Linux 9

Rocky Linux 9, AlmaLinux 9 and RHEL 9 manage the network with NetworkManager. Its settings are stored as keyfiles in /etc/NetworkManager/system-connections/, and the nmcli command is the supported way to edit them.

Finding the connection name

NetworkManager configures connection profiles, which are bound to a device. List them:

nmcli connection show
NAME         UUID                                  TYPE      DEVICE
System eth0  5fb06bd0-0bb0-7ffb-45f1-d6edd65f3e03  ethernet  eth0

The profile name varies between images (System eth0, cloud-init eth0, Wired connection 1). Use the one bound to your device in the commands below.

Setting the static address

Switch the profile to manual addressing and set the address, gateway and DNS in one command:

sudo nmcli connection modify "System eth0" \
  ipv4.method manual \
  ipv4.addresses 203.0.113.10/24 \
  ipv4.gateway 203.0.113.1 \
  ipv4.dns "1.1.1.1 9.9.9.9"

The change is saved but not yet active. Reactivate the profile to apply it:

sudo nmcli connection up "System eth0"
Connection successfully activated (D-Bus active path: /org/freedesktop/NetworkManager/ActiveConnection/2)

If you are changing the address you are connected through, your SSH session will drop; reconnect to the new address. If something goes wrong, use the console and run sudo nmcli connection modify "System eth0" ipv4.method auto followed by sudo nmcli connection up "System eth0" to return to DHCP.

Verifying

Check the settings NetworkManager applied:

nmcli connection show "System eth0" | grep -E '^ipv4\.(method|addresses|gateway|dns):'
ip route show default
ipv4.method:                            manual
ipv4.dns:                               1.1.1.1,9.9.9.9
ipv4.addresses:                         203.0.113.10/24
ipv4.gateway:                           203.0.113.1
default via 203.0.113.1 dev eth0 proto static metric 100

NetworkManager writes the resolvers to /etc/resolv.conf for you. Continue with Step 3.

Option C - ifupdown on Debian 12

Debian 12 servers without Netplan use the classic ifupdown system, configured in /etc/network/interfaces. Cloud images may instead place the interface definition in /etc/network/interfaces.d/50-cloud-init; check both:

cat /etc/network/interfaces
ls /etc/network/interfaces.d/

Make sure the interface is defined in only one file. If it is in interfaces.d/50-cloud-init, move that file out of the way after completing Step 2:

sudo mv /etc/network/interfaces.d/50-cloud-init /root/50-cloud-init.bak

Writing the configuration

Open the main file:

sudo nano /etc/network/interfaces

Make it contain the loopback interface and a static definition for eth0:

source /etc/network/interfaces.d/*

auto lo
iface lo inet loopback

auto eth0
iface eth0 inet static
    address 203.0.113.10/24
    gateway 203.0.113.1

ifupdown only sets DNS resolvers itself when the resolvconf package is installed. Without it, set them directly in /etc/resolv.conf:

sudo nano /etc/resolv.conf
nameserver 1.1.1.1
nameserver 9.9.9.9

Applying the configuration

Restarting the interface briefly takes it down, so run both commands on one line; that way the interface comes back up even though your SSH session is interrupted. Do this from the console if you can:

sudo ifdown eth0 && sudo ifup eth0

Verify the result:

ip -br addr show eth0
ip route show default
eth0             UP             203.0.113.10/24 fe80::be24:11ff:fe12:3456/64

The second command must show default via 203.0.113.1 dev eth0.

Step 3 - Testing connectivity

Whichever tool you used, finish with the same checks. Ping the gateway, then an external address to confirm routing:

ping -c 3 203.0.113.1
ping -c 3 1.1.1.1
3 packets transmitted, 3 received, 0% packet loss, time 2003ms

Confirm that name resolution works:

getent hosts cubepath.com

Finally, reboot once and check that the configuration survives. This is the only reliable way to catch a file that is overwritten at boot:

sudo reboot

After reconnecting, run ip -br addr again and confirm the address is unchanged.

Troubleshooting

netplan apply warns Permissions for /etc/netplan/01-static.yaml are too open: run sudo chmod 600 on every file in /etc/netplan/.

Netplan reports Error in network definition or mapping values are not allowed: the YAML indentation is wrong or contains tabs. Each nesting level is two spaces. Run sudo netplan generate after every edit to catch errors before applying.

The address reverts after reboot: cloud-init regenerated the configuration, or a second file still defines the interface. Complete Step 2 and make sure only one file under /etc/netplan/ (or one ifupdown file) mentions the interface.

The address is set but there is no Internet access: the gateway is wrong or missing. Compare ip route show default with the value you recorded in Step 1.

Pings to IP addresses work but names do not resolve: check the resolvers with resolvectl status on Ubuntu or cat /etc/resolv.conf on Rocky Linux and Debian.

nmcli reports unknown connection: the profile name has spaces or differs from the example. Copy it exactly from nmcli connection show and keep it quoted.

Conclusion

You configured a static IPv4 address, gateway and DNS resolvers with Netplan on Ubuntu 24.04, NetworkManager on Rocky Linux 9 and ifupdown on Debian 12, prevented cloud-init from overwriting them, and verified that the settings survive a reboot.

As next steps, you can:

  • Add IPv6 addresses to the same configuration so the server is reachable over both protocols.
  • Point an A record for your domain at the new address and set a matching reverse DNS (PTR) record.
  • Set up a firewall with UFW or firewalld now that the server has a fixed public address.