IPv4 to IPv6 static NAT-PT by Linux box running NAPTD

If a client in IPv4-only network, wants to access servers in IPv6-only network, a Linux box can be setup between 2 networks, working as a gateway. It runs NAPTD software, which does IPv4 to IPv6 NATing.

I am going to setup 3 virtual machines to simulate this setup.

The network topology is:
ipv4-to-ipv6-NAT-PT-by-NAPTD

3 VMs are running RHEL/CentOS 7.2 Linux.

IPv4 node setup

Setup eth1 ipv4 address by editting ifcfg-eth1 file:

[root@ipv4 ~]# cat /etc/sysconfig/network-scripts/ifcfg-eth1
DEVICE=eth1  
NM_CONTROLLED=no  
TYPE=Ethernet  
IPADDR=172.34.0.2  
PREFIX="24"  
BOOTPROTO=static  
ONBOOT=yes  

Start eth1:

ifdown eth1 && ifup eth1  

IPv6 node setup

Setup eth1 ipv6 address by editting ifcfg-eth1 file:

[root@ipv6 ~]# cat /etc/sysconfig/network-scripts/ifcfg-eth1
DEVICE=eth1  
NM_CONTROLLED=no  
TYPE=Ethernet  
BOOTPROTO=static  
ONBOOT=yes  
IPV6INIT=yes  
IPV6ADDR=2001:a:b:c::2/64  

Setup route to NAPTD virtual network by creating route6-eth1 file:

[root@ipv6 ~]# cat /etc/sysconfig/network-scripts/route6-eth1
2000:ffff::/64 via 2001:a:b:c::1  

Start eth1:

ifdown eth1 && ifup eth1  

Setup NAT-PT gateway node

Configure IPv4 and IPv6 interfaces

Setup eth1 ipv6 address:

[root@natpt ~]# cat /etc/sysconfig/network-scripts/ifcfg-eth1
DEVICE=eth1  
NM_CONTROLLED=no  
TYPE=Ethernet  
BOOTPROTO=static  
ONBOOT=yes  
IPV6INIT=yes  
IPV6ADDR=2001:a:b:c::1/64  

Setup eth2 ipv4 address:

[root@natpt ~]# cat /etc/sysconfig/network-scripts/ifcfg-eth2
DEVICE=eth2  
NM_CONTROLLED=no  
TYPE=Ethernet  
IPADDR=172.34.0.1  
PREFIX="24"  
BOOTPROTO=static  
ONBOOT=yes  

Start eth1 and eth2 ports:

ifdown eth1 && ifup eth1  
ifdown eth2 && ifup eth2  

Install and configure naptd

Download RPM package from http://tomicki.net/naptd.download.php

Install naptd rpm package:

yum install naptd-0.4-1.i386.rpm  

It also installs some dependencies from RHEL7 base OS repo, so make sure you have that repo configured.

Install iptables, it's needed by naptd:

yum install iptables  

Run naptd-confmaker to generate naptd configuration file, it'a interactive tool to ask you several questions about how you want to use naptd:

[root@natpt ~]# naptd-confmaker
Ataga IPv4/IPv6 NAPT Configuration Maker  
(c) 2005 by Lukasz Tomicki <tomicki@o2.pl>

Do you want to create a new configuration? [Y/n]

Do you want IPv4 addresses from the outside interfaces to be automatically used as part of the NAT pool? [Y/n]

Do you want to configure additional address as part of your NAT pool? [y/N]  
n  
Do you want to create a pool of public IPv4 addresses that will allow incoming connections to be dynamically mapped to appropriate IPv6 addresses? [y/N]  
n  
Do you want to create static mappings of public IPv4 addresses that will allow incoming connections to reach IPv6 hosts? [y/N]  
y  
IPv4 address: 172.34.0.102  
IPv6 address: 2001:a:b:c::2

Do you want to enter another static mapping? [y/N]  
n  
Enter the name of the first inside (IPv6) interface that you want NAT-PT to listen on.  
interface (eth0 eth1 eth2): eth1

Do you want to enter more interfaces? [y/N]  
n  
Enter the name of the first outside (IPv4) interface that you want NAT-PT to listen on.  
interface (eth0 eth1 eth2): eth2

Do you want to enter more interfaces? [y/N]  
n  
Enter the TCP translation timeout in seconds [86400]:  
Enter the UDP translation timeout in seconds [3600]:  
Enter the ICMP translation timeout in seconds [30]:

Enter the IPv6 prefix that will be used as the destination for translations.  
prefix [2000:ffff::]:

Please enter the IPv4 address of the DNS server you are currently using.  
IPv4 DNS server: 127.0.0.1

You can configure hosts for automatic DNS translation by using the DNS server below.  
IPv6 DNS Server: 2000:ffff::7f00:1

Thank you for choosing Ataga as you IPv4/IPv6 NAT-PT solution.  
Setup is now complete. Type 'naptd' to start NAT-PT.  

Setup necessary iptables and ip6tables rules to make naptd working:

ip6tables -A OUTPUT -p icmpv6 --icmpv6-type 1 -j DROP  
ip6tables -A FORWARD -d 2000:ffff:: -j DROP

iptables -A INPUT -i lo -j ACCEPT  
iptables -A INPUT -m state --state NEW -m tcp -p tcp --dport 22 -j ACCEPT  
iptables -A INPUT -m state --state ESTABLISHED,RELATED -j ACCEPT  
iptables -A INPUT -j DROP  

Finally, start naptd daemon:

[root@natpt ~]# naptd
Going daemon. Check syslog messages for runtime information.  

You should see some logs like:

[root@natpt ~]# tail -n 20 /var/log/messages
Jan 27 00:44:36 natpt naptd[2229]: Starting NAT-PT.  
Jan 27 00:44:36 natpt naptd[2230]: Initializing Application Level Gateways.  
Jan 27 00:44:36 natpt naptd[2230]: Loaded Domain Name Service plugin.  
Jan 27 00:44:36 natpt naptd[2230]: Loaded File Transfer Protocol plugin.  
Jan 27 00:44:36 natpt naptd[2230]: Dispatching threads.  
Jan 27 00:44:36 natpt kernel: device eth2 entered promiscuous mode  
Jan 27 00:44:36 natpt kernel: device eth1 entered promiscuous mode  
Jan 27 00:44:37 natpt naptd[2230]: Loading IPv4 routes into cache.  
Jan 27 00:44:37 natpt naptd[2230]: Loading IPv6 routes into cache.  
Jan 27 00:44:37 natpt naptd[2230]: Dropping root privileges.  
Jan 27 00:44:37 natpt naptd[2230]: NAT-PT initialized.  

Try to connect IPv6 node from IPv4 node

Now we have everything set, we know we have a static mapping, which map 172.34.0.102 to 2001:a:b:c::2, so let's try to ping IPv6 node via this gateway:

[root@ipv4 ~]# ping 172.34.0.102
PING 172.34.0.102 (172.34.0.102) 56(84) bytes of data.  
64 bytes from 172.34.0.102: icmp_seq=1 ttl=63 time=0.703 ms  
64 bytes from 172.34.0.102: icmp_seq=2 ttl=63 time=0.759 ms  
64 bytes from 172.34.0.102: icmp_seq=3 ttl=63 time=0.544 ms  
64 bytes from 172.34.0.102: icmp_seq=4 ttl=63 time=0.688 ms  
^C
--- 172.34.0.102 ping statistics ---
4 packets transmitted, 4 received, 0% packet loss, time 3000ms  
rtt min/avg/max/mdev = 0.544/0.673/0.759/0.083 ms  

It works!!!

We can look into more details how it works.

From NAT-PT gateway node, we can tcpdump IPv4 port to see IPv4 side packets:

[root@natpt ~]# tcpdump -nni eth2 arp or icmp
01:38:18.859504 ARP, Request who-has 172.34.0.102 tell 172.34.0.2, length 28  
01:38:18.859569 ARP, Reply 172.34.0.102 is-at 52:54:00:93:2a:7e, length 28  
01:38:18.859741 IP 172.34.0.2 > 172.34.0.102: ICMP echo request, id 2211, seq 1, length 64  
01:38:18.860216 IP 172.34.0.102 > 172.34.0.2: ICMP echo reply, id 2211, seq 1, length 64  

So we can see first naptd responses ARP request against 172.34.0.102, then we see icmp request and reply packets flying.

How about IPv6 side? Let's take a look:

[root@natpt ~]# tcpdump -nni eth1 icmp6
01:42:37.688777 IP6 2000:ffff::ac22:2 > 2001:a:b:c::2: ICMP6, echo request, seq 1, length 64  
01:42:37.689107 IP6 2001:a:b:c::2 > 2000:ffff::ac22:2: ICMP6, echo reply, seq 1, length 64  
01:42:38.689037 IP6 2000:ffff::ac22:2 > 2001:a:b:c::2: ICMP6, echo request, seq 2, length 64  
01:42:38.689478 IP6 2001:a:b:c::2 > 2000:ffff::ac22:2: ICMP6, echo reply, seq 2, length 64  

We can see on IPv6 side, source IP is replaced with 2000:ffff::ac22:2, this is a virtual IPv6 network used by naptd to do SNAT. 2000:ffff is the prefix defined during naptd-confmaker run.