WireGuard Archive on lore.kernel.org
 help / color / Atom feed
* On Windows: Wrong source IP address
@ 2019-09-04 13:09 Sebastiano Barrera
  2019-09-14 16:51 ` Jason A. Donenfeld
  0 siblings, 1 reply; 4+ messages in thread
From: Sebastiano Barrera @ 2019-09-04 13:09 UTC (permalink / raw)
  To: wireguard

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

Hi all,

I've been looking for a high-performance VPN solution to build a
secure tunnel for a network application we're developing, and
WireGuard has been perfect for us.

I encountered a problem with the Windows version though [1]. It looks
like a bug to me, and I have a workaround (although a dubious one),
but I'd like to have your confirmation/opinion on how to fix it
better.

The context is simple. There are 2 machines:

- A laptop running Windows 10 with a Wi-fi interface
(192.168.1.223/24) and an Ethernet interface (192.168.71.1/24);

- another computer running Linux is connected to it through an
Ethernet cable (local address 192.168.71.2/24)

I set WireGuard up on both sides as usual (public keys, allowed IPs,
etc.). From the logs on the Windows side ("Logs" tab on the GUI), it
looks like the handshake is sent, but always fails. Running tcpdump on
the Linux side, one can immediately see what the issue consists in
(59874 and 53187 are the UDP ListenPorts of the two WireGuard
instances):

$ sudo tcpdump -n -i eno1 udp port 59874 or udp port 53187
tcpdump: verbose output suppressed, use -v or -vv for full protocol decode
listening on eno1, link-type EN10MB (Ethernet), capture size 262144 bytes
14:51:36.011169 IP 192.168.71.2.53187 > 192.168.71.1.59874: UDP, length 148
14:51:36.013757 IP 192.168.1.223.59874 > 192.168.71.2.53187: UDP, length 92
14:51:41.096679 IP 192.168.71.2.53187 > 192.168.71.1.59874: UDP, length 148
14:51:41.122407 IP 192.168.1.223.59874 > 192.168.71.2.53187: UDP, length 92

As you can see, the handshake request is sent from 192.168.71.2 (Linux
computer) to 192.168.71.1 (Ethernet interface of the Windows
computer), but the response has source address 192.168.1.223, which is
the address of the *Wi-fi* interface of the Windows computer, even
though the packet has correctly come out of its Ethernet interface!

I've tried looking into the issue in the source code, and I can see
that the Windows client continuously queries the routing table to see
which is the default route, and binds its v4/v6 sockets to the
corresponding interface.  This interface's address is what ends up
wrongly as the source address of the packets, as shown in the tcpdump
output above, since the default route goes through the Wi-fi to get to
the internet. Skipping this operation seems to solve the issue
completely (see attached patch).

The question is: am I missing something? If skipping the binding of
the socket to the interface solves this issue, what is the purpose of
this step at all? I'd love to produce a real fix for this issue and
contribute it upstream, but I'd rather know your view on this issue
first.

Keep up the good work. Thanks a lot,
-Sebastiano Barrera

[1] https://github.com/WireGuard/wireguard-windows

[-- Attachment #2: disable_binding.patch --]
[-- Type: application/octet-stream, Size: 1754 bytes --]

[-- Attachment #3: Type: text/plain, Size: 148 bytes --]

_______________________________________________
WireGuard mailing list
WireGuard@lists.zx2c4.com
https://lists.zx2c4.com/mailman/listinfo/wireguard

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

* Re: On Windows: Wrong source IP address
  2019-09-04 13:09 On Windows: Wrong source IP address Sebastiano Barrera
@ 2019-09-14 16:51 ` Jason A. Donenfeld
  2019-09-14 17:11   ` Jason A. Donenfeld
  0 siblings, 1 reply; 4+ messages in thread
From: Jason A. Donenfeld @ 2019-09-14 16:51 UTC (permalink / raw)
  To: Sebastiano Barrera; +Cc: WireGuard mailing list

We do this in order to prevent routing loops. Since the endpoints
can't roam, we can't add an explicit route for it (efficiently and
easily, at least) with the 0/1,128/1 hack. So instead on each platform
we attempt to use some form of policy routing to exclude the wireguard
socket from the wireguard route. On windows, policy routing
capabilities seem somewhat limited, and IP_UNICAST_IF to the default
route seemed like it'd work good enough for most people's use cases.
It obviously totally breaks when you're not using the default route. I
wonder if WFP can be made to attach some kind of context that we can
route on late in the stack, but I haven't looked into that yet. If
you'd like to tackle this issue and find something better than
IP_UNICAST_IF with the default for policy routing, I'd be happy to
take patches.
_______________________________________________
WireGuard mailing list
WireGuard@lists.zx2c4.com
https://lists.zx2c4.com/mailman/listinfo/wireguard

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

* Re: On Windows: Wrong source IP address
  2019-09-14 16:51 ` Jason A. Donenfeld
@ 2019-09-14 17:11   ` Jason A. Donenfeld
  2019-09-16  9:53     ` Sebastiano Barrera
  0 siblings, 1 reply; 4+ messages in thread
From: Jason A. Donenfeld @ 2019-09-14 17:11 UTC (permalink / raw)
  To: Sebastiano Barrera; +Cc: WireGuard mailing list

To give more detail, a more ideal solution would be to specify the
source address / source if index using WSASendMsg, and retrieve the
incoming destination address / destination if index using WSARecvMsg,
and implement sticky socket semantics. A linux implementation in C is
here: https://git.zx2c4.com/WireGuard/tree/contrib/examples/sticky-sockets/sticky-sockets.c
and in go is here:
https://git.zx2c4.com/wireguard-go/tree/device/conn_linux.go . If you
want to provide conn_windows.go that implements sticky sockets, that
would probably solve 80% of the problem. The remaining part would be
policy routing for the case when we don't have a sender if or when
it's gone stale.
_______________________________________________
WireGuard mailing list
WireGuard@lists.zx2c4.com
https://lists.zx2c4.com/mailman/listinfo/wireguard

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

* Re: On Windows: Wrong source IP address
  2019-09-14 17:11   ` Jason A. Donenfeld
@ 2019-09-16  9:53     ` Sebastiano Barrera
  0 siblings, 0 replies; 4+ messages in thread
From: Sebastiano Barrera @ 2019-09-16  9:53 UTC (permalink / raw)
  To: Jason A. Donenfeld; +Cc: WireGuard mailing list

Hi Jason,

Thank you very much for your explanation! I'll look into it and study
the source code you linked, but I don't think I'll be able to
contribute any concrete work before the next week or so.  I'll be back
when I do!

Thanks again!
-Sebastiano

Il giorno sab 14 set 2019 alle ore 19:11 Jason A. Donenfeld
<Jason@zx2c4.com> ha scritto:
>
> To give more detail, a more ideal solution would be to specify the
> source address / source if index using WSASendMsg, and retrieve the
> incoming destination address / destination if index using WSARecvMsg,
> and implement sticky socket semantics. A linux implementation in C is
> here: https://git.zx2c4.com/WireGuard/tree/contrib/examples/sticky-sockets/sticky-sockets.c
> and in go is here:
> https://git.zx2c4.com/wireguard-go/tree/device/conn_linux.go . If you
> want to provide conn_windows.go that implements sticky sockets, that
> would probably solve 80% of the problem. The remaining part would be
> policy routing for the case when we don't have a sender if or when
> it's gone stale.
_______________________________________________
WireGuard mailing list
WireGuard@lists.zx2c4.com
https://lists.zx2c4.com/mailman/listinfo/wireguard

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

end of thread, back to index

Thread overview: 4+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2019-09-04 13:09 On Windows: Wrong source IP address Sebastiano Barrera
2019-09-14 16:51 ` Jason A. Donenfeld
2019-09-14 17:11   ` Jason A. Donenfeld
2019-09-16  9:53     ` Sebastiano Barrera

WireGuard Archive on lore.kernel.org

Archives are clonable:
	git clone --mirror https://lore.kernel.org/wireguard/0 wireguard/git/0.git

	# If you have public-inbox 1.1+ installed, you may
	# initialize and index your mirror using the following commands:
	public-inbox-init -V2 wireguard wireguard/ https://lore.kernel.org/wireguard \
		wireguard@lists.zx2c4.com
	public-inbox-index wireguard

Example config snippet for mirrors

Newsgroup available over NNTP:
	nntp://nntp.lore.kernel.org/com.zx2c4.lists.wireguard


AGPL code for this site: git clone https://public-inbox.org/public-inbox.git