Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Feature request: Differing IPv4 pools based on clients IPv6 source address #115

Closed
toreanderson opened this issue Nov 18, 2014 · 4 comments
Milestone

Comments

@toreanderson
Copy link
Contributor

One piece of customer feedback I've gotten from running a NAT64 in a data centre environment, is that it is desired to select differing IPv4 source addresses based on the client's IPv6 source address. This is to facilitate the use of IPv4-based ACLs in front of external services on the Internet. For example, if I have a client A using 2001:db8:a::/64 and B using 2001:db8:b::/64 (and so on for client C, D, ...), A might want to tell some external IPv4-only service to allow access from IPv4 source address 192.0.2.1. However, at the same time they do not want B (or any others) to gain access to the external IPv4-only service address. So if I could express this using iptables-ish syntax, what I would like to accomplish is something like this:

ip6tables -t nat64 -j POSTROUTING -s 2001:db8:a::/64 -j SNAT --to-source 192.0.2.1
ip6tables -t nat64 -j POSTROUTING -s ::/0 -j SNAT --to-source 192.0.2.2

So customer A would have exclusive use of 192.0.2.1 while all other NAT64 users would be mapped to another address (192.0.2.2). That way, A can feel free to ask external services to allow access from 192.0.2.1, and be certain that doing so does not give third parties access as well.

I hope that explanation made sense...

I don't believe I can accomplish this with Jool, at least I could not figure out how. So there's a feature request you might want to consider, if I'm lucky. :-)

@toreanderson
Copy link
Contributor Author

I think one particularly nice way to implement this is to let IPTables do the matching part, and then communicate the selected IPv4 pool to Jool by marking packets. So in order to implement what I described in my original message, something like this would be required:

# Add 192.0.2.2 to the default IPv4 pool (0) used by customers B/C/D...
# Could also be written as: jool --pool4=0 --add 192.0.2.2/32
$ jool --pool4 --add 192.0.2.2/32

# Add customer A's dedicated IPv4 src address to a custom IPv4 pool (1)
$ jool --pool4=1 --add 192.0.2.1/32

# Use iptables to mark the packets from customer A. Jool uses the mark value to select a pool
$ ip6tables -t mangle -I PREROUTING -s 2001:db8:a::/64 -j MARK --set-mark 1

# This is completely optional as pool 0 would be the default for packets without a mark anyawy
$ ip6tables -t mangle -I PREROUTING ! -s  2001:db8:a::/64 -j MARK --set-mark 0

While matching on layer 3 addresses probably isn't too difficult to do inside Jool either, IPTables can match on a ton of different things, so by outsourcing the matching to IPTables you gain a lot of flexibility for free.

@ydahhrk
Copy link
Member

ydahhrk commented Apr 15, 2015

Say

I'm interested in not polluting the mark, because it's an all-purpose field the operator might want to use for something else.

A long time ago, somebody asked me to correlate pool4 addresses and pool6 prefixes.

As in...

"If IPv6 client writes towards prefix X, then use pool4 address x. If IPv6 client writes towards prefix Y, then use pool4 address y."

If Jool did this, would this also solve your problem?

You'd iptables/block messages from A going to one prefix, and messages from B going to the other prefix.

Currently, having multiple prefixes doesn't have much of a point as far as I can tell.

@toreanderson
Copy link
Contributor Author

Hmm. I don't like that solution much, because it causes significant operational overhead. It would mean that the two IPv6 clients must be provisioned with a different set of DNS64 servers (one with prefix X and one with prefix Y). Standard/common firewall/ACL entries (for example "allow clients to query Google Public DNS") must be duplicated (one rule for X::8.8.8.8 and one for Y::8.8.8.8), and so on.

What I'd really like to be able to do is to select the source IPv4 address/prefix/pool entry based on the clients IPv6 source address/prefix, and somehow ascertain that that IPv6 source address/prefix has exclusive usage of that particular source IPv4 address/prefix/pool.

That said, your suggestion would of course solve the problem as it is really the equivalent of setting up two independent NAT64 instances in the network. But then again, nothing is stopping me from doing that today (except for the operational overhead).

@ydahhrk
Copy link
Member

ydahhrk commented Apr 20, 2015

Related: https://tools.ietf.org/html/rfc7422

Because I'm working on adding port ranges to pool4 anyway, it looks like it will be simple to address this issue (as proposed, using the mark) in milestone 3.4.0. This way I can avoid some duplicate work, I think.

Tentatively moving to milestone 3.4.0.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Projects
None yet
Development

No branches or pull requests

2 participants