IP in VPN vs. LAN: Alias IP Address by iptables

| Created | Modified

Scenario: Using a Consistent IP Address

When you’re at work, you are on the LAN and use an IP address like 192.168.x.x. When you work from home, you connect via VPN to the same database (DB), and your IP address changes to 10.x.x.x. You want to avoid changing configuration files for your application every time you switch environments.

This problem can be easily worked around using iptables to create an IP address alias.

iptables packet flow diagram

https://gist.github.com/nerdalert/a1687ae4da1cc44a437d

The Solution using iptables

The following commands use Network Address Translation (NAT) to redirect traffic destined for your LAN IP (192.168.x.x) to your VPN IP (10.x.x.x) when the VPN is active.

# Enable IP forwarding, which is required for routing and NAT
sudo sh -c 'echo "1" > /proc/sys/net/ipv4/ip_forward'

# Define the target IP addresses for clarity
# LAN IP (the address you want to keep consistent in your app config)
IP_LAN=192.168.3.38

# VPN IP (the actual target IP when connected via VPN)
IP_VIRTUAL=10.8.4.38

Initial Test (Before iptables)

First, we confirm the VPN IP is reachable, but the LAN IP is not (because the system isn’t currently configured to handle it).

Ping the VPN IP (Success expected)

ping -c 1 -W 1 $IP_VIRTUAL
PING 10.8.4.38 (10.8.4.38) 56(84) bytes of data.
64 bytes from 10.8.4.38: icmp_seq=1 ttl=63 time=124 ms

# Ping the LAN IP (Failure expected, as it's not the current route)
ping -c 1 -W 1 $IP_LAN
PING 192.168.3.38 (192.168.3.38) 56(84) bytes of data.

--- 1.23.23.2 ping statistics ---
1 packets transmitted, 0 received, 100% packet loss, time 0ms

Applying the NAT Rules

We add two rules to the nat table:

# 1. DNAT: Redirect traffic destined for the LAN IP to the active VPN IP
sudo iptables -t nat -A PREROUTING -d $IP_LAN -j DNAT --to-destination $IP_VIRTUAL

# 2. MASQUERADE: Rewrite the source address of outgoing packets to ensure proper routing of return traffic
sudo iptables -t nat -A POSTROUTING -j MASQUERADE

Final Test (After iptables)

Now, traffic sent to the LAN IP is redirected by iptables, and the connection succeeds. Your application can now consistently connect to $IP_LAN, regardless of whether you’re on the LAN or the VPN.

# Ping the LAN IP again (Success expected due to NAT rule)
ping -c 1 -W 1 $IP_LAN
PING 192.168.3.38 (192.168.3.38) 56(84) bytes of data.
64 bytes from 192.168.3.38: icmp_seq=1 ttl=63 time=125 ms