NICMx / Jool

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

doesn't support multiport device? #67

Closed techmotive closed 7 years ago

techmotive commented 11 years ago

it seems that the module doesn't support multiport device. because the pool4 address actually belong to one of the outgoing interfaces's address, and the dst ipv4 address after 6to4 translation also related to the same interface. in other words, the address of the interface which the packet goes to, determines the src address of the packet. but this nat64 implementation set the src before knowning the outgoing interface. when in multi-interface device this can cause problem.

robertoaceves commented 11 years ago

You can actually configure multiple pool4 addresses, each belonging to the network of any interface you want.

Roberto Aceves.

On Tue, Aug 20, 2013 at 10:19 PM, techmotive notifications@github.comwrote:

it seems that the module doesn't support multiport device. because the pool4 address actually belong to one of the outgoing interfaces's address, and the dst ipv4 address after 6to4 translation also related to the same interface. in other words, the address of the interface which the packet goes to, determines the src address of the packet. but this nat64 implementation set the src before knowning the outgoing interface. when in multi-interface device this can cause problem.

— Reply to this email directly or view it on GitHubhttps://github.com/NICMx/NAT64/issues/67 .

ydahhrk commented 11 years ago

Hmmm... I'm not following the train of thought :/ Here's some random data I can come up with as I read techmotive's issue:

"the pool4 address actually belong to one of the outgoing interfaces's address" Actually, the addresses of the pools are not expected to belong to the interfaces. Perhaps reviewing the simplest use case can help: https://github.com/NICMx/NAT64/wiki/Getting-Started (see below as well).

"the dst ipv4 address after 6to4 translation also related to the same interface" The dst IPv4 address after 6to4 translation is normally not related to any of the NAT64's interfaces; it's the address of the IPv4 endpoint.

"the address of the interface which the packet goes to, determines the src address of the packet." This makes sense, but again only assuming the address belongs to the interface. If a packet's destination belongs to one of the NAT64's pools, routers are expected to forward the packet to the NAT64. HOWEVER, the address belongs to the pool, not to the NAT64 machine, so Jool "steals" the packet. This is how talking both to the NAT64 machine AND the network behind it is made possible (the former by writing to its real address, and the latter by using an address from the pool).

"but this nat64 implementation set the src before knowning the outgoing interface" Yes, because the source address comes from the pool, not from the interface.

Does this solve your problem?

techmotive commented 11 years ago

Thanks for your nice answer.

HoweverI think the pool4 addresses should belong to the ipv4 address of the interfaces of the NAT64 device, right? Otherwise, say we use B as pool4 address, when the packet return form ipv4 side, the peer device will sent ARP request saying that “who has address B?", since the NAT64 device don't have address B of any of it's interface, the peer will not get the ARP reply and don't known where sent the packet should goes to.

Unless you configure a route in peer device that address B should route to the NAT64 device, the returned ipv4 packet can not go back to the NAT64 device.

So assigning the address of interfaces to pool4 can avoid this problem. Am I right?

ydahhrk commented 11 years ago

I have never met the writers of the RFC, and the RFC never states it (I think), but I'm fairly positive that the whole point of having a pool is so you don't have to use your interface's addresses (Otherwise the NAT64 would be supposed to just figure them out and don't bother asking them to you).

Using your interface's addresses is possible, but is awkward in the sense that it means the NAT64 would steal (and attempt to translate) all of its own machine's incoming traffic (because it is headed for the pool). For example, if you tried to surf the web (e.g. IPv4 Google) in the Jool machine (i. e. not from the IPv6 network), your requests would land in foreign territory all right, but you'd never get to see Google's responses, since Jool would be "stealing" them before they get its own node's browser (Because Jool is Network/Transport layers, and the browser is Application layer, which means Jool handles the packet first). Because the translation would be 4 -> 6, this would mean the packets would get dropped because the module would have no state for them.

As you have mentioned, static routing is one (and perhaps the ideal) way to avoid those ARP requests. But if you don't have access to whatever machine is supposed to forward stuff to the NAT64 node, we have found that a virtual interface can answer the ARP requests for you. Assuming your interface is named "eth0":

ifconfig eth0:1 <your-pool-address-here> up

This way, Jool's pool will match the fake interface's addresses and you will be able to retain the real one's connectivity. I'm not sure if this is inelegant or not, but I don't know of any disadvantages at the moment.

I should really add this to the documentation...


Having said that, I have the impression that I have not answered your question. You said: "when in multi-interface device this can cause problem". I do not know what you mean; can you please exemplify a problem with this behaviour?

techmotive commented 11 years ago

Assuming there's a router implementing the NAT64 on eth0, eth1,eth2, and your pool4 has addr1,addr2,addr3, what's your configuration?

1: ifconfig eth0:1 up ifconfig eth1:1 up ifconfig eth2:1 up or: 2: ifconfig eth0:1 up ifconfig eth1:1 up ifconfig eth2:1 up

or any other way? I'm not very familiar with this and not sure about which one is right... if chose number one, will there be any conflicts ? if chose number two, if one address runs out of, the other address can not be used.

techmotive commented 11 years ago

I don't know why github can't display“ <>"

1: ifconfig eth0:1 [all-of-your-pool-address-here] up ifconfig eth1:1 [all-of-your-pool-address-here] up ifconfig eth2:1 [all-of-your-pool-address-here] up or: 2: ifconfig eth0:1 [addr1] up ifconfig eth1:1 [addr2] up ifconfig eth2:1 [addr3] up

ydahhrk commented 11 years ago

"if chose number one, will there be any conflicts ?" Curious. We didn't know you could list several addresses during a single ifconfig. But as far as we can tell, the last address listed always overrides the previous ones, so number two looks more appropriate.

"if chose number two, if one address runs out of, the other address can not be used." I have to apologize here; I wasn't very familiar with the concept of 'virtual interfaces', so this is probably looking more confusing than it should. Please exclude everything I've said about Jool not using your interface's addresses, and have a look at https://github.com/NICMx/NAT64/wiki/Multi-interface-and-NAT64-pools, where lies an updated and hopefully friendlier explanation of what I've said in this thread.

Indeed, in this case you're setting up additional addresses to make room for Jool's pool. These addresses are not going to be used as backup addresses for your node if it runs out of ports. But keep in mind that you tell Jool which addresses belong to the pool and which do not when you insert the module. In the following example, only .3, .4 and .5 will be hogged up by Jool:

$ ifconfig eth0 1.1.1.1 netmask 255.255.255.0 up $ ifconfig eth0:1 1.1.1.2 netmask 255.255.255.0 up $ ifconfig eth0:2 1.1.1.3 netmask 255.255.255.0 up $ ifconfig eth0:3 1.1.1.4 netmask 255.255.255.0 up $ ifconfig eth0:4 1.1.1.5 netmask 255.255.255.0 up $ modprobe jool pool4=1.1.1.3,1.1.1.4,1.1.1.5

We think we're making a number of assumptions for what your problem is, so if you're still having trouble, I request that you provide more details on what is it you need to do (eg. network topology).

techmotive commented 11 years ago

I HAVE read the https://github.com/NICMx/NAT64/wiki/Multi-interface-and-NAT64-pools, the network topology is the same with mine.

another question: " This means that nothing will ensure that packets destined to B will use 2.2.2.2 as source address; they can very well use 1.1.1.2, so you need to consider this when you design your network."

I'm not quite sure whether "packets destined to B use 1.1.1.2" will cause problems. Could you explain this in more detail? Thanks :)

ydahhrk commented 11 years ago

I'm elaborating here: https://github.com/NICMx/NAT64/wiki/Issue-%2367-%28I-think%29

techmotive commented 11 years ago

"Using your interface's addresses is possible, but is awkward in the sense that it means the NAT64 would steal (and attempt to translate) all of its own machine's incoming traffic (because it is headed for the pool). For example, if you tried to surf the web (e.g. IPv4 Google) in the Jool machine (i. e. not from the IPv6 network), your requests would land in foreign territory all right, but you'd never get to see Google's responses, since Jool would be "stealing" them before they get its own node's browser (Because Jool is Network/Transport layers, and the browser is Application layer, which means Jool handles the packet first). "

-------I fell the same way. But I see IPV4 NAT also use it's wan's IP as NAT's address pool, why doesn't it cause problems? Can we learn form this?(another question)

techmotive commented 11 years ago

I have read https://github.com/NICMx/NAT64/wiki/Issue-%2367-%28I-think%29. The Solution (proposal) is to maps the destination address to the source address, so how about doing this inside the NAT64 to simplify user configuration? that is, before you send the packet, you look for the address that exist in both the ipv4 pool and the outgoing interface(preconfigured), use it as the source address to send the packet.

ydahhrk commented 11 years ago

Sorry for taking so long to answer. They're both good questions we failed to ask ourselves during development, and we're still analyzing their implications. Working...

ydahhrk commented 10 years ago

"-------I fell the same way. But I see IPV4 NAT also use it's wan's IP as NAT's address pool, why doesn't it cause problems?"

Thank you very much for asking this. We found the reason; it's because IPv4 NAT also masks its own packets. As the referenced issue above mentions, we now consider the current behavior a bug and will fix it as soon as we have available resources.

Still working on the other question...

ydahhrk commented 9 years ago

Update: There's a wiki page now discussing some recent thinking.

Update 2015-11-12: I'm working on this again. Going to upload new results later.

ydahhrk commented 8 years ago

It has been a really long time so the OP likely doesn't care anymore, but the project has evolved a lot and there has been accidental progress since the last time this was active.

I still don't really understand why setting the src before knowing the outgoing interface blocks multiport support (afterthought: ok, I guess it's because it might not choose the optimal address), but pool4 has an alternate operation mode now: If it is empty, Jool falls back to compute a best-suited source address on the fly, which requires "premature routing", which defines the outgoing interface. In other words, the source depends on the interface. Interface first, source address second.

It's not perfect because this operation mode can only use "upper ports" (61001-65535) for IPv4 masks, and maybe only one address per interface, but I guess it's a start? Would love some feedback on how to proceed from here.

-------I fell the same way. But I see IPV4 NAT also use it's wan's IP as NAT's address pool, why doesn't it cause problems?

For one thing, this is because it is possible to separate the NAT's ports from the applications' ports. Now that Jool 3.4's pool4 supports port ranges, it is finally possible to use the same IP address for local traffic and translating traffic.

(Yaaaaaaaaaaaay!)

Actually, the core reason is that NAT can quickly tell the difference between a packet to be forwarded and a packet to be delivered locally. Mostly because the NAT64 spec shoves a 6-second timer in the way, Jool cannot inherit this property properly without dropping RFC compliance. This is also the reason why NAT can use ephemeral ports by default, but NAT64 cannot.

(Arrrrgggggggggh)

The Solution (proposal) is to maps the destination address to the source address, so how about doing this inside the NAT64 to simplify user configuration? that is, before you send the packet, you look for the address that exist in both the ipv4 pool and the outgoing interface(preconfigured), use it as the source address to send the packet.

Hmmmmm... ok. But what if none of the addresses from the interface match a pool4 entry? Should it still use an interface address (upper ports) or should it use a pool4 address?

ydahhrk commented 7 years ago

Closing. This thread has long been abandoned and it doesn't seem like there is a problem anymore.