I have to connect multiple, potentially hundrets of networks (branch offices) with overlapping network ranges to a single "core" network using OpenVPN. I wonder if there is a tool that helps me statically mapping ipv4 addresses in a single ipv6 address range.

Let's say, I have four branch offices, with the following address ranges:

Location A: 192.168.1.x/24
Location B: 192.168.1.x/24  (not a typo, same as A)
Location C:

for any given ipv4 adress a.b.c.d, I would like to "embed" it in it's own ipv6 range, for example 2a03:1000:{location}:ab:cd (2a03:1000 randomly chosen for this example)

Location A would be mapped to 2a03:1000:0001::c0a8:01xx  (c0=192, a8=168, 01=1, xx=host part)
Location B would be mapped to 2a03:1000:0002::c0a8:01xx  (c0=192, a8=168, 01=1, xx=host part)
Location B would be mapped to 2a03:1000:0003::0c0c:0100 
                                        ^^^^  ^^^^^^^^^
                                          |       |
                                          |       | ipv4 address range
                                          | location or site id

I think you get the idea ... This way, the overlapping is no longer a problem since these are all unique valid ipv6 addresses. The communication inside each location is still ipv4, and to and from the ipv6 core network each location is identified by it location id as part of the ipv6 address.

As a result, I need routable ipv6 traffic between the core network and each site. It's not required to have traffic between the sites.

Can you give me a kind hint of this is possible and how to implement this using Linux tools such as iptables/nftables or any other software?

Thank you very much!


2 Answers 2


What you are looking for is called SIIT. You can use it to statelessly map between IPv4 and IPv6 addresses. Take a look at the Linux module at https://jool.mx.

  • This looks very promising. I'll take a close look at it in the next few days. Thank you!
    – Sig
    Commented Apr 28, 2021 at 8:57

I would suggest to start with IPv4 to IPv6 conversion using a simple bash script. The input file (ipv4.txt) will contain site IDs and IPv4 subnets (in CIDR notation). Site IDs and subnets are colon (:) delimited. Site ID is limited to two bytes (two characters only) because a single IPv6 quartet is two bytes long. This means that each IPv6 quartet is represented by four HEX digits.

$ cat ipv4.txt

From the output above, we can see that Site-US and Site-UK have conflicting subnets, but IPv6 conversion will solve the problem. Once you have all the abbreviated site IDs with corresponding subnets, you can execute the following script:

# Read IPv4 subnets from a text file ipv4.txt
echo "Converted IP addresses" > ipv6.txt
echo "======================" >> ipv6.txt
while read x; do
        # Declare site as TEXT value
        a=$(echo -n "$x" | cut -d ":" -f 1)
        # Declare site as HEX value
        b=$(echo -n "$a" | xxd -p)
        # Declare subnet
        subnet=$(echo -n "$x" | cut -d ":" -f 2)
        # Expand an IPv4 subnet using prips command and replace periods (.)
        # with single space and store the results in temp.txt file
        # We must remove periods (.) before we convert IPv4 to HEX values
        prips $subnet | awk '{print "'$site' " $0}'| tr '.' ' ' > temp.txt
        # Convert all single IPv4 addresses to HEX using a while loop
        echo >> ipv6.txt
        echo "Site: $a" >> ipv6.txt
        echo "=========================" >> ipv6.txt
        while read y; do
        # Append results to a text file ipv6.txt (Note: I have hardcoded 2a03:1000)
        ip=$(echo $y | tr ' ' '.')
        printf '%x\n' $y | tr '\n' ':' | awk '{print "'$ip' - " "2a03:1000:'$b'::" $0}' | sed 's/.$//' >> ipv6.txt
        done < temp.txt
done < ipv4.txt

Your output should look similar to this:

$ cat ipv6.txt
Converted IP addresses

Site: US
========================= - 2a03:1000:5553::c0:a8:1:0 - 2a03:1000:5553::c0:a8:1:1 - 2a03:1000:5553::c0:a8:1:2 - 2a03:1000:5553::c0:a8:1:3 - 2a03:1000:5553::c0:a8:1:4 - 2a03:1000:5553::c0:a8:1:5 - 2a03:1000:5553::c0:a8:1:6 - 2a03:1000:5553::c0:a8:1:7 - 2a03:1000:5553::c0:a8:1:8 - 2a03:1000:5553::c0:a8:1:9 - 2a03:1000:5553::c0:a8:1:a - 2a03:1000:5553::c0:a8:1:b - 2a03:1000:5553::c0:a8:1:c - 2a03:1000:5553::c0:a8:1:d - 2a03:1000:5553::c0:a8:1:e - 2a03:1000:5553::c0:a8:1:f

Site: C2
========================= - 2a03:1000:4332::a:14:1e:e0 - 2a03:1000:4332::a:14:1e:e1 - 2a03:1000:4332::a:14:1e:e2 - 2a03:1000:4332::a:14:1e:e3 - 2a03:1000:4332::a:14:1e:e4 - 2a03:1000:4332::a:14:1e:e5 - 2a03:1000:4332::a:14:1e:e6 - 2a03:1000:4332::a:14:1e:e7

Site: NL
========================= - 2a03:1000:4e4c::ac:1e:32:80 - 2a03:1000:4e4c::ac:1e:32:81 - 2a03:1000:4e4c::ac:1e:32:82 - 2a03:1000:4e4c::ac:1e:32:83 - 2a03:1000:4e4c::ac:1e:32:84 - 2a03:1000:4e4c::ac:1e:32:85 - 2a03:1000:4e4c::ac:1e:32:86 - 2a03:1000:4e4c::ac:1e:32:87 - 2a03:1000:4e4c::ac:1e:32:88 - 2a03:1000:4e4c::ac:1e:32:89 - 2a03:1000:4e4c::ac:1e:32:8a - 2a03:1000:4e4c::ac:1e:32:8b - 2a03:1000:4e4c::ac:1e:32:8c - 2a03:1000:4e4c::ac:1e:32:8d - 2a03:1000:4e4c::ac:1e:32:8e - 2a03:1000:4e4c::ac:1e:32:8f

Site: UK
========================= - 2a03:1000:554b::c0:a8:1:0 - 2a03:1000:554b::c0:a8:1:1 - 2a03:1000:554b::c0:a8:1:2 - 2a03:1000:554b::c0:a8:1:3 - 2a03:1000:554b::c0:a8:1:4 - 2a03:1000:554b::c0:a8:1:5 - 2a03:1000:554b::c0:a8:1:6 - 2a03:1000:554b::c0:a8:1:7 - 2a03:1000:554b::c0:a8:1:8 - 2a03:1000:554b::c0:a8:1:9 - 2a03:1000:554b::c0:a8:1:a - 2a03:1000:554b::c0:a8:1:b - 2a03:1000:554b::c0:a8:1:c - 2a03:1000:554b::c0:a8:1:d - 2a03:1000:554b::c0:a8:1:e - 2a03:1000:554b::c0:a8:1:f

Once you have all the IPv6 addresses, you can feed them into Linux iptables / OpenVPN or commercial firewall / VPN solution.

Resources: IPv6 Explained, prips command, xxd command

  • Thank you for this solution and the valuable links. I check the static NAT if the suggestion to go with SIIT, and if this does not work, I'll follow your proposal.
    – Sig
    Commented Apr 28, 2021 at 8:59
  • And don't overlook the ipaddress module for python3 docs.python.org/3/library/ipaddress.html. Commented Apr 30, 2021 at 0:57

You must log in to answer this question.

Not the answer you're looking for? Browse other questions tagged .