Cant connect to shared/forwarded internet - NetworkManager + link-local?

Sorry for the long post, but I want to get all the info across.
I have a laptop with Manjaro linux, the location it is usually used in has a poor-to-unusable wifi connection. I have a second (headless) computer with good wifi connection and an appropriate ethernet cable to connect them. The second computer is sharing its internet connection over ethernet, iptables is set up for this,

sudo iptables -t nat -S
-P PREROUTING ACCEPT
-P INPUT ACCEPT
-P POSTROUTING ACCEPT
-P OUTPUT ACCEPT
-A POSTROUTING -o wlan0 -j MASQUERADE

and forwarding gets turned on when needed with this line in a bash script

sudo sh -c “echo 1 > /proc/sys/net/ipv4/ip_forward”

(the AP does not make an IPv6 connection). Results from ip a and ip r show:

ip a
1: lo: <LOOPBACK,UP,LOWER_UP> mtu 65536 qdisc noqueue state UNKNOWN group default qlen 1000
link/loopback 00:00:00:00:00:00 brd 00:00:00:00:00:00
inet 127.0.0.1/8 scope host lo
valid_lft forever preferred_lft forever
2: eth0: <BROADCAST,MULTICAST,UP,LOWER_UP> mtu 1500 qdisc pfifo_fast state UP group default qlen 1000
link/ether b8:27:eb:45:3f:f4 brd ff:ff:ff:ff:ff:ff
inet 169.254.19.86/16 brd 169.254.255.255 scope global noprefixroute eth0
valid_lft forever preferred_lft forever
3: wlan0: <BROADCAST,MULTICAST,UP,LOWER_UP> mtu 1500 qdisc pfifo_fast state UP group default qlen 1000
link/ether b8:27:eb:10:6a:a1 brd ff:ff:ff:ff:ff:ff
inet 10.1.10.226/24 brd 10.1.10.255 scope global dynamic noprefixroute wlan0
valid_lft 604297sec preferred_lft 528697sec
ip r
default via 10.1.10.1 dev wlan0 proto dhcp src 10.1.10.226 metric 303
10.1.10.0/24 dev wlan0 proto dhcp scope link src 10.1.10.226 metric 303
169.254.0.0/16 dev eth0 scope link src 169.254.19.86 metric 202

I have verified that a third computer can successfully ping 8.8.8.8 and browse the internet over the ethernet cable after using the following commands

sudo /etc/init.d/networking stop
sudo ip route add default via 169.254.19.86 dev wlan0
sudo /etc/init.d/networking restart

…and I needed to copy the contents of /etc/resolv.conf from the second to the third computer. Results from ip a and ip r on this third computer show:

ip a
1: lo: <LOOPBACK,UP,LOWER_UP> mtu 65536 qdisc noqueue state UNKNOWN group default qlen 1000
link/loopback 00:00:00:00:00:00 brd 00:00:00:00:00:00
inet 127.0.0.1/8 scope host lo
valid_lft forever preferred_lft forever
inet6 ::1/128 scope host
valid_lft forever preferred_lft forever
2: eth0: <BROADCAST,MULTICAST,UP,LOWER_UP> mtu 1500 qdisc pfifo_fast state UP group default qlen 1000
link/ether b8:27:eb:d2:a5:1a brd ff:ff:ff:ff:ff:ff
inet 169.254.54.50/16 brd 169.254.255.255 scope global noprefixroute eth0
valid_lft forever preferred_lft forever
inet6 fe80::357:d547:33d2:4e8/64 scope link
valid_lft forever preferred_lft forever
3: wlan0: <BROADCAST,MULTICAST> mtu 1500 qdisc noop state DOWN group default qlen 1000
link/ether b8:27:eb:87:f0:4f brd ff:ff:ff:ff:ff:ff
ip r
default via 169.254.19.86 dev eth0
default dev eth0 scope link src 169.254.54.50 metric 202
169.254.0.0/16 dev eth0 scope link src 169.254.54.50 metric 202

Now…
I have been trying unsuccessfully to get the Manjaro laptop to also be able to browse the web over the ethernet cable. This is the only one with NetworkManager running, and the /etc/init.d/networking commands are not available. I have defined a new ‘connection’ with

nmcli con delete shared-internet
nmcli con add con-name shared-internet type ethernet ifname ens4 autoconnect no ethernet.auto-negotiate yes
nmcli con modify shared-internet ipv4.method link-local ipv4.routes “0.0.0.0/0 169.254.19.86 150”

and invoking this when trying to access the internet with

nmcli device disconnect ens4
sudo ip route add default via 169.254.19.86 dev ens4
nmcli --pretty con up shared-internet

The ip route add command reported “Error: Nexthop has invalid gateway”, and ping 8.8.8.8 did not work, so I tried removing this and added the ipv4.routes part to the connection definition, still not working. I can ping and ssh from the Manjaro laptop to the 2nd computer, and I can ping 8.8.8.8 from the second computer. And when I try to change the content of /etc/resolv.conf it gets set back to no DNS when I read it back. Results of ip a and ip r are

ip a
1: lo: <LOOPBACK,UP,LOWER_UP> mtu 65536 qdisc noqueue state UNKNOWN group default qlen 1000
link/loopback 00:00:00:00:00:00 brd 00:00:00:00:00:00
inet 127.0.0.1/8 scope host lo
valid_lft forever preferred_lft forever
inet6 ::1/128 scope host
valid_lft forever preferred_lft forever
2: ens4: <BROADCAST,MULTICAST,UP,LOWER_UP> mtu 1500 qdisc mq state UP group default qlen 1000
link/ether 00:1e:37:d9:eb:74 brd ff:ff:ff:ff:ff:ff
altname enp4s0
inet 169.254.123.210/16 brd 169.254.255.255 scope link noprefixroute ens4
valid_lft forever preferred_lft forever
inet6 fe80::9dbb:a8f:8244:ce4d/64 scope link noprefixroute
valid_lft forever preferred_lft forever
3: wls3: <BROADCAST,MULTICAST> mtu 1500 qdisc mq state DOWN group default qlen 1000
link/ether 42:f5:f3:cd:c7:26 brd ff:ff:ff:ff:ff:ff permaddr 00:22:68:90:a5:d0
altname wlp3s0
ip r
default via 169.254.19.86 dev ens4 proto static metric 20150
169.254.0.0/16 dev ens4 proto kernel scope link src 169.254.123.210 metric 100
224.0.0.0/4 dev ens4 proto static scope link metric 100

I also tried messing with combinations of the following commands

sudo ip route add 169.254.19.86 dev ens4 metric 90
sudo ip route add default via 169.254.19.86
sudo ip link set ens4 down
sudo ip link set ens4 up

Although I can bring the link down with the ip set link command, I could not bring it back up that way and needed to use the nmcli con up command. It seems like the link needs to be up for the ip route commands to be accepted.

The error messages from some of the different messing I did while trying to get it to work seem to indicate that NetworkManager deliberately prevents link-local (aka zero-config) addressed computers from accessing a gateway, so I also tried doing this with ipv4.method set to static, and keeping all the addresses the same

nmcli con delete shared-internet
nmcli con add con-name shared-internet type ethernet ifname ens4 autoconnect no ethernet.auto-negotiate yes
nmcli con modify shared-internet ipv4.method static ip4 169.254.123.210/16 gw4 169.254.19.86 ipv4.dns “75.75.75.75 75.75.76.76”

In all cases, I can ping and ssh from the Manjaro laptop to the 2nd computer (169.254.19.86), and I can ping 8.8.8.8 from the second computer, but I cannot get ping 8.8.8.8 to work from the Manjaro laptop (0 packets received, 100% packet loss).

I also have an ethernet scanner and a printer and other computers, and everything else works using IPv4 link-local (169.254.X.Y) addressing, and I would prefer not to have to research how to change all these. There is no dhcp server on the ethernet, and no ethernet switch or hub - the cable just gets hooked up on an as-needed basis. And if I mess-up the ability to ssh to the headless 2nd computer it will make things harder. I am new at all of this and will be the first to admit I do not really know what I am doing, just trying stuff based on google searches and man pages. Any expertise would be very much appreciated.

some thoughts - I’m not the most proficient in these matters and it has been years since I wrote my own iptables rules …

You connect your laptop via LAN to the PC which is conncted via WIFI to the internet?
Or is it the other way around?

-A POSTROUTING -o wlan0 -j MASQUERADE
seems to indicate the latter
while your description seems to indicate the former

Wouldn’t you need to have a dhcp server running on the PC with the internet connection?
To give the laptop an IP that traffic can be directed to and from?

How does the laptop aquire an IP?

You are correct, I connect my laptop via ethernet to the computer that connects to the internet via wifi.
I don’t fully understand how it all works, but I think the computer that connects to the internet does nat to fake a public IP address for the laptop, and on the local ethernet connection both machines use the zero-config mechanism to assign themselves local IP addresses in the 169.254.0.0/16 range.

you need some means to provide the laptop with it’s own IP address
static routing or a dhcp server running on the PC

knowing the address (range) of both the PC and the laptop
you can then configure routing between the two if needed

this is too complex for me to just casually give valid advice

The PC get’s an IP - it’s connected to internet via WLAN.
This part seems to work.
The laptop needs it’s own IP - it’s connected via LAN to the PC.
How does it get it?
static assignment?
dhcp?

-A POSTROUTING -o wlan0 -j MASQUERADE
seems wrong
… the laptop is not connected by WLAN - but via LAN

this is where my inexperience shines :wink:

think it through again …

I’m trying to understand what you are telling me.

As I have understood it till now (but this is not my area of expertise)…
There are 3 ways an IP address can get assigned - dhcp, static or link-local.
The laptop’s IP address on interface ens4 (ethernet) is 169.254.123.210/16. (originally link-local, but I did also try statically assigning this).
The second computer’s IP address on interface eth0 is 169.254.19.86. Both these addresses I believe are not directly routable and hence would need to be translated.
The second computer’s IP address on interface wlan0 is 10.1.10.226. This I believe was assigned by dhcp by an AP at 10.1.10.1.
(The third computer’s IP address on interface eth0 was 169.254.54.50).

Regarding the iptables rule, I will google some more on how to share an internet connection.

I’m hoping the third computer working is not just an anomaly. Maybe the rules for static and dhcp assigned addresses are different than for IPv4 link-local assigned addresses, but I have not manged to find any description about this. Most search results are about VPN or IPv6, which seem not relevant here. But I did also try assigning this same address statically to no avail.

Ok, thanks to the conversation so far I have some partial success with further research:

  1. The iptables command is correct. Apparently it means computer#2 should modify packets it is about to send out on wlan0 (wifi) if they did not originate from computer#2 (and presumably do the reverse on their responses before forwarding them).

  2. I tried booting the laptop from an older linux iso. After some futzing around I got it work with the older linux distro. Computer#3 was not an anomaly.

  3. It seems like with NetworkManager present the laptop treats 169.254.X.X/16 addresses differently than 192.168.X.X/16 addresses, even though as I understand it both are supposed to be non routable local subnets. This is obviously something I do not know enough about.

  4. I still need to figure out how to get NetworkManager to temporarily relinquish control of /etc/resolv.conf so I can scp it from computer#2, and then resume control whenever I go back to using the laptop’s own wifi.