How To Simulate an IP-Adress Change On A NAT WAN Interface

The vast majority of Internet traffic is still over IPv4 and when I look at all the different kinds of connectivity I use for connecting my PC and smartphone to the Internet, there isn't a single scenario in which I have a public IPv4 address for those devices. Instead, I am behind at least one Network Address Translation (NAT) gateway, that translates a private IPv4 address into another IPv4 address, either a public IPv4 or another private one in case several NATs are cascaded. While that usually works well, every now and then one of those NATs change their IP address on their WAN interface which creates trouble in some use cases.

Applications that use the TCP transport protocol quickly notice this as their TCP link gets broken by the process. Higher layers are notified that the TCP link is broken and apps can reestablish communication to their counterpart. Apps using UDP as a transport protocol, however, have a somewhat harder time. UDP keep-alive packets sent in one direction to keep NAT translations in place are not enough as they just end up in nirvana. Bi-directional UDP keep alive packets also end up in nirvana without the application on top ever being notified about it. The only chance they have is to implement a periodic keep-alive 'ping' and a timeout after which the connection is to be considered broken.

Recently I had to simulate such behavior and wondered how to best do that. Again a Raspberry Pi acting as a Wi-Fi access point, NAT and Ethernet backhaul served as a great tool. Three shell commands are enough to simulate an IP-address change on the WAN-interface:

Do a 'sudo nano /etc/dhcp/dhclient.conf' and insert the following line:

    send dhcp-requested-address;

The IP address needs to be replaced with an IP-address of the subnet of the WAN interface but different from the one currently used. Obviously that IP address must not be used by any other device on the WAN subnet which can be checked by pinging the IP address before changing the configuration file.

Next, disable the dhcp client on the WAN interface with

   dhclient -r -v

The interface itself remains up so Wireshark does not stop an ongoing trace but IP-connectivity is removed. If the scenario to be simulated requires a certain time before a new IP address is available, just pause before inputting the next command.

A new IP address can then be requested with

   dhclient -v eth0

The result returned by the command shows if the requested IP has been granted or if the DHCP server has assigned the previous IP address again or perhaps even an entirely different one. If the DHCP server has assigned the old IP address, changing the MAC address after disabling the dhcp client will probably help.

And that's all there is to it except for one 'little' thing: If the Raspberry Pi or other Linux device you perform these actions on are yet again behind another NAT, the server on the Internet will not see an IP address change but just a different TCP or UDP port for an incoming packet. So while in some scenarios the connection will still break there are potentially scenarios in which a connection can survive. One example is an ongoing conversation over UDP. If the NATs assign the same UDP port translations on all interfaces again, which can but does not necessarily have to happen and the first UDP packet is sent from the NATed network, the connection might just survive. I can imagine some TCP survival scenarios as well so don't assume but check carefully if the exercise produces the expected changes in IP address and port nubmers for your network setup.

Have fun!