Re: [RFC] Handling multiple endpoints for a single peer
Hi, > On 8 Jan 2017, at 23:49, Jason A. Donenfeldwrote: > > (send an encrypted out of band non-IP packet > directly to a peer, for things like autoconfig) could play a nice role > in this. This is highly interesting! I should undust my gcc probably. > One thing that comes to mind is how to detect when the local LAN peer > comes back online there. Should wireguard just be trying to initiate a > new handshake _always_, and eventually it will succeed and promote the > cryptokey routing table entry to "active"? Something like RetryTimeout=X comes to mind. And immediately raises the question how it is different from PersistentKeepalive? The latter one is misused to achieve exactly this sometimes. The concrete problem Samuel described is one that could be solved by scoped addressing. This may be too theoretical for the actual scenario and circumstances. Cheers, Dan ___ WireGuard mailing list WireGuard@lists.zx2c4.com https://lists.zx2c4.com/mailman/listinfo/wireguard
Re: [RFC] Handling multiple endpoints for a single peer
On Mon, Jan 9, 2017 at 9:46 AM, Ameretat Reithwrote: > Another use case would be circumventing some crazy state backed firewalls > that drop or throttle -mostly UDP- connections having high bandwidths. If > peer is being used as gateway and nameserver resolver, it can be used to > rotate server IPs too; yet another method to bypass kind of blockages. That's another neat use case indeed. Baptiste's auto RTT-sensing idea would automatically figure out which IPs the firewall has throttled. (I suspect, however, that WireGuard isn't designed long term to deal with state sponsored firewalls and such; it's fingerprintable, as discussed earlier on the mailing list. Good approaches to building "unblockable VPNs" probably include something like symmetric crypto only, so that there's no protocol or handshake, with large random nonces (XChaPoly), forming messages that are indistinguishable from random, which are then massaged into resembling valid gzip'd data, and then placed below a valid HTTP header on port 80... or something wild like this.) ___ WireGuard mailing list WireGuard@lists.zx2c4.com https://lists.zx2c4.com/mailman/listinfo/wireguard
Re: [RFC] Handling multiple endpoints for a single peer
On Mon, Jan 9, 2017 at 3:37 AM, Samuel Hollandwrote: > I think there should be a distinction between endpoint addresses > provided in explicit configuration and those discovered through roaming. > Presumably, users put those addresses in the configuration file because > they expect them to be relatively stable. So I think those endpoints > should always be remembered. > > As for addresses learned from roaming, a simple solution is some form of > aging. If the endpoint is changing because the machine is physically > moving (e.g. to a different wireless network), it's not likely that > previous address:port combinations will work again in the future, except > for a few common locations (home, work). So there's not much reason to > remember more than the last few. On the other hand, consider a > fixed-location user whose IP only changes when the router reboots every > few months. In that case, there's no chance of even the last one or two > endpoints being reused. So a time-based aging seems more appropriate. > Assuming (for illustration) you pick an endpoint every handshake, then > "this endpoint hasn't been chosen in the last 50 handshakes" means it's > okay to forget about. > > So: 1) always keep manually added endpoints, and 2) only keep a few > roaming endpoints, and drop them when they are unused for a while. I don't like the complexity of adding that kind of distinction, between explicit and learned addresses. I think in the end that will prove to be confusing. But I like the idea of keeping track of metrics and cycling out based on that. > As a separate point, I have a use case that I haven't seen discussed > yet. I have a WireGuard peer at Site A with a public IP. I have two > peers, a desktop and a laptop, at Site B, both behind NAT. Both of them > are configured with the machine at Site A as their only peer. Often I > take the laptop offsite, and then traffic between the desktop and laptop > goes through Site A. Good. However, when I have them on the same local > network, I'd like them to communicate directly (avoiding the round trip > to Site A). > > The problem is that, if I add the desktop and laptop as peers to each > other, they stop sending traffic through Site A at all. Thus, when they > are _not_ on the same network (so behind two different NATs, as opposed > to no NAT) they cannot communicate at all. > > It would be nice to get the desktop and laptop able to directly > communicate (which is what we're discussing mostly in this thread), but, > as a fallback, it would be nice to be able to say "if you can't > handshake with the peer for this internal IP, send their traffic through > the peer with the next larger enclosing subnet of allowed IPs. Then the > peer with the public IP and the allowed IPs of 0.0.0.0/0 could act as a > hub for peers behind stricter NATs. Right now the cryptokey routing is very strict. All entries must work one-to-one, and they're always enforced and active when present. What you're suggesting here is that the cryptokey routing table entries would sort of "disappear" when there isn't a current handshake. That's interesting; I'll give it some thought. One thing that comes to mind is how to detect when the local LAN peer comes back online there. Should wireguard just be trying to initiate a new handshake _always_, and eventually it will succeed and promote the cryptokey routing table entry to "active"? ___ WireGuard mailing list WireGuard@lists.zx2c4.com https://lists.zx2c4.com/mailman/listinfo/wireguard
Re: [RFC] Handling multiple endpoints for a single peer
On Mon, Jan 9, 2017 at 10:47 AM, Baptiste Jonglezwrote: > This is not what I proposed. Endpoints do not need to be ordered, and you Sorry, I read too fast evidently. That's a nice suggestion, indeed, of sending multiple handshakes and seeing which one arrives first. If the same exact handshake packet is sent to multiple IP, only the first one to arrive will actually be replied to, due to the anti-replay attack prevention rejecting the ones that arrive later. This, then, makes implementation quite simple. Wonderful. So then, as you wrote, the symmetric session would use the IP from the handshake for the duration. I'm still struggling to come up with a satisfactory solution for how to manage "learned" new IPs from the roaming, to prevent the list from getting too large. Fixed size LRU cycling perhaps? ___ WireGuard mailing list WireGuard@lists.zx2c4.com https://lists.zx2c4.com/mailman/listinfo/wireguard
Re: [RFC] Handling multiple endpoints for a single peer
On Sun, Jan 08, 2017 at 11:49:18PM +0100, Jason A. Donenfeld wrote: > But if it is in the kernel, the decision logic boils down essentially > to: there's a list of endpoints in a given order. Based on differing > metrics of success at differing points in time, the list gets > reordered, and packets are always sent to the top of the list. This is not what I proposed. Endpoints do not need to be ordered, and you do not need to keep statistics about the past. This path is precarious because you will always have to balance between being overly conservative (which means you won't react fast enough to new situations) and being overly enthusiastic (which means that you will react to the slightest insignificant change of your metric, impacting stability). What I proposed is based on happy eyeballs, see an excerpt of my first mail below: On Sun, Jan 08, 2017 at 11:41:17PM +0100, Baptiste Jonglez wrote: > ## Select new endpoint during each handshake > > This is perhaps the most clean and simple trade-off, and exploits the fact > that Wireguard regularly performs a new handshake with a peer: > > - during the handshake, select the "best" endpoint > - while the symmetric key is in use (a few minutes), keep the same endpoint > - the roaming functionality can still update the current endpoint between two > handshakes > - during the next handshake, repeat the procedure, potentially selecting a > new endpoint > > Selection of the "best" endpoint can be quite simple: send a handshake > packets to all endpoints simultaneously, and select the endpoint for which > the answer arrives the first. This would select the endpoint with the > lowest RTT at this point in time. To avoid switching endpoint too often, > the current endpoint can be given a slight advantage, similarly to happy > eyeballs: first send the handshake packet to the current endpoint, wait > e.g. 10 ms, and then send the handshake packet to all other endpoints. > This way, we switch to a new endpoint only if that would improve the RTT > by 10 ms. > > It looks quite simple, but I am sure there would be a lot of > implementation difficulties: > > - What if the remote peer always performs key exchange just before us? We > would never be able to try other endpoints. > > - What should be the behaviour of the peer when it receives several > handshake packets? Should it reply to all of them? (probably, because > of asymmetric RTT on Internet paths). How would the peer select its own > endpoint towards us? > > > Since Wireguard performs handshakes at relatively short intervals, this > method provides some amount of liveliness: if connectivity with the > current endpoint breaks (blackhole), it will be detected and corrected > within a few minutes. > > Of course, there can be optimisations for cases with obvious lack of > connectivity. For instance, if the current endpoint is an IPv6 address > and we are moving to a network with no IPv6 connectivity, trying to send > an IPv6 packet will result in an immediate error. In this case, we would > immediately initiate a new handshake and use the IPv4 endpoint. > Similarly, if sending an encrypted packet elicits an ICMP error in > response (host or port unreachable), then we can initiate a new handshake > to test other endpoints. signature.asc Description: PGP signature ___ WireGuard mailing list WireGuard@lists.zx2c4.com https://lists.zx2c4.com/mailman/listinfo/wireguard
Re: [RFC] Handling multiple endpoints for a single peer
On Sun, Jan 08, 2017 at 08:37:55PM -0600, Samuel Holland wrote: > Hello, > > On 01/08/17 16:49, Jason A. Donenfeld wrote: > >However, this doesn't shine any light on the hardest problem: how to > >update the list of addresses in a memory-bounded fashion. Right now, > >if you receive an encrypted packet, the endpoint of that peer is > >updated to the src address of that packet. With multi-endpoint, > >which endpoint is updated? Is it simply appended to an ever-growing > >list of recent endpoints? How to keep this clean and manageable? > > I think there should be a distinction between endpoint addresses > provided in explicit configuration and those discovered through roaming. > Presumably, users put those addresses in the configuration file because > they expect them to be relatively stable. So I think those endpoints > should always be remembered. I agree, it's not a hard problem. Always keep explicitely configured addresses, and keep at most X addresses discovered through roaming (where X does not need to be much more than 1, 2 or 3). > As a separate point, I have a use case that I haven't seen discussed > yet. I have a WireGuard peer at Site A with a public IP. I have two > peers, a desktop and a laptop, at Site B, both behind NAT. Both of them > are configured with the machine at Site A as their only peer. Often I > take the laptop offsite, and then traffic between the desktop and laptop > goes through Site A. Good. However, when I have them on the same local > network, I'd like them to communicate directly (avoiding the round trip > to Site A). > > The problem is that, if I add the desktop and laptop as peers to each > other, they stop sending traffic through Site A at all. Thus, when they > are _not_ on the same network (so behind two different NATs, as opposed > to no NAT) they cannot communicate at all. See the "## Local and scope-dependent addressing" point in my first email, which unfortunately Jason forgot to quote. Unless I'm mistaken, this is exactly the use-case you describe here. signature.asc Description: PGP signature ___ WireGuard mailing list WireGuard@lists.zx2c4.com https://lists.zx2c4.com/mailman/listinfo/wireguard
Re: [RFC] Handling multiple endpoints for a single peer
Hello, On 01/08/17 16:49, Jason A. Donenfeld wrote: However, this doesn't shine any light on the hardest problem: how to update the list of addresses in a memory-bounded fashion. Right now, if you receive an encrypted packet, the endpoint of that peer is updated to the src address of that packet. With multi-endpoint, which endpoint is updated? Is it simply appended to an ever-growing list of recent endpoints? How to keep this clean and manageable? I think there should be a distinction between endpoint addresses provided in explicit configuration and those discovered through roaming. Presumably, users put those addresses in the configuration file because they expect them to be relatively stable. So I think those endpoints should always be remembered. As for addresses learned from roaming, a simple solution is some form of aging. If the endpoint is changing because the machine is physically moving (e.g. to a different wireless network), it's not likely that previous address:port combinations will work again in the future, except for a few common locations (home, work). So there's not much reason to remember more than the last few. On the other hand, consider a fixed-location user whose IP only changes when the router reboots every few months. In that case, there's no chance of even the last one or two endpoints being reused. So a time-based aging seems more appropriate. Assuming (for illustration) you pick an endpoint every handshake, then "this endpoint hasn't been chosen in the last 50 handshakes" means it's okay to forget about. So: 1) always keep manually added endpoints, and 2) only keep a few roaming endpoints, and drop them when they are unused for a while. As a separate point, I have a use case that I haven't seen discussed yet. I have a WireGuard peer at Site A with a public IP. I have two peers, a desktop and a laptop, at Site B, both behind NAT. Both of them are configured with the machine at Site A as their only peer. Often I take the laptop offsite, and then traffic between the desktop and laptop goes through Site A. Good. However, when I have them on the same local network, I'd like them to communicate directly (avoiding the round trip to Site A). The problem is that, if I add the desktop and laptop as peers to each other, they stop sending traffic through Site A at all. Thus, when they are _not_ on the same network (so behind two different NATs, as opposed to no NAT) they cannot communicate at all. It would be nice to get the desktop and laptop able to directly communicate (which is what we're discussing mostly in this thread), but, as a fallback, it would be nice to be able to say "if you can't handshake with the peer for this internal IP, send their traffic through the peer with the next larger enclosing subnet of allowed IPs. Then the peer with the public IP and the allowed IPs of 0.0.0.0/0 could act as a hub for peers behind stricter NATs. Thanks, Samuel ___ WireGuard mailing list WireGuard@lists.zx2c4.com https://lists.zx2c4.com/mailman/listinfo/wireguard
Re: [RFC] Handling multiple endpoints for a single peer
Thanks for the proposal. Obviously the easiest solution is a userspace decoupled one, but this might not necessarily be the most desirable. However, it's possible the upcoming userspace event notification fd support (epoll on an fd to learn when handshakes happen) and userspace peer-message support (send an encrypted out of band non-IP packet directly to a peer, for things like autoconfig) could play a nice role in this. But if it is in the kernel, the decision logic boils down essentially to: there's a list of endpoints in a given order. Based on differing metrics of success at differing points in time, the list gets reordered, and packets are always sent to the top of the list. For example, the list could be rotated or permutated on every handshake retry. Or the various other RTT or routing metrics you mentioned earlier. However, this doesn't shine any light on the hardest problem: how to update the list of addresses in a memory-bounded fashion. Right now, if you receive an encrypted packet, the endpoint of that peer is updated to the src address of that packet. With multi-endpoint, which endpoint is updated? Is it simply appended to an ever-growing list of recent endpoints? How to keep this clean and manageable? ___ WireGuard mailing list WireGuard@lists.zx2c4.com https://lists.zx2c4.com/mailman/listinfo/wireguard