Given the following installation:
old router 192.168.1.1 with NAT forward of tcp port 80 to 192.168.1.10:80
new router 192.168.1.2 with NAT forward of tcp port 80 to 192.168.1.10:80
web server 192.168.1.10 with default gateway 192.168.1.1
Currently, the DNS entry for my service points to the external address of the old router. The router does a port forwarding of the traffic to the web server which returns the answer back to the old gateway.
For a seamless migration to a new router (with another external IP), I want to setup a new router first, test the whole thing with both connections active, and then change the DNS IP to the new external address.
Now, with the above setup, the old router still works. But tcp connections which are addressed to the new router, are also answered to the old router which cannot handle them.
I thought about using nat with masquerading but then all traffic which is addressed to the new router will look like local traffic. This tricks out server ip-based filters and logging.
Now, my plan is to use a helper PC with Debian and iptables for a temporary solution:
old router 192.168.1.1 with NAT forward of tcp port 80 to 192.168.1.10:80
new router 192.168.1.2 with NAT forward of tcp port 80 to 192.168.1.20:80
web server 192.168.1.10 with default gateway 192.168.1.20
helper pc 192.168.1.20
the helper pc is now responsible for finding the correct gateway:
- keep state of connections which were forwarded by 192.168.1.2 and forward them without modifying to 192.168.1.10 (i think about identifying them by their origin mac address and SYN)
- forward packets of tracked connections to 192.168.1.2
- forward packets of not-tracked connections to 192.168.1.1
I found a lot of input in the internet and especially serverfault.com (especially this one), but all of them cover only a single part of this problem. I guess it needs a combination of mac address based filter rules -m mac --mac-source <mac>
, NAT, states and rt_tables --set-mark
/ ip rule add fwmark
(--gw doesn't seem to be supported by Debian).
There are two effective solutions, depending on the scenario.
Solution 1: The webserver is Linux and fully under your control.
First, ensure that
/etc/iproute2/rt_tables
contains the following lines:Second, populate the tables
Third, create two iproute2 rules to 'shunt' processing to those custom tables:
Finally, create the set of iptables commands to mark the corresponding packets properly:
Solution 2: The webserver is not Linux and/or it is not fully under your control
This solution is very similar to the previous solution. The difference is in the set of iptables rules:
Edit: Modified Solution 2
Still the same as the above, but add:
this ensures that packets destined for the local network (I'm assuming
192.168.1.0/24
) will not be handled by the gateways.Also, add another
iptables
rule:Finally, have both gateways forward port 80 to the 'helper pc'; it will save a great deal of headache trying to troubleshoot 'half-open' connections (because, in your current plan the 'helper pc' can only see traffic originating from the webserver instead of traffic going bothways).
If it's for a local test only you could use -s option of iptables to tell your old router that if the traffic originate from that source IP, forward it to the new router. Then your new router will be forwarding your request to the web server (based on the configuration you provided).
Even if you are testing from outside you setup, you can still filter your source address ip with -s.
Example: