Reverse Tethering using nmcli

From time to time I would like to provide the internet connection from my Linux notebook (via USB cable) to the Librem 5 (reverse tethering) and an the same time use ssh from my notebook to the Librem 5.
To avoid misunderstanding: This post is not about using the Librem 5 for internet access (tethering). In my case has the Librem no wifi connection and a very slow GSM connection, so I would prefer to use an usb cable to a notebook for internet access.

Because I want to ssh into the librem and have reverse tethering through the same physical interface at the same time, I assume using ip route with nat is not a good idea.

AFAI understand this should be doable using a virtual bridge. So I tried to create the same network addressing on both devices, in this example 192.168.1.x (IPv4 without subnet)

The notebook uses interface eth0 with 192.168.1.2 for a connected LAN cable to the internet router/ISP gateway.
The notebook uses interface usb0 with 192.168.1.3 for the connected USB cable to the Librem 5.
The Librem 5 uses interface usb0 with 192.168.1.4 for the connected USB cable to the notebook.
Default Gateway and DNS for all 3 connections are 192.168.1.1 which is the internet router/ISP gateway.

On the Librem 5 I did: Settings > Network > Wired

  • IPv4:
    • Manual
    • IP: 192.168.1.4
    • Netmask: 24
    • Gateway: 192.168.1.1
    • DNS: 192.168.1.1
  • IPv6: deactivate
  • Then activate the wired connection
    The terminal shows using “ip addr show usb0” that the Librem has now the IP address 192.168.1.4.

On the notebook I created a bridge using nmcli (because I read that brctl / bridge-utils are deprecated):

nmcli connection add type bridge ifname br0 con-name br0 ipv4.method manual ipv4.addresses “192.168.182.5/24”
nmcli con add type bridge-slave ifname eth0 master br0
nmcli con add type bridge-slave ifname usb0 master br0
nmcli con modify br0 bridge.stp no
nmcli con down eth0
nmcli con down usb0
nmcli con up br0

On the notebook I see the bridge is active, I can ping the virtual bridge.
I am not able to ping from the notebook to the librem 5 (192.168.1.4). Why?

I am happy if anybody can help me here.
Because I use virsh for VMs, a solution via virsh (instead of nmcli) would be cool too.

What is the output of ip route

Assuming the details you’ve provided are accurate to your system/setup then when the bridge is up your notebook will have a single IP address of 192.168.182.5/24 it won’t know how or where to reach 192.168.1.4

I would think you would want to configure a 192.168.1.0/24 IP address/subnet on the bridge probably inline with however eth0 is normally configured outside of the bridge.

If all you want is to provide internet access to the phone via your notebook, it is much simpler to use NetworkManagers connection sharing feature on your notebook. Out the box, the Librem 5 will have a DHCP client running on the Ethernet over USB interface so attaching the Librem 5 to your notebook via USB and then enabling a shared connection for that interface should be all that is required. For SSH from notebook to Librem 5, again out the box, the Librem 5 has mDNS enabled so assuming your notebook can make use of that and you have established a between phone and notebook, then you can establish an SSH connection with the phone using <LIbrem 5 username>@<Librem 5 hostname>.local from a terminal on your notebook (i.e. if everything is as default you should be able to reach the phone via ssh purism@pureos.local

As far as I’m aware virsh is for managing VMs, I don’t see that it could be used in place of nmcli to configure your networking?

Thank you Loki for the detailed explanations, which kind of solves the issue. For everydays use I would prefer a more comfortable solution for point 2 below.

  1. mDNS is not working, but fixable using static IP addresses
    The Librem gets an IP address, nevertheless I am no able to “ssh purism@pureos.local”. For this I got a workaround using static IP addresses:
    On the notebook in NetworkManager were the “Shared to other computers” is set, I added an IP address with netmask and gateway.
    On the Librem in NetworkManager I set for the “Wired Connection” a static IP in the same network with the gateway from one line above.
    When connecting the Librem 5 with the notebook using the usb cable, the configured IPs are used (and NetworkManager automatically enables IP forwarding for the interface, adds firewall rules, and enables masquerading).
    Then “ssh purism@” works including internent access from the Librem.

An advantage of this approach is that no time for getting the ip address via DHCP is needed.

  1. The name of the usb interface and its MAC address of the notebook changes every day
    Every 24 hours or so the usb port gets a new interface name starting with enx (e. g. enx123a4bcde5f). After booting the notebook, this interface name appears in dmesg the first time when the usb port is used with the Librem. Like the name, the MAC address changes too. This leads to 2 issues:

a) I did not find a way to create in NetworkManager a permanent connection, because the interface name only exists a day. So I have to change in this connection the interface every day in NetworkManager.

b) When plugging the usb cable in the notebook and the old interface name is not valid any more, NetworkManager on the notebook starts a “Wired connection 1” looking for IP adresses via DHCP. I have to stop and delete the connection.
When reading the NetworkManager configuration files and its man pages I see in /etc/NetworkManager/NetworkManager.conf I may stop this behaviour using no-auto-default, but for this an (unchanging) MAC address or interface name is needed too.

In case it matters: The notebook is running Debian 12 (Bookworm).

How to create a connection in NetworkManager for the usb interface when its name and MAC address changes everyday?

Is it possible to get the usb interface name or MAC address before plugging the usb cable connecting the Librem 5?

In case the solution is a static usb interface name for ethernet: How to do this?

If you are having to add static IPs at either end it would suggest that there is some misconfiguartion somewhere, perhaps there are some remnants of a previous configuration attempt still lingering causing some conflict.

The IP configuartion for the shared connection on the netbook and the Librem 5 should not have the same gateway value, the fact that that works also suggest to me that there is some configuration error somewhere. Without knowing any detail I would guess that you still have a bridge configuration up?

With regards point 2, yes, the MAC address is regenerated on each boot this should not be relevant for this setup however. The Librem 5 also regenerates it’s MAC address for the host device/interface on boot and it’s that device/interface that you should be seeing within NetworkManager on your notebook and it’s the MAC address of the Librem 5 that should be made static.

The interface name that you are seeing within NetworkManager of your notebook, is this the same interface name that you are seeing within dmesg of your notebook?

I’m currently using Debian (Bookworm) running Gnome as my day to day OS/Desktop environment and setting up a reliable/connsitent connection share between the desktop and the phone from defaults should only invlolve less than a handful of terminal commands, a couple on the phone and a couple on laptop/desktop/notebook.

Success!

When connected to the Librem 5 via usb cable, the usb interface now always has the name librem5 (instead of enx).
This name has to be chosen in the shared connection of NetworkManager.

When afterwards connecting the Librem 5 via usb cable to the notebook, the NetworkManager connection is set up automatically and ssh into the Librem works, plus the Librem cann access the internet through the attached notebook (reversed tethering).

For those who wants an unique interface name for the Librem is here a description which works on Debian 12. It may not work on your Linux distribution:

  1. Find a unique network identifier of the Librem
    When connected, execute the following as root on your PC:

udevadm info -q all -p /sys/class/net/<enx_name_according_to_nmcli>

In the output choose an identifier:


E: ID_MODEL=Librem_5
E: ID_MODEL_ENC=Librem\x205
E: ID_MODEL_ID=4c05
E: ID_SERIAL=Purism__SPC_Librem_5_0123456789
E: ID_SERIAL_SHORT=0123456789
E: ID_VENDOR=Purism__SPC
E: ID_VENDOR_ENC=Purism\x2c\x20SPC
E: ID_VENDOR_ID=316d
E: ID_REVISION=0604
E: ID_TYPE=generic
E: ID_USB_MODEL=Librem_5
E: ID_USB_MODEL_ENC=Librem\x205
E: ID_USB_MODEL_ID=4c05
E: ID_USB_SERIAL=Purism__SPC_Librem_5_0123456789
E: ID_USB_SERIAL_SHORT=0123456789
E: ID_USB_VENDOR=Purism__SPC
E: ID_USB_VENDOR_ENC=Purism\x2c\x20SPC
E: ID_USB_VENDOR_ID=316d

I chose: ID_USB_MODEL=Librem_5

  1. Create a file in /etc/systemd/network using your chosen identifier
    I choose /etc/systemd/network/72-librem5.link. The chosen identifier has to be set as “Property”.

[Match]
Driver=cdc_ncm
Property=ID_USB_MODEL=Librem_5

[Link]
Description=Librem 5
NamePolicy=
Name=librem5

A restart of your PC / systemd is needed afterwards.

@Loki:
Maybe our systems are not that easy comparable, because I installed Debian 12 with minimal packages (no gui) and added the i3 window manager and NetworkManager afterwards. Because of that there may be differences in the daemon for mDNS and I did not have a static interface name for usb.

Without knowing any detail I would guess that you still have a bridge configuration up?

No, there are no Bridges or virtual interfaces active.
Regarding the same gateway: I think it is fine, because the shared connection does forward the gateway too and adapt it to the “internet” network on the notebook.

Thank you for your help.

I’m happy to read that you got it worked out!

Agreed, not all Bookworm install are equal or comaprable, mDNS is not an integral part of NetworkManager so it may not be installed as part of a miniaml setup. I misunderstood your comments previously in that I had thought you meant that you were unable to access the Librem 5 via <hostname>.local but were able after assigning static IPs.

The connection share feature howver is an itegral part of NetworkManager so I would expect that to work regardless of install type, specifcially the feature should, on top of enabling IP forwarding and set/configure masquerading, also run a small DHCP server on the connection negating any need for static IP and/or gateway assignment.

I’m sure you have worked it out from looking at the property list coming from udevadm, this is setting a static idetifier for the device/interface of the Librem 5 rather than the interface of your notebook that gets a random MAC addrress at boot.