Transforming an UDP Broadcast Packet to a Unicast Packet to traverse subnets

I'm pretty sure it should work because the same server also replies to other unicast packets coming from other clients on Internet.

Yeah, I think I'll look at SNAT as well (although the source header contains the correct IP Address) but first I'd just want to make my unicast packet reach the server...

1 Like

Keep in mind that initial packets for the service discovery may be processed differently from direct connections, that's why it is best to capture and carefully analyze those broadcast requests.

1 Like

It could be, of course... But I guess I have to get that packet to the server in the first place, anyway :grinning:

Ok, I have an update: through ebtables I managed to rewrite the dest MAC address so that it doesn't look like a broadcast anymore, and in conjunction with the above mentioned iptables now the packet reaches the server:

ebtables -t nat -A PREROUTING -p ip --ip-protocol udp -d ff:ff:ff:ff:ff:ff/ff:ff:ff:ff:ff:ff --ip-destination-port 10307 -j dnat --to-destination 9c:c9:eb:15:dd:ce

Not only: the server actually replies, but the packet is not sent back to the client. Now, it could be because as I said all traffic should be blocked from the server zone to the client zone; nonetheless, because the traffic is allowed the other way around (i.e. from the client zone to the server zone), why I can successfully establish a connection from the client to the server, but not from the server to the client? I mean, traffic is allowed only client->server, so any UDP packet coming from the server should be dropped regardless of a previously successful connection, isn't it?

Probably connection tracking is not implemented for your protocol.
Responses not matching the related/established state need to be explicitly allowed.

Uhm... yeah, I thought somerthing similar. But apparently conntrack is matching the traffic both ways:

    [NEW] udp      17 60 src=192.168.1.227 dst=255.255.255.255 sport=53917 dport=10308 [UNREPLIED] src=192.168.2.36 dst=192.168.1.227 sport=10308 dport=53917
 [UPDATE] udp      17 86400 src=192.168.1.227 dst=255.255.255.255 sport=53917 dport=10308 src=192.168.2.36 dst=192.168.1.227 sport=10308 dport=53917 [OFFLOAD]
    [NEW] udp      17 60 src=192.168.1.227 dst=255.255.255.255 sport=53917 dport=10310 [UNREPLIED] src=192.168.2.36 dst=192.168.1.227 sport=10310 dport=53917
 [UPDATE] udp      17 86399 src=192.168.1.227 dst=255.255.255.255 sport=53917 dport=10310 src=192.168.2.36 dst=192.168.1.227 sport=10310 dport=53917 [OFFLOAD]

I just cannot understand that OFFLOAD...

https://www.kernel.org/doc/html/v5.12/networking/segmentation-offloads.html

Well... it doesn't seem to be of any interest for my case.

I think I'm so close: I can see the return packet leaving the server, and logged in the router... but somehow it cannot reach the client, and I don't know where to look :\

A permissive firewall rule for initial responses is still necessary.
I'm afraid this kind of communication does not expect a firewall in the middle.

Well, that should be covered by

ACCEPT     all  --  anywhere             anywhere             ctstate RELATED,ESTABLISHED /* !fw3 */
ACCEPT     all  --  anywhere             anywhere             ctstate RELATED,ESTABLISHED /* !fw3 */
FLOWOFFLOAD  all  --  anywhere             anywhere             /* !fw3: Traffic offloading */ ctstate RELATED,ESTABLISHED FLOWOFFLOAD hw

isn't it?

EDIT: I also disabled offloading (unneeded noise in my head for now) and allowed all forwarding between the two zones, both directions, for the sake of testing, and still no joy :confused:

That is only relevant for related/established connections for unicast traffic.
The initial service discovery broadcast queries cannot be used for connection tracking.
So, the following unicast replies must be allowed explicitly.

But the reply seems to be a unicast reply from server to client, isn't that so? Because it's just the reply that is somehow dropped...

Connection tracking cannot associate unicasts with broadcasts, so netfilter considers unicasts as starting packets and drops them, since you have prohibited forwarding from the server to the clients.

Well, my understanding was that conntrack actually manages to correlate the two connections: now that I disabled offloading, I get:

    [NEW] udp      17 60 src=192.168.1.227 dst=255.255.255.255 sport=65137 dport=10308 [UNREPLIED] src=192.168.2.36 dst=192.168.1.227 sport=10308 dport=65137
 [UPDATE] udp      17 60 src=192.168.1.227 dst=255.255.255.255 sport=65137 dport=10308 src=192.168.2.36 dst=192.168.1.227 sport=10308 dport=65137
 [UPDATE] udp      17 60 src=192.168.1.227 dst=255.255.255.255 sport=65137 dport=10308 src=192.168.2.36 dst=192.168.1.227 sport=10308 dport=65137 [ASSURED]

And anyway, as I said, I also opened up forwarding for the whole zones but still can't see that packet going back...

Another, unfortuately small, progress:

On the OUTPUT chain I have ebtables logging these entries for the response:

IN= OUT=wlan0 MAC source = 9c:c9:eb:15:dd:ce MAC dest = 50:2f:9b:2a:ba:9d proto = 0x0800 IP SRC=255.255.255.255 IP DST=192.168.1.227, IP tos=0x00, IP proto=17 SPT=10308 DPT=51719
IN= OUT=wlan0 MAC source = 9c:c9:eb:15:dd:ce MAC dest = 50:2f:9b:2a:ba:9d proto = 0x0800 IP SRC=255.255.255.255 IP DST=192.168.1.227, IP tos=0x00, IP proto=17 SPT=10308 DPT=51719

Am I right assuming conntrack is playing a role here by routing the packet from the wrong source address? I would expect to have 192.16.2.36 as the SRC IP here, and not having this packet in the OUTPUT chain at all, but rather in the FORWARD chain...

Can you just add a vlan interface to the server and have it participate in the subnet of interest? You could filter the packets by bridge filtering so it only sees /sends the packets it needs.

The server is already in a separate VLAN: the "main bridge" (br-lan) uses the main wifi and 3 out of 4 ports in the router, and is assigned an own VLAN, firewall zone "lan" and the subnet 192.168.1.0. The server is on a different bridge with the 4th port and a separate wifi, the 192.168.2.0 subnet, a separate firewall zone and a separate VLAN.

I hope I gave you enough details. Could you please elaborate a bit more on your proposal? As I said my networking skills are quite basic (actualy I'm impressed I even managed to get this far...)

Thank you both @dlakelan and @vgaetera for your support. I ended up convincing myself that the best thing to do is to put the server in my same subnet, and achieving filtering through the bridge interfaces. I'll open a new thread for that.

EDIT: apparently my idea is not possible (see How to share the same subnet across two bridge interfaces? - #4 by psherman) so @dlakelan if you could please elaborate a bit more it would be great.

1 Like

The proposal is a little complicated I guess.

I'm thinking on the server create two tagged vlans, one for it's current DMZ or whatever and one for the LAN where you want to provide services. Then on the router you tag packets on the Ethernet port it's connected to. Finally, if you want to be able to filter stuff you would need to actually use tagged packets in a different vlan and bridge that with the LAN in a Linux bridge otherwise the switch will bridge them unfiltered.

Yeah, way beyond my skills I think.

I am reasoning about a simpler solution as said in the other thread (and I will try to keep even simpler by throwing the server in the same firewall zone and creating a rule to block every outgoing traffic from the server to other lanncloent except the only few that I will allow with another rule)