NICMx / Jool

SIIT and NAT64 for Linux
GNU General Public License v2.0
325 stars 66 forks source link

Allow multiple stateful NAT64 pools with different IPv4 addresses #353

Closed telmich closed 3 years ago

telmich commented 3 years ago

Assume the following setting:

The use case is to enable "arbitrary" (fixed list of) private IPv4 islands/devices to be accessible from the IPv6 Internet.

Most of these legacy devices come in one of the above ranges. The jool router needs to have a leg (IP address) in each of the supported /24 networks, as the legacy devices (192.168.0.1, 192.168.1.1, 192.168.8.1) often don't have a default route or even play dhcp server.

So in jool we'd need a way to map the respective IPv4 "pool" to an IPv6 pool. This is rather similar to EAMT in jool_siit, with the difference of doing stateful mappings.

ydahhrk commented 3 years ago

But what's the problem with 2001:db8::192.168.0.42, 2001:db8::192.168.1.42 and 2001:db8::192.168.8.42?

telmich commented 3 years ago

Nothing wrong with that, if there is a way to ensure traffic for 2001:db8::192.168.0.0/120 is emitted from 192.168.0.42 on the IPv4 side and 2001:db8::192.168.1.0/120 is emitted by 192.168.1.42 and so on.

ydahhrk commented 3 years ago

Sorry, I still don't quite understand what's currently stopping you from implementing that.

If

then a packet headed towards destination address 2001:db8::192.168.0.42 will be routed through eth0 (because the dst will become 192.168.0.42), and a packet headed towards 2001:db8::192.168.1.42 will be routed through eth1 (because the dst will become 192.168.1.42).

What's missing?

Note that this is not the same problem as the one we discussed on Matrix. On Matrix, we discussed source 6-to-4 source addresses (ie. pool4), and in this issue we're discussing 6-to-4 destination addresses (ie. pool6).

If you meant to report the other bug, note that you have a quick workaround: Flush pool4. This will force Jool to route 6-to-4 packets after deciding destination address, and before deciding source address. This will give you the source address that you want.

The only problem is that you'll be limited by the size of the empty pool4 (ie. Jool will only use 6-to-4 source ports 61001-65535.) If I'm not mistaken, what you really want (if you really want something) is to expand the empty pool4 port range.

For example, something like this:

jool global update min-empty-pool4-port 20000
jool global update max-empty-pool4-port 65535

Is this what you want?

ydahhrk commented 3 years ago

I'll try to explain this better.

You said this on the Matrix conversation:

jool -4 -a 192.168.1.1 jool -4 -a 10.0.0.1

technically works, but it does not "work as expected" in the sense that jool does not select the translation ip based on the destination network; is this something that would work in jool 4 directly?

Let's suppose that your pool6 is 2001:db8::/96, and that Jool is connected to two IPv4 networks: 192.168.1.0/24 and 10.0.0.0/24.

IPv6 client (cafe::1) wants to talk to IPv4 server 192.168.1.2:

The choice is random. And of course, whenever Jool chooses the second option, the IPv4 server can't respond, because it doesn't know how to reach 10.0.0.1. Right?

If you operate with an empty pool4, then instead of choosing randomly from the table, Jool will use the interface address (through which the packet is being routed) as source.

Therefore, packet cafe::1 -> 2001:db8::192.168.1.2 will become 192.168.1.1 -> 192.168.1.2, and cafe::1 -> 2001:db8::10.0.0.2 will become 10.0.0.1 -> 10.0.0.2.

Isn't that what you want?

telmich commented 3 years ago

Testing on openwrt 19.07.5:

Setting up the route for the first device:

ip addr add 192.168.61.42/24 dev br-lan
root@viwib5:~# ping -c2 192.168.61.1
PING 192.168.61.1 (192.168.61.1): 56 data bytes
64 bytes from 192.168.61.1: seq=0 ttl=64 time=1.250 ms
64 bytes from 192.168.61.1: seq=1 ttl=64 time=0.660 ms

--- 192.168.61.1 ping statistics ---
2 packets transmitted, 2 packets received, 0% packet loss
round-trip min/avg/max = 0.660/0.955/1.250 ms
root@viwib5:~# 

pool6 set, pool4 empty:

root@viwib5:~# jool -6 
Prefix
2a0a:e5c1:605:b00::/96
  (Fetched 1 entries.)
root@viwib5:~# jool -4
+------------+-------+--------------------+-----------------+-------------+
|       Mark | Proto |     Max iterations |         Address |       Ports |
+------------+-------+--------------------+-----------------+-------------+
  (empty)
root@viwib5:~# 

Pinging from outside:

[2:08] bridge:~% ping -c1 2a0a:e5c1:605:b00::192.168.61.1 
PING 2a0a:e5c1:605:b00::192.168.61.1 (2a0a:e5c1:605:b00::c0a8:3d01): 56 data bytes
64 bytes from 2a0a:e5c1:605:b00::c0a8:3d01: seq=0 ttl=59 time=511.237 ms

--- 2a0a:e5c1:605:b00::192.168.61.1 ping statistics ---
1 packets transmitted, 1 packets received, 0% packet loss
round-trip min/avg/max = 511.237/511.237/511.237 ms

Works. Adding a 2nd network/ip:

root@viwib5:~# ip addr add 192.168.1.42/24 dev br-lan

And pinging 192.168.1.1:

[2:08] bridge:~% ping -c1 2a0a:e5c1:605:b00::192.168.1.1 
PING 2a0a:e5c1:605:b00::192.168.1.1 (2a0a:e5c1:605:b00::c0a8:101): 56 data bytes
64 bytes from 2a0a:e5c1:605:b00::c0a8:101: seq=0 ttl=59 time=530.497 ms

--- 2a0a:e5c1:605:b00::192.168.1.1 ping statistics ---
1 packets transmitted, 1 packets received, 0% packet loss
round-trip min/avg/max = 530.497/530.497/530.497 ms
[2:13] bridge:~% 

Also works!

This is amazing! Jool, even in the "old" openwrt version is fully capable of connecting IPv4 islands! Closing the ticket and I'll write a blog article about this!