Source NAT between VLANs?

Started by tchubaba, September 25, 2023, 10:17:06 PM

Previous topic - Next topic
Hi all. I'm in the process of segregating my home network to separate IOT devices from my main network. I have created two VLANs, one is MAIN (192.168.1.1/24) and the other one is the IOT (192.168.2.1/24) one. To the IOT subnet, I'm connecting 3 Reolink cameras I have. I have created a firewall rule to allow access from the the MAIN subnet to the IOT subnet, like this:

Rule:
Action: Pass
TCP/IP Version: IPv4
Protocol: any
Source: MAIN net
Dest/Invert: unchecked
Destination: reolink_cams
Dest Port: any
Description: Allow access to Reolink cams

Alias:
Name: reolink_cams
Type: Host(s)
Content: (the cameras IP addresses, which are static)
Description: Reolink IP cams

From a Windows PC in the MAIN subnet, I am able to ping all three cameras with this setup, indicating the firewall rule works. However, I am unable to connect to them using the Reolink client via IP address on port 9000. I have created a post in the Reolink forums, and the moderator there said that, by design, Reolink cameras will only accept connections from devices in the same subnet, thus why I can't connect. He suggested that I "Source NAT" my traffic so that traffic from MAIN appears to be originating from the same subnet as devices on IOT.

From my research to this point, it appears that I should be able to accomplish this by creating a rule under "Firewall > NAT > Outbound". In there, I select Hybrid and then I create a rule. This is the rule I have created:

Rule:
Interface: MAIN
TCP/IP Version: IPv4
Protocol: any
Source address: MAIN net
Source port: any
Destination invert: unchecked
Destination address: IOT net
Destination port: any
Translation / target: Interface address

However, this does not appear to work, as I still cannot get the client app to connect to the cameras. I have tried variations of this rule where in "Destionation address:" I use the "reolink_cams" alias or "IOT address" to no avail.

So I ask if this is the correct approach I should take to accomplish my goal of "Source NATing" traffic from the MAIN subnet to the IOT subnet. If yes, what am I doing wrong? If not, what should I do instead?

I appreciate any insight!

Can you try this rule:

Interface: IOT
TCP/IP Version: IPv4
Protocol: any
Source address: 192.168.1.0/24
Source port: any
Destination invert: unchecked
Destination address: any (or 192.168.2.0/24 if you want more restrictions, but try any first)
Destination port: any
Translation / target: 192.168.2.1
Hardware:
DEC740

Thanks for the reply, Monviech. Unfortunately that rule did not work either. I tried with both the "Destination address" set to "any" and "192.168.2.0/24". I also tried changing the interface back to MAIN in your rule, but again, no dice. Unable to connect in any of these scenarios.

Please check if your nat rules are set to hybrid so a related rule is created to allow the incoming traffic into the IOT network. It should appear on the automatically generated list.
Also this port is used for RTP traffic, so try enabling static port.

It is indeed set to hybrid and I did enable static port. Unfortunately, that didn't help either.

It seems I have other underlying issues preventing access across VLANs. I decided to run a few tests to see if Source NAT was working at all, so I connected a laptop to the IOT VLAN, running a nginx webserver (which I am able to access locally). I then ran tcpstat to check on incoming connections to this laptop. In a PC in the MAIN VLAN, I tried to connect to the nginx server in the laptop.

tcpstat did show the incoming connection, but its IP was from the MAIN VLAN, and not the IOT gateway. Furthermore, the connection never established. It got stuck on SYN_RECV. I then disabled the Outbound NAT rule to see if the connection would establish, but even then, it never did.

It seems I have some routing problems in my network, which I'm trying to troubleshoot. At this time, I have no clue what it could be.

September 26, 2023, 09:25:55 AM #5 Last Edit: September 26, 2023, 09:27:39 AM by Monviech
I have just verified it just to be sure, the rule I have posted above is the right way to do it.

Here is my test Setup:

Client A:
LAN: 172.16.0.141/24
Default Route: 0.0.0.0/0 next hop 172.16.0.254
^
| 172.16.0.0/24
v
Opnsense:
LAN: 172.16.0.254/24
DMZ: 10.0.0.254/24
^
| 10.0.0.0/24
v
Server A:
DMZ: 10.0.0.203/24
Default Route: 0.0.0.0/0 next hop 10.0.0.254



OUTBOUND NAT RULE:

Interface: DMZ
TCP/IP Version: IPv4
Protocol: any
Source address: 172.16.0.0/24
Source port: any
Destination address: 10.0.0.0/24
Destination port: any
Translation / target: DMZ address


PING from CLIENT A to SERVER A:

ping 10.0.0.203
PING 10.0.0.203 (10.0.0.203) 56(84) bytes of data.
64 bytes from 10.0.0.203: icmp_seq=1 ttl=63 time=1.23 ms
^C
--- 10.0.0.203 ping statistics ---
1 packets transmitted, 1 received, 0% packet loss, time 0ms
rtt min/avg/max/mdev = 1.232/1.232/1.232/0.000 ms


TCPDUMP:

Client A:
root@clientA: tcpdump -i eth0 proto ICMP -n
tcpdump: verbose output suppressed, use -v[v]... for full protocol decode
listening on eth0, link-type EN10MB (Ethernet), snapshot length 262144 bytes
09:19:20.264690 IP 172.16.0.141 > 10.0.0.203: ICMP echo request, id 4, seq 1, length 64
09:19:20.265900 IP 10.0.0.203 > 172.16.0.141: ICMP echo reply, id 4, seq 1, length 64


Opnsense:
LAN (hn6):
root@opn01:~ # tcpdump -i hn6 proto ICMP -n
tcpdump: verbose output suppressed, use -v or -vv for full protocol decode
listening on hn6, link-type EN10MB (Ethernet), capture size 262144 bytes
09:19:20.201785 IP 172.16.0.141 > 10.0.0.203: ICMP echo request, id 4, seq 1, length 64
09:19:20.202352 IP 10.0.0.203 > 172.16.0.141: ICMP echo reply, id 4, seq 1, length 64
09:19:20.202521 IP 10.0.0.203 > 172.16.0.141: ICMP echo reply, id 4, seq 1, length 64


DMZ (hn7):
root@opn01:~ # tcpdump -i hn7 proto ICMP -n
tcpdump: verbose output suppressed, use -v or -vv for full protocol decode
listening on hn7, link-type EN10MB (Ethernet), capture size 262144 bytes
09:19:20.201844 IP 10.0.0.254 > 10.0.0.203: ICMP echo request, id 15913, seq 1, length 64
09:19:20.202000 IP 10.0.0.254 > 10.0.0.203: ICMP echo request, id 15913, seq 1, length 64
09:19:20.202325 IP 10.0.0.203 > 10.0.0.254: ICMP echo reply, id 15913, seq 1, length 64


Server A:
root@serverA:# tcpdump -i eth0 proto ICMP -n
tcpdump: verbose output suppressed, use -v or -vv for full protocol decode
listening on eth0, link-type EN10MB (Ethernet), capture size 262144 bytes
09:19:20.263775 IP 10.0.0.254 > 10.0.0.203: ICMP echo request, id 15913, seq 1, length 64
09:19:20.263846 IP 10.0.0.203 > 10.0.0.254: ICMP echo reply, id 15913, seq 1, length 64


Please verify that you have the same results.
Hardware:
DEC740