Managing IPv4 islands with Jool and OpenWrt

Posted on 2020-12-15 by ungleich

Introduction

At ungleich we are using Jool in a variety of scenarios with NAT64 or SIIT. The main use of jool in our infrastructure is to enable IPv6 only hosts to communicate with the IPv4 Internet.

However today we want to show you a different use case of jool: Enabling IPv4 islands to communicate with the IPv6 Internet.

For this we will focus on using Jool on OpenWrt, because this is a platform that you can also easily use in your networks or even at home.

The general problem to solve

The literally biggest problem to solve when connecting the two different worlds is that the IPv6 space is significantly bigger. This is a problem, because we cannot achieve a 1:1 mapping from the IPv4 world, but we can do a 1:1 mapping from the IPv6 world:

Installing jool

Installing jool on OpenWrt is very easy, it is just a matter of installing the kernel module and the tools for managing jool:

opkg update
opkg install kmod-jool jool-tools

Making IPv4 islands reachable

Assume that you are mostly running IPv6 only networks. And you happen to have some hosts, which, for whatever reason, cannot be switched to IPv6. We can use a stateful NAT64 to map "the whole IPv6 Internet" to 192.0.2.1 as follows:

This works pretty similar to regular NAT that you are used from home. If we compare it visually, it is even more clear:

Let's have a look at this in an OpenWrt context:

  • The LAN network is usually 192.168.1.0/24
  • The router's IPv4 address is usually 192.168.1.1
  • In this example we routed 2a0a:e5c1:18f::/48 to the router
  • 192.168.1.0/24 has 8 bits for the hosts (32-24=8)
  • We choose 2a0a:e5c1:18f:b00::/120 to map the IPv4 island (128-120=8)
  • We use the OpenWrt's standard address to masquerade/squash the IPv6 Internet

First we will create an "IPv4 pool":

root@vigir2:~# jool -4 -a 192.168.1.1
root@vigir2:~# jool -4
+------------+-------+--------------------+-----------------+-------------+
|       Mark | Proto |     Max iterations |         Address |       Ports |
+------------+-------+--------------------+-----------------+-------------+
|          0 |   TCP |       1024 ( auto) |     192.168.1.1 |     1-65535 |
+------------+-------+--------------------+-----------------+-------------+
|          0 |   UDP |       1024 ( auto) |     192.168.1.1 |     1-65535 |
+------------+-------+--------------------+-----------------+-------------+
|          0 |  ICMP |       1024 ( auto) |     192.168.1.1 |     0-65535 |
+------------+-------+--------------------+-----------------+-------------+
  (Fetched 3 samples.)

This allows jool to map IPv6 addresses stateful to 192.168.1.1 and basically allows incoming IPv6 traffic. What is left now is to configure the mapping from IPv6 to IPv4. For this we use the pool6 argument of jool:

jool -6 2a0a:e5c1:18f:b00::/96

Note that we cheated here. We did not only map 2a0a:e5c1:18f:b00::/120, but we did actually map the whole IPv4 range. The advantage of this is that we do not need to care which networks are used on the IPv4 island. Any IPv4 address inside the LAN segment is now reachable. If you want to reach the IP address 192.168.1.42, you can ping as 2a0a:e5c1:18f:b00::192.168.1.42. As a matter of fact, while writing this article, the sample network is up and running and you should be able to ping 2a0a:e5c1:18f:b00::192.168.1.1 from the IPv6 Internet.

More of this?

If you are interested in IPv6 or network, feel free to join us on the IPv6.chat.