Linux IP Redirection: Mapping Internal to Public IP on Ubuntu 14.04 Using NAT


2 views

We often encounter situations where internal network resources need to be accessed from different networks. In this case, we have:

  • Machine A (local machine) trying to access Machine B using its private IP
  • Both machines running Ubuntu 14.04
  • Machines are on separate networks
  • Machine B has both private and public IP addresses

The most effective approach is to implement Network Address Translation (NAT) on Machine A to redirect internal IP requests to Machine B's public IP. Here's how:


# Enable IP forwarding
echo 1 | sudo tee /proc/sys/net/ipv4/ip_forward

# Add NAT rule to redirect traffic
sudo iptables -t nat -A OUTPUT -d 192.168.1.100 -j DNAT --to-destination 203.0.113.45
sudo iptables -t nat -A POSTROUTING -j MASQUERADE

Let's break this down with specific examples:


# Example scenario values:
# Machine B internal IP: 192.168.1.100
# Machine B public IP: 203.0.113.45

# Make the changes persistent across reboots
sudo apt-get install iptables-persistent
sudo iptables-save > /etc/iptables/rules.v4

For more complex scenarios, consider these additional parameters:


# Redirect specific ports only
sudo iptables -t nat -A OUTPUT -d 192.168.1.100 -p tcp --dport 80 -j DNAT --to-destination 203.0.113.45:80

# Redirect entire subnet
sudo iptables -t nat -A OUTPUT -d 192.168.1.0/24 -j DNAT --to-destination 203.0.113.45

After implementation, verify the setup:


# Check NAT rules
sudo iptables -t nat -L -n -v

# Test connectivity
ping 192.168.1.100
traceroute 192.168.1.100

If you encounter problems:

  • Ensure IP forwarding is enabled: cat /proc/sys/net/ipv4/ip_forward
  • Check firewall rules: sudo ufw status
  • Verify network routes: ip route show

When Machine A tries to access Machine B using its private IP (e.g., 192.168.1.100) while they're on different networks, we need to implement network address translation (NAT) to redirect these requests to B's public IP. This requires proper configuration on the router/gateway that connects Machine B's local network to the internet.

The most effective approach involves setting up Destination NAT (DNAT) rules on Machine B's gateway router. Here's the step-by-step implementation:

# Enable IP forwarding on the gateway
echo 1 > /proc/sys/net/ipv4/ip_forward

# Configure NAT rules
sudo iptables -t nat -A PREROUTING -d 192.168.1.100 -j DNAT --to-destination B.PUBLIC.IP.ADDRESS
sudo iptables -t nat -A POSTROUTING -s 192.168.1.0/24 -j SNAT --to-source B.PUBLIC.IP.ADDRESS
sudo iptables -A FORWARD -i eth0 -o eth1 -m state --state RELATED,ESTABLISHED -j ACCEPT
sudo iptables -A FORWARD -i eth1 -o eth0 -j ACCEPT

If you don't have router access, you can configure Machine B to handle the translation:

# On Machine B (Ubuntu 14.04)
sudo sysctl -w net.ipv4.ip_forward=1
sudo iptables -t nat -A PREROUTING -d B.PUBLIC.IP.ADDRESS -j DNAT --to-destination 192.168.1.100
sudo iptables -t nat -A POSTROUTING -s 192.168.1.100 -j SNAT --to-source B.PUBLIC.IP.ADDRESS

Verify the setup using these commands:

# Check NAT rules
sudo iptables -t nat -L -n -v

# Test connectivity
ping 192.168.1.100 # From Machine A
tcpdump -i eth0 host B.PUBLIC.IP.ADDRESS # On Machine B's gateway

For Ubuntu 14.04, make these changes permanent:

# Edit sysctl.conf
echo "net.ipv4.ip_forward = 1" | sudo tee -a /etc/sysctl.conf
sudo sysctl -p

# Save iptables rules
sudo apt-get install iptables-persistent
sudo service iptables-persistent save
  • Ensure proper routing tables on all machines
  • Check firewall settings (UFW on Ubuntu)
  • Verify that NAT rules are applied in correct order
  • Confirm that IP forwarding is actually enabled

For complex networks, consider adding route statements on Machine A:

sudo route add -host 192.168.1.100 gw A.DEFAULT.GATEWAY.IP