The Linux Page

Setting up your static IP address since Ubuntu 18.04

Spider Web representing various Internet and Intranet network of users.

Older Versions (Ubuntu 17.10-)

With older versions I would just go to /etc/network and edit the interfaces file.

This file would have definitions about the computer interfaces, whether each computer gets a static IP or uses DHCP, etc.

Here is a sample setup for older versions:

auto eth0
iface eth0 inet static
        address 10.0.0.1
        netmask 255.0.0.0
        network 10.0.0.0
        broadcast 10.255.255.255
        gateway 10.0.0.1
        dns-nameservers 10.0.0.8 10.0.0.9
        dns-search m2osw.com
        pre-up /etc/network/firewall

The pre-up is a script run before that specific interface gets initialized. In my case, I want to start my firewall (good idea if the interface is for external access: your firewall should be up before the world has a chance to access your computer.)

The DNS name servers is a space separated list of IP addresses used to access the DNS to be used to determine the IP address from a name,

Newer Versions (Ubuntu 18.04+)

The settings themselves have not changed in Ubuntu 18.04, however, the location where it gets setup is completely different. Also the format changed from a plain text Unix like configuration file to a Yaml format declarative setup.

The configuration is also in a new location and uses a file with a completely different name. You will find the file under /etc/plan and it is named 50-cloud-init.yaml.

As we can see, the extension of the file is .yaml. That means it supports any number of sub-options defined by adding more tabs and a different introducer.

First, notice that they mention the netplan replacement and location of the new files. It's not clear which you have to update to make things work, though.

$ cat /etc/network/interfaces
# ifupdown has been replaced by netplan(5) on this system.  See
# /etc/netplan for current configuration.
# To re-enable ifupdown on this system, you can run:
#    sudo apt install ifupdown

Now, looking at the /etc/netplan files, by default we see not much is added by default:

$ find /etc/netplan/ -exec ls -ld {} \;
drwxr-xr-x 2 root root 4096 Apr  5 21:03 /etc/netplan/
-rw-r--r-- 1 root root  589 Apr  5 21:03 /etc/netplan/50-cloud-init.yaml

Just one file! When you first look at it, you'll notice that the default is that the computer will automatically be given an IP address through DHCP.

The following is what I use when switching to my local static IP address:

# This file is generated from information provided by
# the datasource.  Changes to it will not persist across an instance.
# To disable cloud-init's network configuration capabilities, write a file
# /etc/cloud/cloud.cfg.d/99-disable-network-config.cfg with the following:
# network: {config: disabled}
network:
    ethernets:
        enp0s3:
            addresses: [10.0.0.15/8]
            dhcp4: false
            dhcp6: false
            optional: false
            #gateway4: 10.0.0.1
            nameservers:
                addresses: [75.75.75.75,75.75.76.76]
            routes:
                - to: 0.0.0.0/0
                  via: 10.0.0.1
                  metric: 100
    version: 2

The gateway is generally one of your own computer in an intranet setup.

Two things that make that definition select a static IP address:

1. The dhcp[46]: false;

2. the addresses: ... definitions.

My example shows the default route using the routes: ... definition because the gateway4: ... is being deprecated and will not work anymore at some point soon (deprecated since Ubuntu 21.10).

Apply Modifications to /etc/netplan/*

Whenever you make changes to files under /etc/netplan/... it is required let the netplan know otherwise nothing is going to happen until you reboot.

sudo netplan apply

It should be pretty quick and return to the prompt. After that, you can verify that your changes took hold as expected with:

ifconfig

What about the WARNING in that yaml file?

Yes. You noticed a warning and instructions on how to block the configuration from being blown away. If you're not going to use the graphical interface, you're probably safe just like that. On a computer with X-Windows running, I would advice to properly disable the cloud-init as follow:

# Open file
$ sudo vim /etc/cloud/cloud.cfg.d/99-disable-network-config.cfg

# Add this line (i for insert and then type the following)
network: {config: disabled}

# Then save and exit (:wq or ZZ)

The file is not likely to already exist. vim will create it as expected just by editing the content of the file.

What about the Pre-up Script?

You may notice that the netplan does not offer any hooks.

The fact is that the netplan is processed using systemd (via the systemd-network service from networkd-dispatcher), therefore, the solution to implementing a pre-up script is to add your own service file and make sure it runs before the systemd-network service. This will have the same effect.

Here is a sample from the Snap! Websites snapfirewall project:

# Documentation available at:
# https://www.freedesktop.org/software/systemd/man/systemd.service.html

# This service is used on 18.04 and newer systesm where the ifup/ifdown
# interfaces file is not used anymore; it replaces our `pre-up ...` call

[Unit]
Description=Snap! Websites snapfirewall initialization on boot
Wants=network-pre.target
Before=network-pre.target

[Service]
Type=oneshot
WorkingDirectory=~
ProtectHome=true
NoNewPrivileges=false
# We will change this path once we have a better script to setup the firewall
ExecStart=/etc/network/firewall
Restart=no

[Install]
WantedBy=network.target

# vim: syntax=dosini

One of the answers says to write a service file similar to the one used by netfilter-persistent (which depends on iptables-persistent). On my end, I was wondering on where the files should be installed. So I installed netfilter and looked at the output. Here is the info:

Created symlink:
   /etc/systemd/system/multi-user.target.wants/netfilter-persistent.service →
   /lib/systemd/system/netfilter-persistent.service.

As we can see, the file gets intalled under /lib/systemd/system.

Then a syslink is created as a multi-user.target.wants.

Source: How to start a systemd service before networking starts?

IMPORTANT: The --run-startup-triggers option of the networkd-dispatcher may run after the interface is up. So do not use those events. It's always going to be too late.

Nothing Gets Applied?!

When you run the command to update your IP addresses, as in:

sudo netplan apply

The netplan may be perfect and all, but when you look at your network with ifconfig, it's not setup. It uses a default IPv6 address. Note that it will say that it is UP, even though it's not connected.

When you check out the journal, you will notice a couple of funny messages.

One is by the NetworkManager (which is named that way even by default when you use the networkd renderer):

NetworkManager: definition eno1 is not for us (backend 1)

Another message I've seen directly from systemd-networkd is the following:

eno1: Link is not managed by us

This is interesting since I just defined that link in the netplan .yaml file and it clearly defines eno1, so... what's up?

Ha! Ha! Good question, actually the correct question is: what's down?

And the answer is: your port.

This will change in the future (according to the messages I've seen), but if you disconnect your network cable, your computer does not see a carrier and it decides not to setup the port. At least not until it sees a carrier again. From what they are saying, the detection of the carrier will trigger an event and setup the netplan at that time. I've not tried that to see if it is true. I may do so later.

So... as a result, to setup your port, you need to have a valid network card connected to your router or your switch or your hub (are network hubs still being sold? switches are so cheap now, I don't see why we'd still need hubs.)

To see more info about your network session, you can use the journalctl command like so:

journalctl -xeu ststemd-networkd

The -e option is to bring you at the end of that journal. You may have to go up a bit to see the entire session startup sequence.

See Also: Why is Netplan/Networkd not bringing up a static ethernet interface?

Error: address is missing /prefixlength

The static IP address you are assigning to the computer must include a mask. This is the "/<number>" at the end of the address. In my example above, I used "/8" giving me a giant network (up to 16 million computers in my LAN.)

            addresses: [192.168.55.35/24]

Here is another example with a 192.168.x.x where we limit the number of computers to about 250. Netplan gives you the error above when that prefix length was not specified.

Note: For old timers (like me), it is important to understand that newer network settings do not support masks anymore (are not expected to support such). Instead, they have a prefix length. In other words, the mask is all zeroes except for the number of bits specified by the prefix length.

Error: gateway unknown field

I got that one error once too. Note that the gateway specification in the old interfaces file used the word gateway to specify that IP address.

Netplan, on the other hand, uses gateway4 and gateway6 so it can be sure it's parsing the correct type of IP address.

The documentation doesn't say and I haven't tried, but it is likely that both will work together. I would only use one or the other. Test which works best for you and stick to it.

Where can I find the other fields?

You should already know that since it shows up in the old interfaces file...

For additional information, use the manual with the following:

man 5 netplan

For example you could specify the size of the MTU (not really recommanded, although on a local network, having a larger MTU could help with large transfers.) There are also options to setup routes. Usually the default is enough, but on a rather specific network, adding a few routes could be useful and it can be done at this point.

Re: Setting up your static IP address since Ubuntu 18.04

You, sir, are amazing, was having so much trouble with the error: address is missing /prefix-length

Your explanation sorted it for me, unlike several others I was trying to sort it.

thanks :)