How to set up a RaspberryPi & Nftables for masquerading between to interfaces? - linux

I'm trying to set up a RaspberryPi running Nftables as a "router". It's running on RaspberryPi OS 64 bits with kernel 5.15.32-v8+ and Nftables v0.9.8 (E.D.S.). I would like it to allow traffic between the LAN it's connected to through its WiFi interface and an Android phone sharing it's cellular data connection through USB.
The RPi is connected to a LAN through it's WiFi interface. There is a DHCP server running on that LAN. It serves clients class C private addresses like 192.168.80.X/24. The RaspberryPi gets served as below. The network configuration allows for a range of IP addresses to be assigned manually, shall that be needed.
- RaspberryPi : interface wlan0
- IP address : 192.168.80.157
- Subnet : 255.255.255.0
- Gateway : 192.168.80.2
- DNS : 192.168.200.1 (firewall living an another VLAN) / 8.8.8.8
An Android phone is connected to the RaspberryPi through a USB cable and acts as a USB modem, sharing its cellular data. It assigns the RPi a class C private address like 192.168.X.Y/24. It changes each time I plug the Android phone in / reboot, and I can't tune the range of addresses served by the phone.
- RaspberryPi : interface usb0 (Android phone)
- IP address : 192.168.42.48 (at the moment)
- Subnet : 255.255.255.0
- Gateway : 192.168.42.105
- DNS : 192.168.42.105 (same as gateway)
I have enabled IP forwarding in the sysctl.conf
net.ipv4.ip_forward=1
Nftables is configured as follow (example from here :
table ip nat_antoine {
chain prerouting {
type nat hook prerouting priority dstnat; policy accept;
ip protocol icmp counter meta nftrace set 1
}
chain postrouting {
type nat hook postrouting priority srcnat; policy accept;
oifname "usb0" masquerade
}
}
I ran the following tests. I disabled nftables and SSH'd into the RPi through the wlan0 interface. If I configure the firewall at 192.168.200.1 to allow internet access to the RPi (and disconnect the Android phone "usb0"), it works : the RPi can ping / curl / ssh into the "outside" world.
Then I revoked the internet access through wlan0 and plugged the Android phone "usb0" in. Same : I can ping / curl / ssh into the "outside" world. I have made sure that the traffic is going through usb0 and not wlan0.
Issues arise when I enable nftables and try to access internet via the RPi through another client. I took another android phone, connected it to the 192.168.80.0/24 LAN and manually configured the gateway address to be the RPi's wlan0 interface address (DNS from Quad9). Best I can get is pinging the wlan0 interface on the RPi.
"nft monitor" output when pinging 192.168.80.157 from an Android client (client gets an answer) :
trace id 98bebc6f ip nat_antoine prerouting packet: iif "wlan0" ether saddr d0:1b:49:f1:01:29 ether daddr dc:a6:32:65:a2:f4 ip saddr 192.168.80.20 ip daddr 192.168.80.157 ip dscp cs0 ip ecn not-ect ip ttl 64 ip id 40158 ip length 84 icmp code net-unreachable icmp id 30 icmp sequence 1 #th,64,96 820786881435526521749372928
trace id 98bebc6f ip nat_antoine prerouting rule ip protocol icmp counter packets 1 bytes 84 meta nftrace set 1 (verdict continue)
trace id 98bebc6f ip nat_antoine prerouting verdict continue
trace id 98bebc6f ip nat_antoine prerouting policy accept
"nft monitor" output when pinging 192.168.42.48 from the same Android client (client gets no answer) :
trace id c59a6b89 ip nat_antoine prerouting packet: iif "wlan0" ether saddr d0:1b:49:f1:01:29 ether daddr dc:a6:32:65:a2:f4 ip saddr 192.168.80.20 ip daddr 192.168.42.48 ip dscp cs0 ip ecn not-ect ip ttl 64 ip id 29620 ip length 84 icmp code net-unreachable icmp id 31 icmp sequence 1 #th,64,96 56218603639456293821148039936
trace id c59a6b89 ip nat_antoine prerouting rule ip protocol icmp counter packets 1 bytes 84 meta nftrace set 1 (verdict continue)
trace id c59a6b89 ip nat_antoine prerouting verdict continue
trace id c59a6b89 ip nat_antoine prerouting policy accept
Can someone please help me / point me to the right direction for fixing this ?
Thank you very much.

Related

Two wired connection at the same time

I am struggling with a network problem.
My computer needs to be linked to two differents networks. one via PCI the other one via a USB adapter. The pci is the "usual" network, the usb is to use for specific address.
I have tried differents solutions, with dns, multiple wired connection, modifiying /etc/network/interfaces, ...
But I can't manage to have the 2 networking working at the same time.
Do you have any solution. I am working with Debian - jessie.
Cheers
Since you haven't specified any networks, IP addresses or device names, I will use my machine as an example.
I have an IOGear ethernet USB dongle which shows up as device enx0050b6d341bb, and an RTL811 PCI ethernet device which shows up as eth0. eth0 is plugged into the "main" network which has a DHCP server and enx0050b6d341bb is connected to a private switch on my workbench.
If I want to use eth0 to connect to the internet, but use enx0050b6d341bb to connect to anything on network 192.168.168.0/24, /etc/network/interfaces will look like this:
auto lo
iface lo inet loopback
# Obtain DHCP address from server
auto eth0
iface eth0 inet dhcp
# Connect to 192.168.168.0 network
auto enx0050b6d341bb
iface enx0050b6d341bb inet static
address 192.168.168.3
network 192.168.168.0
netmask 255.255.255.0
Since I only have one device using DHCP, my default route will automatically go through that device, which happens to be exactly what I want :-)
solargy#GEPY633007AX:~$ ip route
default via 192.168.10.1 dev eth0
192.168.10.0/24 dev eth0 proto kernel scope link src 192.168.10.67
192.168.168.0/24 dev enx0050b6d341bb proto kernel scope link src 192.168.168.3
The above shows that my default traffic will go through eth0 and that any traffic for addresses in network 192.168.168.0/24 will go through enx0050b6d341bb. To verify that, you can find out which device will be used to communicate with address 192.168.168.2:
solargy#GEPY633007AX:~$ ip route get 192.168.168.2
192.168.168.2 dev enx0050b6d341bb src 192.168.168.3
cache
As you can see, any traffic for 192.168.168.2 will go through enx0050b6d341bb.

Linux NIC driver: what's the UDP packet from 0.0.0.0 to 255.255.255.255?

I am playing with rhel6 and rhel 7 NIC driver.
The interesting thing is, when I do "ifup eth0" (eth0 is the NIC associated with my driver), I found Linux will try to send two special UDP packets, with source address of 0.0.0.0 and destination address of 255.255.255.255.
Can someone help me to understand what's the purpose of those UDP packets?
This is a DHCP Discovery request. The interface is attempting to acquire an IP address from your DHCP server.

Send UDP packets through no IP assigned bridge interface in Ubuntu Linux

I have two network interfaces (e.g. eth0 and eth1) configured as two ends of a bridge in Ubuntu Linux 14.04. They are not assigned with any IP addresses. eth0 is physically connected to a subnet. I want to send UDP packets through eth0 to a subnet connected machine. I create a UDP socket and check that it can successfully bind to eth0 (i.e. setsockopt(socket, SOL_SOCKET, SO_BINDTODEVICE, eth0, strlen(eth0)), and executing sendto() reports success as well. However, the designated target machine cannot receive anything from eth0!!
Is there any Ubuntu tools/commands to trace where the UDP packets go (actually, I did try to use Wireshark. But, Wireshark cannot detect any network interface to capture!)?
And, is there any workarounds, under the situation that eth0 and eth1 must be set as a interconnected bridge with no IP addresses, to make use of eth0 to send UDP packets to other machine with designated IP address and port?

Two gateway routing issue

I have two NICs.
On eth1 IP is 10.135.28.86/16.
On eth IP is 135.251.8.43/24.
My routing table is like below:
135.251.8.0/24 dev eth1 proto kernel scope link src 135.251.8.43
10.135.0.0/16 dev eth0 proto kernel scope link src 10.135.28.86
169.254.0.0/16 dev eth0 scope link metric 1002
169.254.0.0/16 dev eth1 scope link metric 1003
10.0.0.0/8 via 10.135.0.1 dev eth0
default via 135.251.8.1 dev eth1
Now if I ping 10.135.28.86 from 10.34.7.103, it's OK, while if I ping 135.251.8.43 from 10.34.7.10, it fails.
And if I ping my public IP 135.251.8.43 from 135.252.11.7, it's OK, if I ping 10.135.28.86, it fails.
However, on my other machines which have exactly the same subnet and gateway configured, I can ping both IP either from 10.34.7.103 or 135.252.11.7.
Any ideas on this?
I used tcpdump to capture icmp packet on other machines and found that echo request come in eth0 and echo reply out from eth1.
but on this machine no echo reply were captured.
When you ping from your other machines with IP's in both networks the machine uses the interface on the same network to send the packet (so private-to-private and public-to-public, since they are on directly connected subnets). That is why it reaches, they are on the same subnet.
I see 2 scenarios.
1.
The machine which only has IP on your private network (10.34.7.10) probobly sends its ping to dgw (IP?) which then forwards it to 135.251.8.43 (eth0).
But since the source adress (10.34.7.10) is on a network directly connected to it's other interface (eth1) the answer will be sent back there. I would say you have a flawed network architecture.
The machine 10.34.7.10 has a static route for 135.251.8.43 to 10.135.28.86, but your machine has not bridged the 2 networks.

Send all traffic to network interface and receive from other

i'm triying to imagine how to do:
(with Linux Debian based distro)
I have PC with 4 NIC:
eth0 = Internet Access (connect to router WAN)
eth1 = Local lan
eth2 = OUT NIC
eth3 = IN NIC
I need to send all traffic from eth1 (local lan) to eth2, receive the same traffic from eth3 and route to eth0.
The idea is send all eth1 traffic to external device over eth2, the external device inspect the packets and send to PC again on eth3, then my PC Linux route traffic to eth0
Is posible to do that ?
You're running linux on a PC? We need to know the version first off. Second you are looking into IProutes if you want to redirect traffic from one NIC to another.

Resources