Development discussion of WireGuard
 help / color / mirror / Atom feed
* Multihomed server issue
@ 2017-07-28  0:51 Wang Jian
  2017-07-31 15:34 ` Jason A. Donenfeld
  0 siblings, 1 reply; 18+ messages in thread
From: Wang Jian @ 2017-07-28  0:51 UTC (permalink / raw)
  To: wireguard

Hi,

I have met multihome server issue with an unusual network setup.

The server is multihomed, all public addresses are configured on
dummyN interfaces,
and routes are established by bird routing daemon, via address pairs
(172.16.xx.xx/30) on public network interface.

And, the default route is via private gateway on private interface
(10.x.x.x), which actually will be NATed by dedicated NAT gateway.

(The server has two network interface, one for private network, one
for public network)

The configuration is the simplest form:  server has [Interface]
ListenPort, while client has [Peer] Endpoint but no [Interface]
ListenPort.

The problem is

1. when wg0 on both side is brought up at the same time,  ping server
from client doesn't get response; but then ping client from server
will make tunnel alive. The tunnel will keep alive any longer.

>From 'wg' command output on client, it's clear that peer Endpoint is
NAT gateway pool address, not the one specified in config file

2. After 1, down and up client wg0, the tunnel stops work; even ping
client from server doesn't help

3. After some time, ping client from server will make tunnel alive again.

====

IMHO, the reason behind that is

1. when client contacts server, the server remembers the client's
endpoint, but handshake will fail because server responses using
10.x.x.x (which then NATed). But when ping client from server, server
will use remembered client endpoint, and client can finish handshake.

Beware that I can do nothing to help server choosing the correct
public address. Server will use best route to deduce UDP source
address, in my case, 10.x.x.x or 172.16.xx.xx/30, which doesn't help
the situation.

2. when client wg0 down and up again, the server will not do handshake

3. after some time, server will do handshake, and things work again

====

The solution can be one of:

1. server can RTS (response to source), or can bind to arbitary
address for outgoing
2. improve handshake

^ permalink raw reply	[flat|nested] 18+ messages in thread

* Re: Multihomed server issue
  2017-07-28  0:51 Multihomed server issue Wang Jian
@ 2017-07-31 15:34 ` Jason A. Donenfeld
  2017-08-01  2:01   ` Wang Jian
  0 siblings, 1 reply; 18+ messages in thread
From: Jason A. Donenfeld @ 2017-07-31 15:34 UTC (permalink / raw)
  To: Wang Jian; +Cc: WireGuard mailing list

On Fri, Jul 28, 2017 at 2:51 AM, Wang Jian <larkwang@gmail.com> wrote:
> The solution can be one of:
>
> 1. server can RTS (response to source), or can bind to arbitary
> address for outgoing

The server does already respond to source.

Can you send me a TCP dump and the output of `ip route` indicating
that WireGuard is doing otherwise?

Thanks,
Jason

^ permalink raw reply	[flat|nested] 18+ messages in thread

* Re: Multihomed server issue
  2017-07-31 15:34 ` Jason A. Donenfeld
@ 2017-08-01  2:01   ` Wang Jian
  2017-08-01  3:06     ` Jason A. Donenfeld
  0 siblings, 1 reply; 18+ messages in thread
From: Wang Jian @ 2017-08-01  2:01 UTC (permalink / raw)
  To: Jason A. Donenfeld; +Cc: WireGuard mailing list

2017-07-31 23:34 GMT+08:00 Jason A. Donenfeld <Jason@zx2c4.com>:
> On Fri, Jul 28, 2017 at 2:51 AM, Wang Jian <larkwang@gmail.com> wrote:
>> The solution can be one of:
>>
>> 1. server can RTS (response to source), or can bind to arbitary
>> address for outgoing
>
> The server does already respond to source.

Sorry, I didn't make it clear. By saying RTS, I mean response to
source link, that is,
using called address and incoming link.

>
> Can you send me a TCP dump and the output of `ip route` indicating
> that WireGuard is doing otherwise?

For security reason, I will send you privately.

^ permalink raw reply	[flat|nested] 18+ messages in thread

* Re: Multihomed server issue
  2017-08-01  2:01   ` Wang Jian
@ 2017-08-01  3:06     ` Jason A. Donenfeld
  2017-08-01 11:28       ` Wang Jian
  0 siblings, 1 reply; 18+ messages in thread
From: Jason A. Donenfeld @ 2017-08-01  3:06 UTC (permalink / raw)
  To: Wang Jian; +Cc: WireGuard mailing list

On Tue, Aug 1, 2017 at 4:01 AM, Wang Jian <larkwang@gmail.com> wrote:
> 2017-07-31 23:34 GMT+08:00 Jason A. Donenfeld <Jason@zx2c4.com>:
>> On Fri, Jul 28, 2017 at 2:51 AM, Wang Jian <larkwang@gmail.com> wrote:
>>> The solution can be one of:
>>>
>>> 1. server can RTS (response to source), or can bind to arbitary
>>> address for outgoing
>>
>> The server does already respond to source.
>
> Sorry, I didn't make it clear. By saying RTS, I mean response to
> source link, that is,
> using called address and incoming link.

You're still unclear to me. What?

^ permalink raw reply	[flat|nested] 18+ messages in thread

* Re: Multihomed server issue
  2017-08-01  3:06     ` Jason A. Donenfeld
@ 2017-08-01 11:28       ` Wang Jian
  2017-08-03  3:00         ` Wang Jian
  0 siblings, 1 reply; 18+ messages in thread
From: Wang Jian @ 2017-08-01 11:28 UTC (permalink / raw)
  To: Jason A. Donenfeld; +Cc: WireGuard mailing list

2017-08-01 11:06 GMT+08:00 Jason A. Donenfeld <Jason@zx2c4.com>:
> On Tue, Aug 1, 2017 at 4:01 AM, Wang Jian <larkwang@gmail.com> wrote:
>> 2017-07-31 23:34 GMT+08:00 Jason A. Donenfeld <Jason@zx2c4.com>:
>>> On Fri, Jul 28, 2017 at 2:51 AM, Wang Jian <larkwang@gmail.com> wrote:
>>>> The solution can be one of:
>>>>
>>>> 1. server can RTS (response to source), or can bind to arbitary
>>>> address for outgoing
>>>
>>> The server does already respond to source.
>>
>> Sorry, I didn't make it clear. By saying RTS, I mean response to
>> source link, that is,
>> using called address and incoming link.
>
> You're still unclear to me. What?

Let's say server has multiple interfaces, eth0, eth1, ... ethN, with
IP0, IP1, ... IPn,
If an incoming request is to eth1, to IP1, then the server's response
packet will go out from eth1, and source is IP1.

In some cases, it can be done using policy routing, but other cases not. I know
a FreeBSD based VPN implements so called RTS.

In my case, the server looks like

eth0 = 10.1.1.2/24                    (default route, via 10.1.1.1/24)
eth1.100 = 172.16.1.2/30         (policy routing: when source address
is 111.111.1.0/24,  route via 172.16.1.1/30)
eth1.200 = 172.16.2.2/30         (policy routing: when source address
is 111.111.2.0/24,  route via 172.16.2.1/30)
dummy0 = 111.111.1.2/24
dummy1 = 111.111.2.2/24

When a wireguard client contacts 111.111.1.2, the server responses UDP packet
with source address 10.1.1.2 but not the desired 111.111.1.2, because
of default route.

I have mailed you my network setup privately. Sorry for inconvenience.

^ permalink raw reply	[flat|nested] 18+ messages in thread

* Re: Multihomed server issue
  2017-08-01 11:28       ` Wang Jian
@ 2017-08-03  3:00         ` Wang Jian
  2017-08-03 12:59           ` Jason A. Donenfeld
  0 siblings, 1 reply; 18+ messages in thread
From: Wang Jian @ 2017-08-03  3:00 UTC (permalink / raw)
  To: Jason A. Donenfeld; +Cc: WireGuard mailing list

2017-08-01 19:28 GMT+08:00 Wang Jian <larkwang@gmail.com>:
> 2017-08-01 11:06 GMT+08:00 Jason A. Donenfeld <Jason@zx2c4.com>:
>> On Tue, Aug 1, 2017 at 4:01 AM, Wang Jian <larkwang@gmail.com> wrote:
>>> 2017-07-31 23:34 GMT+08:00 Jason A. Donenfeld <Jason@zx2c4.com>:
>>>> On Fri, Jul 28, 2017 at 2:51 AM, Wang Jian <larkwang@gmail.com> wrote:
>>>>> The solution can be one of:
>>>>>
>>>>> 1. server can RTS (response to source), or can bind to arbitary
>>>>> address for outgoing
>>>>
>>>> The server does already respond to source.
>>>
>>> Sorry, I didn't make it clear. By saying RTS, I mean response to
>>> source link, that is,
>>> using called address and incoming link.
>>
>> You're still unclear to me. What?
>
> Let's say server has multiple interfaces, eth0, eth1, ... ethN, with
> IP0, IP1, ... IPn,
> If an incoming request is to eth1, to IP1, then the server's response
> packet will go out from eth1, and source is IP1.
>
> In some cases, it can be done using policy routing, but other cases not. I know
> a FreeBSD based VPN implements so called RTS.
>
> In my case, the server looks like
>
> eth0 = 10.1.1.2/24                    (default route, via 10.1.1.1/24)
> eth1.100 = 172.16.1.2/30         (policy routing: when source address
> is 111.111.1.0/24,  route via 172.16.1.1/30)
> eth1.200 = 172.16.2.2/30         (policy routing: when source address
> is 111.111.2.0/24,  route via 172.16.2.1/30)
> dummy0 = 111.111.1.2/24
> dummy1 = 111.111.2.2/24
>
> When a wireguard client contacts 111.111.1.2, the server responses UDP packet
> with source address 10.1.1.2 but not the desired 111.111.1.2, because
> of default route.
>
> I have mailed you my network setup privately. Sorry for inconvenience.

I managed to handle this issue for one public address

------
[Interface]
FwMark = 600
PostUp = ip rule add pref 20000 fwmark 600 table 600; ip route add
table 600 default via 172.16.1.1 src 111.111.1.2
------

With this workaround, for a wireguard interface, only one public address can
be used. We do need multiple public addresses for a reason: some clients
connect to one public address while other clients connect to another public
address.

We can use multple wg interfaces to address the limitation. But I do wish that
server can deduce public address which the client connects to, and use the
public address to response to the client, then the configuration will be
simple and straightforward.

^ permalink raw reply	[flat|nested] 18+ messages in thread

* Re: Multihomed server issue
  2017-08-03  3:00         ` Wang Jian
@ 2017-08-03 12:59           ` Jason A. Donenfeld
  2017-08-03 18:38             ` Wang Jian
  0 siblings, 1 reply; 18+ messages in thread
From: Jason A. Donenfeld @ 2017-08-03 12:59 UTC (permalink / raw)
  To: Wang Jian; +Cc: WireGuard mailing list

Hi Wang,

I understand your inquiry and I see what you're trying to accomplish
with your use of ip rule and fwmark. However, *WireGuard already does
this automatically*. We _do_ support reply-to-sender. We _do_
supported multihomed servers. You wrote, "But I do wish that server
can deduce public address which the client connects to, and use the
public address to response to the client, then the configuration will
be simple and straightforward." WireGuard _does_ do this.

To demonstrate that, I've added a more explicit test of this to the test suite:
https://git.zx2c4.com/WireGuard/commit/?id=bf44c07a805a5e40408059ac60dfc526196a3797

If this is not working for you, then you're either doing something
wrong, or you've uncovered a bug in either WireGuard or the kernel. In
case it's the latter, would you send me a patch for netns.sh that
demonstrated the problem in a clear way?

Thanks,
Jason

^ permalink raw reply	[flat|nested] 18+ messages in thread

* Re: Multihomed server issue
  2017-08-03 12:59           ` Jason A. Donenfeld
@ 2017-08-03 18:38             ` Wang Jian
  2017-08-10 14:29               ` Jason A. Donenfeld
  0 siblings, 1 reply; 18+ messages in thread
From: Wang Jian @ 2017-08-03 18:38 UTC (permalink / raw)
  To: Jason A. Donenfeld; +Cc: WireGuard mailing list

2017-08-03 20:59 GMT+08:00 Jason A. Donenfeld <Jason@zx2c4.com>:
> Hi Wang,
>
> I understand your inquiry and I see what you're trying to accomplish
> with your use of ip rule and fwmark. However, *WireGuard already does
> this automatically*. We _do_ support reply-to-sender. We _do_
> supported multihomed servers. You wrote, "But I do wish that server
> can deduce public address which the client connects to, and use the
> public address to response to the client, then the configuration will
> be simple and straightforward." WireGuard _does_ do this.
>
> To demonstrate that, I've added a more explicit test of this to the test suite:
> https://git.zx2c4.com/WireGuard/commit/?id=bf44c07a805a5e40408059ac60dfc526196a3797
>
> If this is not working for you, then you're either doing something
> wrong, or you've uncovered a bug in either WireGuard or the kernel. In
> case it's the latter, would you send me a patch for netns.sh that
> demonstrated the problem in a clear way?

Your test case is straightforward. And I am confident that you're right in this
kind of setup.

But there's significant difference. In your test case, the endpoint
addresses are configured
directly on attached link. In my case, the wireguard server's endpoint
address is configured on
dummy interface, not attached link.

I reproduce the problem while using tcpdump to get some clues,

1. server can receives client's packet
2. server 'wg' output shows client's endpoint addr:port correctly
3. tcpdump on client only captures outgoing request packets, no
response from server
4. tcpdump on server only captures incoming request packets, no
response (on all physical interfaces)

I was wrong. Response is not routed via default gateway, or other
interfaces. There is NO response at all.
Very sorry for misleading.

I am not familiar with test in namespace. I will look into it.
Hopefully I can come back
with a patch.

^ permalink raw reply	[flat|nested] 18+ messages in thread

* Re: Multihomed server issue
  2017-08-03 18:38             ` Wang Jian
@ 2017-08-10 14:29               ` Jason A. Donenfeld
  2017-08-10 18:43                 ` Jason A. Donenfeld
                                   ` (2 more replies)
  0 siblings, 3 replies; 18+ messages in thread
From: Jason A. Donenfeld @ 2017-08-10 14:29 UTC (permalink / raw)
  To: Wang Jian; +Cc: WireGuard mailing list, Jan De Landtsheer

Hi Wang,

Did you have any luck reproducing this with the netns.sh script?

Here's what's happening here:

1. Packet from peer P arrives from src:A dst:B
2. WireGuard records that it should contact P at src:B dst:A
3. When sending an encrypted packet to P, it asks for which interface
to use for src:B dst:A. The routing API returns interface I.
4. We ask whether interface I has an address B assigned to it. If yes,
we transmit the packet as src:B dst:A using interface I, and return.
If no, we move to step 5:
5. We ask which interface and src IP we should use for src:default
dst:A. The routing API returns interface I' (which may be the same as
I or perhaps not) and a default src address, B', for interface I'.
6. We transmit the packet as src:B' dst:A using interface I'.

In the past, this has been sufficient for handling issues with
multihomed servers, while still dealing gracefully with IP address
changes.

It seems like the problem you're facing is that B does not belong to
I, because B belongs to an unrouted dummy0 interface. The solution
would be to change the question of step 4 to instead ask if _any_
interface contains B, not just the returned interface I. While this is
essentially what's done for IPv6, I'm not certain this is the correct
behavior for IPv4. Do you know of any relevant RFCs for your use of v4
dummy interfaces and RTS routing? Or some other reference?

Please do let me know whether the above is an accurate representation
of the problem you're facing.

Jason

^ permalink raw reply	[flat|nested] 18+ messages in thread

* Re: Multihomed server issue
  2017-08-10 14:29               ` Jason A. Donenfeld
@ 2017-08-10 18:43                 ` Jason A. Donenfeld
  2017-08-10 21:17                   ` Jan De Landtsheer
  2017-08-10 22:16                 ` Baptiste Jonglez
  2017-08-12 16:08                 ` Wang Jian
  2 siblings, 1 reply; 18+ messages in thread
From: Jason A. Donenfeld @ 2017-08-10 18:43 UTC (permalink / raw)
  To: Wang Jian; +Cc: WireGuard mailing list, Jan De Landtsheer

On Thu, Aug 10, 2017 at 4:29 PM, Jason A. Donenfeld <Jason@zx2c4.com> wrote:
> It seems like the problem you're facing is that B does not belong to
> I, because B belongs to an unrouted dummy0 interface. The solution
> would be to change the question of step 4 to instead ask if _any_
> interface contains B, not just the returned interface I. While this is
> essentially what's done for IPv6, I'm not certain this is the correct
> behavior for IPv4.

This looks like http://ix.io/z3d if you want to try it and report back.

Jason

^ permalink raw reply	[flat|nested] 18+ messages in thread

* Re: Multihomed server issue
  2017-08-10 18:43                 ` Jason A. Donenfeld
@ 2017-08-10 21:17                   ` Jan De Landtsheer
  0 siblings, 0 replies; 18+ messages in thread
From: Jan De Landtsheer @ 2017-08-10 21:17 UTC (permalink / raw)
  To: Jason A. Donenfeld, Wang Jian; +Cc: WireGuard mailing list, Jan De Landtsheer

[-- Attachment #1: Type: text/plain, Size: 662 bytes --]

indeed, this looks the same


On Thu, Aug 10, 2017 at 8:43 PM Jason A. Donenfeld <Jason@zx2c4.com> wrote:

> On Thu, Aug 10, 2017 at 4:29 PM, Jason A. Donenfeld <Jason@zx2c4.com>
> wrote:
> > It seems like the problem you're facing is that B does not belong to
> > I, because B belongs to an unrouted dummy0 interface. The solution
> > would be to change the question of step 4 to instead ask if _any_
> > interface contains B, not just the returned interface I. While this is
> > essentially what's done for IPv6, I'm not certain this is the correct
> > behavior for IPv4.
>
> This looks like http://ix.io/z3d if you want to try it and report back.
>
> Jason
>

[-- Attachment #2: Type: text/html, Size: 1097 bytes --]

^ permalink raw reply	[flat|nested] 18+ messages in thread

* Re: Multihomed server issue
  2017-08-10 14:29               ` Jason A. Donenfeld
  2017-08-10 18:43                 ` Jason A. Donenfeld
@ 2017-08-10 22:16                 ` Baptiste Jonglez
  2017-08-10 23:50                   ` Jason A. Donenfeld
  2017-08-12 16:08                 ` Wang Jian
  2 siblings, 1 reply; 18+ messages in thread
From: Baptiste Jonglez @ 2017-08-10 22:16 UTC (permalink / raw)
  To: Jason A. Donenfeld; +Cc: WireGuard mailing list, Jan De Landtsheer

[-- Attachment #1: Type: text/plain, Size: 2582 bytes --]

Hi Jason,

On Thu, Aug 10, 2017 at 04:29:54PM +0200, Jason A. Donenfeld wrote:
> 1. Packet from peer P arrives from src:A dst:B
> 2. WireGuard records that it should contact P at src:B dst:A
> 3. When sending an encrypted packet to P, it asks for which interface
> to use for src:B dst:A. The routing API returns interface I.
> 4. We ask whether interface I has an address B assigned to it. If yes,
> we transmit the packet as src:B dst:A using interface I, and return.
> If no, we move to step 5:
> 5. We ask which interface and src IP we should use for src:default
> dst:A. The routing API returns interface I' (which may be the same as
> I or perhaps not) and a default src address, B', for interface I'.
> 6. We transmit the packet as src:B' dst:A using interface I'.
> 
> In the past, this has been sufficient for handling issues with
> multihomed servers, while still dealing gracefully with IP address
> changes.
> 
> It seems like the problem you're facing is that B does not belong to
> I, because B belongs to an unrouted dummy0 interface. The solution
> would be to change the question of step 4 to instead ask if _any_
> interface contains B, not just the returned interface I. While this is
> essentially what's done for IPv6, I'm not certain this is the correct
> behavior for IPv4. Do you know of any relevant RFCs for your use of v4
> dummy interfaces and RTS routing? Or some other reference?

This is essentially a difference of weak vs. strong host model, see
https://tools.ietf.org/html/rfc1122#page-61

The RFC is quite clear:

    If the datagram is sent in response to a received datagram, the source
    address for the response SHOULD be the specific-destination address of
    the request.

However, a system with a strong host model would drop the incoming packets
in the first place, still from the RFC:

    A host MAY silently discard an incoming datagram whose destination
    address does not correspond to the physical interface through which it
    is received.

    A host MAY restrict itself to sending (non-source-routed) IP datagrams
    only through the physical interface that corresponds to the IP source
    address of the datagrams.

But Linux has adopted the weak host model, see for instance the documentation
for "arp_filter" and "arp_announce" in Documentation/networking/ip-sysctl.txt.

So I think your proposed change makes sense, you should use the
destination address of the request as source address, even if this address
is not assigned to the outgoing interface.

Baptiste

[-- Attachment #2: signature.asc --]
[-- Type: application/pgp-signature, Size: 833 bytes --]

^ permalink raw reply	[flat|nested] 18+ messages in thread

* Re: Multihomed server issue
  2017-08-10 22:16                 ` Baptiste Jonglez
@ 2017-08-10 23:50                   ` Jason A. Donenfeld
  2017-08-12  1:55                     ` Jason A. Donenfeld
  0 siblings, 1 reply; 18+ messages in thread
From: Jason A. Donenfeld @ 2017-08-10 23:50 UTC (permalink / raw)
  To: Baptiste Jonglez; +Cc: WireGuard mailing list, Jan De Landtsheer

Hey Baptiste,

On Fri, Aug 11, 2017 at 12:16 AM, Baptiste Jonglez
<baptiste@bitsofnetworks.org> wrote:
> This is essentially a difference of weak vs. strong host model, see
> https://tools.ietf.org/html/rfc1122#page-61
>
> The RFC is quite clear:

Wow, thank you so much for knowing about this / finding this. Exactly
the kind of "actual knowledge" I was hoping would emerge on the
thread. Super appreciated.

> However, a system with a strong host model would drop the incoming packets
> in the first place, still from the RFC:
> But Linux has adopted the weak host model, see for instance the documentation
> for "arp_filter" and "arp_announce" in Documentation/networking/ip-sysctl.txt.

That's a useful way of distinguishing it. WireGuard's external
endpoint has always aimed to be as _weak_ as possible, always
listening on ::/0 and 0.0.0.0/0, and always accepting the most packets
in the most permissive way, because it can rely on solid
cryptographically verified authenticators to verify that the packet is
legitimate, and because it stays silent anyway in response to
illegitimate packets. For this reason, in terms of ingress, I think
following the weak model makes sense.

It's therefore useful to know that the egress decision can directly
follow from the ingress decision, according to your reasoning and that
of the RFC.

> So I think your proposed change makes sense, you should use the
> destination address of the request as source address, even if this address
> is not assigned to the outgoing interface.

Okay, I'll most likely roll with that. I will still check, however,
that the source address belongs to one of the interfaces in general.
If the source address belongs to no interfaces, it will then use the
default one from the routing table. Otherwise, the socket won't react
to changes at all, what I've been calling "overly sticky" in the test
suite and commits, and connections won't gracefully resume when
changing interfaces around. Doing it this way has the added benefit
that I can check for address interface inclusion before doing a
routing lookup, rather than after and then retrying, which is a nice
optimization.

There is one thing, though, that occurred to me. The reason it was
like this originally -- checking to see if the outgoing source address
belonged to the interface it was going out on -- was because I very
frequently change between wifi and ethernet on my laptop, and each
interface has a different IP address. When I'm on wifi, and then I
connect to ethernet, the ethernet's default route gets a lower (higher
priority) metric than the wifi, and so packets that were formerly on
wifi now go through ethernet. I wanted this same change-over to happen
with wireguard too -- where changing to ethernet would result in
ongoing wireguard packets now having the source address of the
ethernet interface. However, this wasn't happening, since wireguard
was "remembering" the previous source address of the wifi, from the
ingress. Therefore, I added the check to see if that source address
was still on the routed egress interface, and if it wasn't, resetting
it to 0 (choose the default) and trying again.

So, if I'm going to go the route of the weak model, I'll need a
different check to see when I should drop the source address to 0.
Perhaps comparing the ingress device with the routed egress device is
in fact the proper way to do it. The "remembered" source address would
only be used if the egress packet is going out of the same interface
as the ingress packet, and otherwise the default source address would
be used. This seems superior to what we have now. What do you think?

In any case, coding this will likely wait until I'm back from holiday
in a few weeks, so there's plenty of time to think carefully about it.

Jason

^ permalink raw reply	[flat|nested] 18+ messages in thread

* Re: Multihomed server issue
  2017-08-10 23:50                   ` Jason A. Donenfeld
@ 2017-08-12  1:55                     ` Jason A. Donenfeld
  0 siblings, 0 replies; 18+ messages in thread
From: Jason A. Donenfeld @ 2017-08-12  1:55 UTC (permalink / raw)
  To: Baptiste Jonglez; +Cc: WireGuard mailing list, Jan De Landtsheer

Work in progress of last email from airplane:
https://git.zx2c4.com/WireGuard/commit/?id=afca9ef9ce88e8ef026e9c9deca98600c19c502e
If you'd like to test or play with the code.

(Will refine further when I'm home.)

^ permalink raw reply	[flat|nested] 18+ messages in thread

* Re: Multihomed server issue
  2017-08-10 14:29               ` Jason A. Donenfeld
  2017-08-10 18:43                 ` Jason A. Donenfeld
  2017-08-10 22:16                 ` Baptiste Jonglez
@ 2017-08-12 16:08                 ` Wang Jian
  2017-09-07 21:28                   ` Jason A. Donenfeld
  2 siblings, 1 reply; 18+ messages in thread
From: Wang Jian @ 2017-08-12 16:08 UTC (permalink / raw)
  To: Jason A. Donenfeld; +Cc: WireGuard mailing list, Jan De Landtsheer

[-- Attachment #1: Type: text/plain, Size: 1216 bytes --]

2017-08-10 22:29 GMT+08:00 Jason A. Donenfeld <Jason@zx2c4.com>:
> Hi Wang,
>
> Did you have any luck reproducing this with the netns.sh script?

I managed to test with dummy interface but things are not as expected.
I think it's because my test case patch is not equvalent to my real setup.

I was building a more complex test case that mimics my real setup, but
got stuck on other things and got no progress by now.

It seems that you have figured out what the scenario is and how to deal
with it.

IMHO, you have several options
1. Use request's destination address as reply source address, inject
the packet, then let kernel routing code do the left work, because a
policy route is installed anyway
2. like 1, but your code lookup routing table and search best route for
reply source address
3. provide config option that ListenAddress can be specified. You just
use it/them to check against request packet's dest address, and inject
the reply packet.

(Disclaimer: I haven't looked into your code related to routing due to
time constraint, so my opinions may be totally wrong)

I understand that you prefer 0.0.0.0 for most flexible, thus option 3
is not convicing.

BTW: finished test case is attached anyway.

[-- Attachment #2: netns.dummy.patch --]
[-- Type: application/octet-stream, Size: 4053 bytes --]

diff --git a/src/tests/netns.sh b/src/tests/netns.sh
index 6a58b37..66869a6 100755
--- a/src/tests/netns.sh
+++ b/src/tests/netns.sh
@@ -325,3 +325,69 @@ n2 ping -W 1 -c 1 192.168.241.1
 ip1 link del veth1
 ip1 link del wg0
 ip2 link del wg0
+
+
+# Test multihomed server which uses dummy interfaces
+# ┌────────────────────────────────────────┐    ┌─────────────────────────────────────────────────────────┐
+# │             $ns1 namespace             │    │                     $ns2 namespace                      │
+# │                 client                 │    │                          server                         │
+# │  ┌─────┐             ┌─────┐           │    │  ┌─────┐            ┌────────┐       ┌─────┐            │
+# │  │ wg0 │─────────────│veth1│───────────┼────┼──│veth2│────────────│ dummy0 │───────│ wg0 │            │
+# │  ├─────┴──────────┐  ├─────┴──────────┐│    │  ├─────┴──────────┐ ├────────┴─────┐ ├─────┴──────────┐ │
+# │  │192.168.241.1/24│  │10.0.0.1/24     ││    │  │10.0.0.2/24     │ │172.16.0.2/32 │ │192.168.241.2/24│ │
+# │  │fd00::1/24      │  │fd00:aa::1/96   ││    │  │fd00:aa::2/96   │ │              │ │fd00::2/24      │ │
+# │  └────────────────┘  └────────────────┘│    │  └────────────────┘ └──────────────┘ └────────────────┘ │
+# └────────────────────────────────────────┘    └─────────────────────────────────────────────────────────┘
+
+ip1 link add dev wg0 type wireguard
+ip2 link add dev wg0 type wireguard
+configure_peers
+ip1 link add veth1 type veth peer name veth2
+ip1 link set veth2 netns $netns2
+n1 bash -c 'printf 0 > /proc/sys/net/ipv6/conf/veth1/accept_dad'
+n2 bash -c 'printf 0 > /proc/sys/net/ipv6/conf/veth2/accept_dad'
+n1 bash -c 'printf 1 > /proc/sys/net/ipv4/conf/veth1/promote_secondaries'
+
+# Now we show that we can successfully do reply to sender routing
+ip1 link set veth1 down
+ip2 link set veth2 down
+ip1 addr flush dev veth1
+ip2 addr flush dev veth2
+ip1 addr add 10.0.0.1/24 dev veth1
+ip1 addr add fd00:aa::1/96 dev veth1
+ip2 addr add 10.0.0.2/24 dev veth2
+ip2 addr add fd00:aa::2/96 dev veth2
+ip1 link set veth1 up
+ip2 link set veth2 up
+waitiface $netns1 veth1
+waitiface $netns2 veth2
+
+ip2 link add dev dummy0 type dummy
+ip2 addr add 172.16.0.2/32 dev dummy0
+ip1 route add 172.16.0.2/32 via 10.0.0.2
+
+ip2 rule add pref 20000 from 172.16.0.2/32 table 2000
+ip2 route add table 2000 default via 10.0.0.1 dev veth2 src 172.16.0.2
+n1 ping -W 1 -c 1 -I 10.0.0.1    172.16.0.2
+n2 ping -W 1 -c 1 -I 172.16.0.2  10.0.0.1
+
+n1 wg set wg0 peer "$pub2" endpoint 172.16.0.2:2
+n1 ping -W 1 -c 1 192.168.241.2 || true
+n1 wg
+n2 wg
+
+ip1 link del wg0
+ip2 link del wg0
+ip1 link add dev wg0 type wireguard
+ip2 link add dev wg0 type wireguard
+configure_peers
+n1 wg set wg0 peer "$pub2" endpoint 172.16.0.2:2
+n2 wg set wg0 fwmark 0x300
+n2 ip rule add pref 20000 fwmark 0x300 table 2000
+n1 ping -W 1 -c 5 192.168.241.2 || true
+n1 wg
+n2 wg
+
+ip1 link del veth1
+ip1 link del wg0
+ip2 link del wg0

^ permalink raw reply	[flat|nested] 18+ messages in thread

* Re: Multihomed server issue
  2017-08-12 16:08                 ` Wang Jian
@ 2017-09-07 21:28                   ` Jason A. Donenfeld
  2017-09-09  8:26                     ` Wang Jian
  0 siblings, 1 reply; 18+ messages in thread
From: Jason A. Donenfeld @ 2017-09-07 21:28 UTC (permalink / raw)
  To: Wang Jian; +Cc: WireGuard mailing list, Jan De Landtsheer

Hey there,

This all should be fixed and working well in the latest snapshot. Can
you test this and confirm that it behaves the way you were hoping?

Thanks,
Jason

^ permalink raw reply	[flat|nested] 18+ messages in thread

* Re: Multihomed server issue
  2017-09-07 21:28                   ` Jason A. Donenfeld
@ 2017-09-09  8:26                     ` Wang Jian
  2017-09-20 13:15                       ` Jason A. Donenfeld
  0 siblings, 1 reply; 18+ messages in thread
From: Wang Jian @ 2017-09-09  8:26 UTC (permalink / raw)
  To: Jason A. Donenfeld; +Cc: WireGuard mailing list, Jan De Landtsheer

2017-09-08 5:28 GMT+08:00 Jason A. Donenfeld <Jason@zx2c4.com>:
> Hey there,
>
> This all should be fixed and working well in the latest snapshot. Can
> you test this and confirm that it behaves the way you were hoping?
>

Hi Jason,

It works as expected now. Thanks a lot.

--
Wang Jian

^ permalink raw reply	[flat|nested] 18+ messages in thread

* Re: Multihomed server issue
  2017-09-09  8:26                     ` Wang Jian
@ 2017-09-20 13:15                       ` Jason A. Donenfeld
  0 siblings, 0 replies; 18+ messages in thread
From: Jason A. Donenfeld @ 2017-09-20 13:15 UTC (permalink / raw)
  To: WireGuard mailing list; +Cc: Jan De Landtsheer

Hey again,

It turns out that our new semantics -- of rejecting only if the src IP
doesn't belong to _any_ interface, as opposed to the specific
interface -- nicely map to Linux's PKTINFO interface for userspace. In
working with Mathias on the Go implementation, I produced the
following code snippet that shows this sticky-socket technique using
pure-userspace facilities:

https://git.zx2c4.com/WireGuard/tree/contrib/examples/sticky-sockets/sticky-sockets.c

Just FYI, if anybody is curious.

Jason

^ permalink raw reply	[flat|nested] 18+ messages in thread

end of thread, other threads:[~2017-09-20 12:48 UTC | newest]

Thread overview: 18+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2017-07-28  0:51 Multihomed server issue Wang Jian
2017-07-31 15:34 ` Jason A. Donenfeld
2017-08-01  2:01   ` Wang Jian
2017-08-01  3:06     ` Jason A. Donenfeld
2017-08-01 11:28       ` Wang Jian
2017-08-03  3:00         ` Wang Jian
2017-08-03 12:59           ` Jason A. Donenfeld
2017-08-03 18:38             ` Wang Jian
2017-08-10 14:29               ` Jason A. Donenfeld
2017-08-10 18:43                 ` Jason A. Donenfeld
2017-08-10 21:17                   ` Jan De Landtsheer
2017-08-10 22:16                 ` Baptiste Jonglez
2017-08-10 23:50                   ` Jason A. Donenfeld
2017-08-12  1:55                     ` Jason A. Donenfeld
2017-08-12 16:08                 ` Wang Jian
2017-09-07 21:28                   ` Jason A. Donenfeld
2017-09-09  8:26                     ` Wang Jian
2017-09-20 13:15                       ` Jason A. Donenfeld

This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for NNTP newsgroup(s).