First, thank you! The "ndp -s" trick does exactly what I need. (I did not need to consider ndp-reflector.) The rest of this email could be summarized as "That works so perfectly I would pay for someone to make it automatic; meanwhile the other things I asked about were in fact bad ideas and I will stop wishing for them."
> What you're actually trying to do here is respond to NDP requests as a > proxy. It's not a clean way to do it (the clean way is "upstream routes > you a subnet"), but some people are trying to do this on cheap services > that are only intended for a single host connection and that's about the > only way. > > In this case you might be able to do it with ndp -s, as the "proxied" > address is down a tunnel and not going to respond to NDP itself anyway, > so it doesn't hit the main problem for arp/ndp proxy in OpenBSD which > is that it answers on all interfaces, you can't tie it to one in > particular. > > (For some other use cases, where you're on a /64 behind an ISP router, > and have other hosts on a different ethernet interface, it looks like > https://github.com/toru-mano/nd-reflector might do the trick). What makes it unclean? (The "ndp -s" trick is simple and works perfectly; I'm trying to understand why it's architecturally bad.) The use case is: - I have a whole /64 subnet. - I cannot easily modify the gateway router on this subnet. - I want to connect a single client to this network over a tunnel that is administered by a host (not the gateway router!) on that network. - I want the client to be assigned a single [dynamic] IPv6 address on the /64 subnet. This address must be globally routable! - IPv4 is explicitly out-of-scope because addresses are hard to come by; I'm fine just using NAT for IPv4. These items describe both my VPS (where the hypervisor has allocated me an entire /64 subnet but only delivers packets to the vio0 interface when their destination addresses can be found among my NDP neighbor advertisements) and my physical network at home (where again the whole /64 is mine, but replacing the ISP-provided router is a nontrivial affair). Since iked already supports dynamic address assignments, that part is noncontroversial. What is needed for this address to be globally routable? The Internet at large already knows how to look at the top 64 bits of an address to figure out what gateway router to deliver the packet to, and if the packet somehow reaches the IKEv2 responder, iked has already set up the routes necessary to push the packet down the tunnel to its final destination. All we're missing is the step between the gateway router and the IKEv2 responder. They're on the same link. What is the proper way to for iked to announce the dynamic IPv6 address to other hosts on the local link? NDP. And it turns out that OpenBSD already has a utility in base that does NDP proxying. It seems like this should be the recommended solution for IPv6. Taking responsibility for routing the whole /64 subnet just to support a couple of IPsec tunnels seems wrong. I'm not trying to bridge networks; I just want to use an IPsec tunnel to proxy traffic from my laptop. The "ndp -s" trick seems simple and elegant, and it does exactly what we need it to and no more. I would go a step further and ask if *this* functionality could be done automatically by iked. I looked at the code in the ndp utility and it appears to work just by writing messages to a kernel routing socket. Seeing as iked *already* writes messages to a routing socket whenever a flow starts or stops, it seems like it would be easy (and architecturally sound) to add an option to tell iked to do the equivalent of calling "ndp -s $client_addr $server_mac proxy" when a client connects and "ndp -d $client_addr" when it disconnects---just treat it like any other routing step. It could be enabled with a configuration option like "ndp-proxy vio0". (The point of the interface name is to free me from the burden of entering the MAC address by hand.) The option would only be valid for connections with a "config address" option where the address is an IPv6 address, because of course that is the address which would be added to the NDP proxy list. I would gladly pay $200 to a developer who can add this functionality to iked. That's one reason I care so much about whether this is really a "clean" solution. If it isn't clean then maybe adding it isn't such a good idea. But to *me* it looks like iked is already responsible for updating routing information to match the currently-active flows, and the code in the ndp utility suggests that from the kernel's point of view, neighbor advertisements are a routing issue controlled through a routing socket. I can automate this process with a script, but I really do think this is the right way to do "road warrior" IPv6 connections. >> So what would be fantastic is if instead of >> putting "config address 2001:db8:2::/64" in the responder's iked.conf, >> I could put "config inet6 autoconf vio0" instead. Then iked would >> make sure that vio0 is using autoconf addresses and, if so, it would >> request a new address via SLAAC (preferably randomizing all 64 bits >> instead of just the bottom 32 bits like it does right now), assign >> that address to the client, configure all the routing, and then would >> somehow configure vio0 to claim ownership of that address for >> NDP neighbor solicitation purposes, but have the kernel *not* claim >> the address for routing purposes. The client config wouldn't change >> at all; it would still say "request address any". > > autoconf privacy addresses require that old addresses stay active so > that long-running connections don't die. You're asking hell of a lot > from a number of different subsystems, some of which do not have a way > to handle this, to make it all work. That's a fair point. I assumed this could be handled entirely on the client side, by having the client periodically open up new flows. but apparently IKEv2 has a state machine concept that might not be so friendly to dynamically varying the number of active routes between the initiator and the responder. So, never mind. I also see more complexity with the "autoconf eth0" idea (even after dropping the idea of temporary addresses)---if there are multiple IPv6 routers blurting advertisements on eth0's link, then there's no good way for iked to choose which of the addresses to assign to the tunnel. If the goal is for the client to join *all* of the available networks which happen to be on the Ethernet link, then this is logically a layer 2 tunnel ("show me all the Ethernet traffic") and not a layer 3 tunnel ("show me everything with this IP address"), so it doesn't make sense to bundle that with IP-level routing rules. So never mind to this, too. That said, I repeat my offer of $200 if you (or someone else with OpenBSD commit rights) can automate the process of enabling and disabling NDP proxying for responder-assigned IPv6 addresses. I am firmly convinced that this is a good idea because my VPN setup was unusable until I tried "ndp -s". > -- > Please keep replies on the mailing list. Oops, Tobias' reply included me on the To: line so I assumed I was supposed to do the same. This reply is to the misc list only. Thanks, Anthony Coulter