DNS resolving issue with fixed IP setting (USB network)

Today I’ve managed to get my fixed DNS IP’s into the file /etc/resolv.conf by changing another file.
I’ve changed the setting DHCP=yes into DHCP=no in /etc/systemd/network/99-dhcp.network

I’m not sure if I broke something while doing so, but after rebooting the L5, the manual DNS entries where written into resolv.conf.
Name resolution is OK now.

Questions:
What process manages the file /etc/systemd/network/99-dhcp.network?
Why is this setting set to “yes” despite my choice to not use DHCP?
What is the proper way of changing the setting?
Is my conclusion correct that this setting causes the problem I’m facing?

2 Likes

networkd (might be known as systemd-networkd)

This is a default connection, it is not written to or updated for new/modified/active connections.

This is just a simple connection file that gets installed by default with networkd, you can place your own configuration in the directory. You could simply edit the existing file but it isn’t very helpful to have a file name suggesting DHCP is enabled containing settings to disable DHCP. Also note that this is a system file installed by default, any chnages you make may get overwritten by an future update.

No.

I have run a number of networking connections of various configurations on the Librem 5, some simple, other more complex, I haven’t ran into any issues. As NetworkManager is the system Librem 5 uses to mange all network connections, I interact with NetworkManager directly through nmcli rather than any other setting apps, unclear if that makes any difference or not.

As I’m about to jettison my Librem 5, I have just done a full reflash so I currently have a clean system with default network setup. I tried setting a static IP on a USB->RJ45 dongle I have and all looks to be working no problems.

For reference, the config I set was as follows:

IP Address: 192.168.18.8/24
Gateway: 192.168.18.251
DNS Servers: 1.0.0.1 and 1.1.1.1

First I attached the dongle and connected to my network, this should by default setup a new connection and set it to be configured by DHCP. With the dongle connected I query nmcli for a list of connections to determine the connection name for the dongle…

nmcli con show

It is likely that the connection shows up in the list as “Wired connection N” (the connection will be listed in green if it’s active i.e. your network DHCP server if you have one has dished out an IP address and other config information to the connection)

Armed with the connection name, I modified the connection to the static IP details I noted previously…

nmcli con mod "Wired connection N" ipv4.method manual ipv4.address 192.168.18.8/24 ipv4.gateway 192.168.18.251 ipv4.dns 1.0.0.1,1.1.1.1

Then bring the connection down and back up…

nmcli con down "Wired connection N"
nmcli con up "Wired connection N"
ping cloudflare.com
PING cloudflare.com (104.16.132.229) 56 (84) bytes of data.
64 bytes from 104.16.132.229 (104.16.132.229): icmp_seq=1 ttl=56 time=15.3ms
64 bytes from 104.16.132.229 (104.16.132.229): icmp_seq=1 ttl=56 time=15.8ms
64 bytes from 104.16.132.229 (104.16.132.229): icmp_seq=1 ttl=56 time=15.7ms
64 bytes from 104.16.132.229 (104.16.132.229): icmp_seq=1 ttl=56 time=15.5ms
^C
--- cloudflare.com ping statistics ---
4 packets transmitted, 4 received, 0% packet loss, time 3002ms
rtt min/avg/max/mdev = 15.332/15.579/15.812/0.179ms

This worked fine over reboots.

The only minor issue I noticed was that the “Network availability” indicator icon on the status bar didn’t always accurately reflect the network status (i.e. when I disconnected the dongle the “No network” icon did not always show. However, I suspect this has nothing to do with the connection and it did not have any affect on the performance of the connection or network traffic.

To be clear, this is from a clean fresh re-and/flash/install, I have no idea what configuration changes you have made and/or if any of them would have affect on your results if you follow this noted method above.

Hi Loki,

First let me thank you for your reply and effort to investigate this matter.
I have some questions:
First, when you switched from DHCP settings to fixed IP settings, did you switched your DNS option from automatic to manual as well?
Second, was the DHCP server still running when you tested the fixed IP settings?
This is important, since I’ve discovered that name resolution was ok when DHCP was running, despite the manual entered entries.
After I switched off DHCP, the name resolution went wrong e.g. resolv.conf missed any nameserver data and thus causing name resolution to fail.

Third question: Is there any explanation why name resolution started working as expected after changing the DHCP setting from Yes to No in /etc/systemd/network/99-dhcp.network ?
FYI I didn’t change anything else on the L5

And again, I appreciate your and all others effort and time for trying to help me.

No, assuming I am thinking of the same option, the automatic DNS setting is only relevant for connections marked as “auto”, i.e. it has no affect when the connection is set to “manual”

For my initial testing, the DHCP server was still running. However, on the strength of this question I have repeated the test/config without a DHCP server running and do now see the issue you are experiencing.

The network setup with regards DNS is a little different to what I normally run on my desktop machines so I am not overly familiar with it. The main difference is that the Librem 5 uses systemd-resolved for DNS whereas my other machines have NetworkManager manage the DNS directly. I don’t want to get too deep into it so all I’ll say is I think systemd-resolved is probably better suited to portable devices like smartphones than having NetworkManager handle DNS directly.

When the connection comes up, NetworkManger should hand off the DNS server details for the connecion over to systemd-resolved. From what I can gather, things are falling at that first hurdle, either NetworkManager is not passing the DNS details for the connection to systemd-resolved or systemd-resolved is choosing to ignore or simply not use the DNS details. With a static connection configured and up you’ll note systemd-resolve --status shows no DNS servers for the link.

However, adding the DNS servers to the link manually brings everything to life…

sudo systemd-resolve --interface <your_interface> --set-dns dns.server.1.ip --set-dns dns.server.2.ip

All very interesting, but what’s the fix? Certainly the quickest and easiest fix is to set DHCP=no in the 99-dhcp.network file as you have done. If you are always going to use static IPs anytime you need a wired connection then may be just stick with the simple file edit.

If however you need something a little more flexible, I thought about hooking into NetworkManager’s dispatcher to set the DNS servers for the link anytime a manual connection comes up.

A quick and dirty script…

#!/bin/bash

[[ ${2} != "up" ]] && exit 0

[[ -z $(nmcli -f ipv4.method -t c s ${CONNECTION_UUID} \
      | grep :manual) ]] && exit 0

for DNS in ${IP4_NAMESERVERS}; do
  SET_SERVERS+=" --set-dns ${DNS} "
done

systemd-resolve --interface ${DEVICE_IP_IFACE} ${SET_SERVERS}

exit 0

I saved this file as "99-static-dns" and set the permissions to be executable…

chmod 755 99-static-dns

Then set ownership to root…

sudo chown root:root 99-static-dns

And then moved into NetworkManager’s dispatcher directory…

sudo mv 99-static-dns /etc/NetworkManager/dispatcher.d/

This is just a very quick and dirty script, all it does is checks that the connection is coming up, if so checks that it’s a manual connection and if so pulls the DNS server IPs from the connection details and plugs them into systemd-resolve for the connection link.

It’s certainly not as quick and easy as changing yes to no, but it does give a little more flexibility. With something like this in place you can leave DHCP=yes in the 99-dhcp.network file so any DHCP links you may have will still get their DNS handled correctly and anytime a manual connection comes up their DNS servers will be picked up and set with systemd-resolved.

I couldn’t give a definitive answer to this, it may be that my understanding of this file is incorrect. I had thought this file was a default file and with DHCP=yes that would enable DHCP configuration for any new interfaces that appear that don’t already have a configured connection. With existing connections set to manual, I had thought that all manual settings would take. It’s worth noting that when DHCP=no any existing connection set to “auto” will still come up and get it’s main IP configuration from the DHCP server but it will then fail on DNS lookups. This seems like a bug in the DNS handling rather than expected behaviour.

Thank you for confirming the problem I ran into.
Good to read that the problem is reproducible, not only at my side.

For the moment I can live with manually changing the 99-dhcp.network file (if needed).
Luckily this setting change doesn’t affect the cellular interface. That one keeps resolving as expected.

What surprises me is that there are two separate systems (NetworkManager and Systemd) in Linux that handle the network config. It seems to me that this may be a source for error and confusion.

The script you offered is something I’m not going to use at the moment, but will copy that into my personal Wiki for later study and perhaps use.
Learning Bash is on my to do list.

I’ve already created an issue for it and I’m gonna add your findings to it.
Hopefully Purism has enough info to look into it.

Great work, thanks Loki.

As with most things *nix, you have a choice. It’s quite trivial to make the change and choose to have NetworkManager handle all things networking including DNS, this according to my Debian Buster and Bullseye boxes is the default for Debian and is also my preference where practical. However, doing so on the Librem 5 would make it so you are likely to quite quickly encounter this issue…

purism@pureos: $ cat /etc/resolv.conf
# Generated by NetworkManager
nameserver 1.0.0.1
nameserver 1.1.1.1
nameserver 192.168.18.201
# NOTE: the libc resolver may not support more than 3 nameservers.
# The nameservers listed below may not be recognized.
nameserver 192.168.18.202
nameserver 2a01:4c8:f000:1::1
nameserver 2a01:4c8:f000:1::2

In this case, it’s highly probable that my IP6 connection is going to be SOL for DNS. NetworkManager also just manages this lot as a large monolithic list, only dnsmasq (a popular choice for many) and systemd-resolved can manage per-connection DNS (as far as I’m aware) which may be beneficial on a device that can have many varied active connections at any one time and those connections regularly coming up and going down.

2 Likes

As far is I do understand you correctly:
For straight forward networking (with one or two interfaces) the better choice would be using NetworkManager.

For multiple connection situations like with cellphones, the better choice would be systemd-resolved since this method can better handle DNS per connection.

As I’ve already mentioned and as you are confirming, mixing the two methods is not best practice.

“There is enough bandwidth available.”

Kind of Off-Topic, just for the Records.

The issue i described was not about bandwidth, it was about timing. If you splice up one Line, not managed to multiple Device, they will not take care of each other DDOS that Line, witch will lead to Package drops.

This is why we have just one Computer at the end of each Modem or Provider End-Point. Mostly with something like Network Address Translation (NAT) or an IPv6 Solution.