Debian – iptables – bridge / routing between two independent LANs (and router)

bridgedebianifconfigip-forwardingsubnet

I can't find a solution in a network like in the drawing below.

  • I need to be able to open admin page of router 2 on LAN2 from a pc in
    a LAN1, w/o routing throught Internet.
  • I have a "bridge" PC with 2 NIC and linux (Debian) and I can doing everything on it.

I would like that from any PC connected to LAN 1 it's possible to access port 80 of the LAN 2 router.

     Internet 1                         Internet 2
        !                                   !
+---------------------+             +---------------------+
| Router 1            |             | Router 2            |
| LAN 192.168.55.1/24 |             | LAN 192.168.2.1/24  |
|                     |             |                     |
+---------------------+             +---------------------+
        |                                   |
        |                                   |
        |       +-----------------------+   |
        |       |                       |   |
        |       |         BRIDGE        |   |
        |-------|eth0                   |   |
        |       |192.168.55.2       eth1|---|
        |       |            192.168.2.2|   |
        |       +-----------------------+   |
        |                                   |
        |                                   |
    Other clients                       other clients
     LAN 1                                  LAN 2

The idea is to set a port (example 8080) on eth0, of the (PC) "bridge" and exit on eth1 on LAN 2 to the IP of the router 192.168.2.1:80

The answer from 192.168.2.1 would not go through the gateway but would go back to eth1.
After manipulation, the IP pachet come out from eth0.
The "bridge" should replace the source address, as if it originated from 192.168.55.2.

I've done a lot of testing, but I can't find a solution with various test with iptables settings.

Obviously, I enabled ip_forward = 1
and I set iptables so.

iptables -A FORWARD -i eth0 -o eth1 -p tcp --dport 8080 -j ACCEPT
iptables -A PREROUTING -t nat -p tcp -i eth0 --dport 8080 -j DNAT --to 192.168.2.1:80

and forwarding:

sysctl -a | grep "\.forwarding" | grep ipv4
sysctl: reading key "net.ipv6.conf.all.stable_secret"
sysctl: reading key "net.ipv6.conf.default.stable_secret"
sysctl: reading key "net.ipv6.conf.eth0.stable_secret"
sysctl: reading key "net.ipv6.conf.lo.stable_secret"
sysctl: reading key "net.ipv6.conf.wlan0.stable_secret"
net.ipv4.conf.all.forwarding = 1
net.ipv4.conf.default.forwarding = 1
net.ipv4.conf.eth0.forwarding = 1
net.ipv4.conf.lo.forwarding = 1
net.ipv4.conf.wlan0.forwarding = 1

has anyone had a similar problem and can you give me a hint?

Thanks in advance!

Best Answer

You are moving in good direction but you are on half way... literally :-). The problem is with the answer - way back.

@Router 1
default => "internet GW"
192.168.55.0/24 => LAN
  # 192.168.55.2 is ok
  # 192.168.2.0/24 is unknown - "matched" by default route
@Router 2
default => "internet GW"
192.168.2.0/24 => LAN
  # 192.168.2.2 is ok
  # 192.168.55.0/24 is unknown - "matched" by default route
iptables -A PREROUTING -t nat -p tcp -i eth0 --dport 8080 -j DNAT --to 192.168.2.1:80

This rule would change just destination but not changing source. Let's think about source IP 192.168.55.55: (SRC) 192.168.55.55:<port> => 192.168.55.2:8080 (DST) is changed by this rule to (SRC) 192.168.55.55:<port> => 192.168.2.1:80 (DST) and properly routed. This part would work without issue. The problem starts once Router2 will try to respond. Based on routing table the address 192.168.55.55 is matched by "default" and routed to the internet.

option 1 - changes realized on "bridge"

To have it working you need also "touch" source IP on "bridge" so Router2 will send communication to 192.168.2.2 so it will be possible to NAT it back. You can realize it by adding following rule:

iptables -A POSTROUTING -t nat -s 192.168.55.0/24 -o eth1 -d 192.168.2.0/24 -j MASQUERADE

option 2 - changes realized on "Router2"

Once you would add route 192.168.55.0/24 => 192.168.2.2 it will also start working. The routing table on Router2 would be

@Router 2
default => "internet GW"
192.168.2.0/24 => LAN
192.168.55.0/24 => 192.168.2.2
  # 192.168.2.2 is ok
  # 192.168.55.0/24 is routed via 192.168.2.2

--- edit : 2019/03/23 ---

  • removed -i eth0 in "offered" rule related to POSTROUTING (Thanks for feedback - my fault, sure POSTROUTING cannot operate with source interface as routing process is done and source interface is not available/relevant information)

Next to it there is the most probably similar situation for the answer as it is not NATed "back" to 192.168.55.2:8080 ;-). I have midnight now so some logical faul may happen (as "original" option 2 is working for you):-D. Take this edited stuff like brainstorming for future study...

I see two options for that.

option 1

Set the same rule for the connection on reverse direction so all the time (both direction) will be visible on the subnet as communication with the gateway... The port 8080 will be available for the initialization of the communication but the following communication will not use it...

iptables -A POSTROUTING -t nat -d 192.168.55.0/24 -o eth0 -s 192.168.2.0/24 -j MASQUERADE

option 2

you can "NAT back" to directly port 8080 so even folowing communication would work. As we are working with --sport we have to specify protocol (-p) which is not needed in case we are working just with IPs like in previous option ;-).

iptables -A POSTROUTING -t nat -p tcp -d 192.168.55.0/24 -o eth0 -s 192.168.2.1 --sport 80 -j SNAT --to-source 192.168.55.2:8080

Hopefully this will help you to make it fully working as you suppose ;-). Good Luck !