I admit defeat… You know how it is: you’re searching for a solution to a technical problem, and you KNOW that someone else has had the same problem. In fact thousands of people have had the same problem. And it was fixed years ago. If I can just find that solution…
EDIT: 22 July – The project has really taken shape. Version 0.3 is now useful enough to be considered a working beta version. Building is very simple – do please try it out and let me know of any issues, good or bad.
And find it, eventually (Google, Bing et al – Thank You!) you do.
Except when you don’t. Back in this post I wrote about a specific, but key, problem in implementing an IPv6 firewall/router on a Linux box, when attached to a “normal” ISP.
What was the problem?
In a nutshell, it was as follows. My ISP gives me a full IPv6 service, with a staticically allocated (i.e. fixed) global IPv6 address. They give me a /64, so I in turn have a full /64 to play with in my private net. Enough to network every dust particle in the house. (And this is one dusty house).
As I found, not surprisingly the ISP does not let me advertise address space back to them regarding which devices in my private-but-globally-addressed network actually exist. Given that, I rather naively hoped that they would thus blindly forward anything that was addressed to my (global prefix + private part) network to me regardless, and treat my gateway device as, in effect, a sort of default route for my IPv6 prefix.
Could you give an example?
Sure. Say my ISP has given me the IPv6 prefix of 2a01:e35:8b25:7ea9:… A device inside my network then, by the magic of radvd, gets an address of, say: 2a01:e35:8b25:7ea9:1111:2222:3333:4444.
(If you need a primer on this stuff, read all about it here!)
Then assuming all the other myriad options are set up right, from that inside device I do a test ping6 of ipv6.google.com. And it fails.
As per my earlier article, it’s all down to my ISP, when they get traffic from the remote host (in fact in this case the ICMP6 echo reply from Google) destined for 2a01:e35:8b25:7ea9:1111:2222:3333:4444 rather than just “knowing” that such a global address must, by definition, be behind my connection, they go to the irritating lenghts of instead doing the whole Neighbor Solicitation dance with me.
And I find that unless I have performed the following command on my Linux gateway:
ip -6 neigh add proxy 2a01:e35:8b25:7ea9:1111:2222:3333:4444 dev eth0
the gateway device will not reply to the neighbor solicitation. And hence nothing works.
OK, does it matter much?
- Each inside device must be statically configured on the gateway.
- It is currently not possible (I know this seems implausible…) from user-space to list or show what devices you have configured in this way.
- The biggie: if you are dynamically allocating addresses in the network, you will not even KNOW what the end-point address is.
Item 3 is in large part a consequence of using radvd. But even if one used (at the cost of a lot more work) an IPv6 DHCP server, you still have to statically pre-configure the end devices addresses on it, and lose the ability to add devices on-the-fly.
So we have a real stumblin block. Sure, for test purposes I can dig out the IPv6 address which my end station has picked, and bang in the neighbor proxy command on the gateway. And it works fine.
But in terms of manageability and scalability it’s a freakin’ disaster.
Must be easy to fix, surely?
Well if it is, no one I’ve spoken to has any idea! It’s a great, glaring black-hole. IPv6 on Linux simply currently appears to have no support for automating the proxying of global/private addresses using the Neighbor Solicitation mechanism. I can only assume that it was never thought this would be a problem, and Neighbor Solicitation would only ever be used to directly connected devices.
The ability to force a neighbor proxy as shown here is pretty obviously an after-thought. The real give away is the inability to list current defined proxies…
So what we gonna do?
I intend to fix it!! I’m going to use the article linked to HERE as a working document to put together a rough and ready design for a user-space daemon to fix this. It’s going to be simple to use – that’s key.
The main elements I can think of as a start are as follows:
- Run in user-space (I hope!)
- Have a single, simple config file.
- To have no prior knowledge of devices inside the networks.
- Only prior knowledge, via static config, is the IPv6 prefix.
- If a neighbor solicitation is received for our prefix, regardless of the suffix, we respond positively.
Easy? No idea! I’m a useful enough network programmer but not at all familiar with the Linux IPv6 stack from the code perspective. But the functionality is, conceptually, not complex.
The key gotchas I forsee are:
- How we hook incoming neighbor solicitations. Period.
- Then as per (1), but now with the “I want to run in user-space” goal. 🙂
- What I do when someone points out (and they will…) that I’m going to violate several dozen RFCs by doing this.
Piece of cake. As per above link, the working design doc will be here. Very soon. All contributions welcome – and I really do mean that!