IPv6 to IPv4 Port Forwarding with iptables: A Practical Guide for Network Configuration


11 views

Many legacy systems still rely on IPv4-only configurations, while modern infrastructure increasingly adopts IPv6. Bridging these protocols becomes essential when you need to expose IPv6 services through IPv4-only backend servers. Let's explore how iptables can solve this.

Before implementing the solution, ensure your system meets these requirements:

  • Linux kernel 2.6.32+ with IPv6 support
  • iptables 1.4.7+ with ip6tables module
  • IPv6 connectivity on the gateway machine
  • Proper routing between the gateway and IPv4 server

We'll use a dual-stack server as a gateway to:

  1. Accept IPv6 incoming connections
  2. Translate them to IPv4
  3. Forward to the backend IPv4 server
  4. Route responses back to IPv6 clients

Here's the complete iptables configuration for forwarding TCP port 80 from IPv6 to IPv4:

# Enable IPv6 forwarding
sysctl -w net.ipv6.conf.all.forwarding=1

# IPv6 DNAT rule (assuming gateway's IPv6 is 2001:db8::1)
ip6tables -t nat -A PREROUTING -d 2001:db8::1 -p tcp --dport 80 -j DNAT --to-destination 192.168.1.100:80

# IPv4 SNAT rule for return traffic
iptables -t nat -A POSTROUTING -d 192.168.1.100 -p tcp --dport 80 -j SNAT --to-source 192.168.1.1

# Forwarding between interfaces
iptables -A FORWARD -d 192.168.1.100 -p tcp --dport 80 -j ACCEPT

Verify the setup with these commands:

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

# Test connectivity
curl -6 http://[2001:db8::1]

For UDP services or multiple ports, modify the rules accordingly:

# UDP port forwarding example
ip6tables -t nat -A PREROUTING -d 2001:db8::1 -p udp --dport 53 -j DNAT --to-destination 192.168.1.100:53

# Port range forwarding
ip6tables -t nat -A PREROUTING -d 2001:db8::1 -p tcp --dport 8000:9000 -j DNAT --to-destination 192.168.1.100:8000-9000
  • Connection timeouts: Check IPv4 routing and firewall rules on the backend server
  • Partial connectivity: Verify both IPv4 and IPv6 modules are loaded in kernel
  • Rule not applying: Ensure the ip6tables service is running and rules persist after reboot

On most distributions, save rules with:

ip6tables-save > /etc/ip6tables.rules
iptables-save > /etc/iptables.rules

Then configure your init system to restore them at boot.


In some server setups, you might encounter a situation where a critical service is only accessible via IPv4, while your front-facing server supports IPv6. This can happen due to legacy configurations, hardware limitations, or network policies. The challenge is to bridge this gap without overhauling your entire infrastructure.

iptables remains a powerful tool for network address translation (NAT) in Linux systems, even in mixed IPv4/IPv6 environments. While newer tools like nftables exist, many administrators still rely on iptables for its widespread compatibility and familiar syntax.

Before implementing this solution, ensure:

  • Your IPv6-capable server has IPv4 connectivity to the target server
  • IPv6 forwarding is enabled (net.ipv6.conf.all.forwarding=1)
  • You have root access to configure iptables rules

Here's how to forward TCP port 80 traffic from IPv6 to an IPv4 server:

# Enable IPv6 forwarding
sysctl -w net.ipv6.conf.all.forwarding=1

# Allow incoming IPv6 connections
ip6tables -A INPUT -p tcp --dport 80 -j ACCEPT

# NAT the IPv6 traffic to IPv4
ip6tables -t nat -A PREROUTING -p tcp --dport 80 -j DNAT --to-destination 192.168.1.100:80

# Allow the forwarded traffic
iptables -A FORWARD -p tcp -d 192.168.1.100 --dport 80 -j ACCEPT

# Masquerade the outgoing IPv4 traffic
iptables -t nat -A POSTROUTING -p tcp -d 192.168.1.100 --dport 80 -j MASQUERADE

For forwarding multiple ports (e.g., 80 and 443), you can use multiport:

ip6tables -t nat -A PREROUTING -p tcp -m multiport --dports 80,443 -j DNAT --to-destination 192.168.1.100
iptables -A FORWARD -p tcp -d 192.168.1.100 -m multiport --dports 80,443 -j ACCEPT

To make these changes permanent:

# Save iptables rules
iptables-save > /etc/iptables/rules.v4
ip6tables-save > /etc/iptables/rules.v6

# Enable persistent forwarding
echo "net.ipv6.conf.all.forwarding=1" >> /etc/sysctl.conf
sysctl -p
  • Verify forwarding is working with tcpdump -i eth0 ip6 and tcpdump -i eth0 ip
  • Check kernel logs (dmesg) for NAT-related errors
  • Test connectivity from an IPv6 client using curl -6 http://[your-ipv6-address]

When implementing this solution:

  • Restrict source IPs if possible (-s flag in iptables)
  • Consider rate limiting to prevent abuse
  • Monitor forwarded traffic for unusual patterns