Re: [RFC] Handling multiple endpoints for a single peer

2017-01-16 Thread Dan Lüdtke
Hi,


> On 8 Jan 2017, at 23:49, Jason A. Donenfeld  wrote:
> 
> (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

2017-01-15 Thread Jason A. Donenfeld
On Mon, Jan 9, 2017 at 9:46 AM, Ameretat Reith  wrote:
> 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

2017-01-15 Thread Jason A. Donenfeld
On Mon, Jan 9, 2017 at 3:37 AM, Samuel Holland  wrote:
> 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

2017-01-15 Thread Jason A. Donenfeld
On Mon, Jan 9, 2017 at 10:47 AM, Baptiste Jonglez
 wrote:
> 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

2017-01-09 Thread Baptiste Jonglez
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

2017-01-09 Thread Baptiste Jonglez
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

2017-01-08 Thread Samuel Holland

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

2017-01-08 Thread Jason A. Donenfeld
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