database64128 / swgp-go

🐉 Simple WireGuard proxy with minimal overhead for WireGuard traffic.
GNU Affero General Public License v3.0
224 stars 23 forks source link

SWGP-GO on Windows error. #39

Closed sergey-protsenko closed 10 months ago

sergey-protsenko commented 10 months ago

My Wireguard tunnel cannot set up connection on Windows via SWGP, I get the following message:

WARN service/client.go:397 Failed to write swgpPacket to proxyConn {"client": "client", "listenAddress": ":20222", "clientAddress": "[::ffff:127.0.0.1]:32345", "proxyAddress": "123.121.120.1:20220", "error": "write udp [::]:56064->123.121.120.1:20220: wsasendto: A message sent on a datagram socket was larger than the internal message buffer or some other network limit, or the buffer used to receive a datagram into was smaller than the datagram itself."}

Could you please help to understand and fix the cause?

I use swgp-go-v1.4.0-windows-x86-64-v2.

Thank you.

database64128 commented 10 months ago

swgp-go disables IP fragmentation to catch and prevent misconfiguration of tunnel MTU. You need to lower your WireGuard tunnel's MTU to the "wgTunnelMTU" value printed at startup by swgp-go.

sergey-protsenko commented 10 months ago

Thank you! I will try to lower my WireGuard tunnel MTU and check.

sergey-protsenko commented 10 months ago

Unfortunately, I could not fix the problem changing MTU. Initialy, I had minimal MTU for my WireGuard tunnel - 1280.

I tried to set MTU to the "wgTunnelMTU" value printed at startup by swgp-go (1440) and get the same error. Also, I changed the mtu parameter in the swgp-go config file several times, and, after that, set the new MTU value in my WireGuard tunnel. No changes, every time I got the same messages from swgp-go.

I checked swgp-go-v1.4.0-windows-x86-64-v3.tar.zst and swgp-go-v1.4.0-windows-x86-64-v2.tar.zst.

Below, my commandline, output of swgp-go and my config file. Thank you.

swgp-go.exe -confPath config.json -logLevel debug
2023-11-01T10:58:31.703+0300 INFO service/client.go:169 Started service {"client": "client", "listenAddress": ":20222", "proxyAddress": "12.23.34.56:20220", "wgTunnelMTU": 1440}
2023-11-01T10:59:57.961+0300 DEBUG service/client.go:253 Updated client pktinfo {"client": "client", "listenAddress": ":20222", "clientAddress": "[::ffff:127.0.0.1]:32345", "clientPktinfoAddr": "127.0.0.1", "clientPktinfoIfindex": 1}
2023-11-01T10:59:57.963+0300 INFO service/client.go:325 New session {"client": "client", "listenAddress": ":20222", "clientAddress": "[::ffff:127.0.0.1]:32345", "proxyAddress": "12.23.34.56:20220"}
2023-11-01T10:59:58.083+0300 WARN service/client.go:397 Failed to write swgpPacket to proxyConn {"client": "client", "listenAddress": ":20222", "clientAddress": "[::ffff:127.0.0.1]:32345", "proxyAddress": "12.23.34.56:20220", "error": "write udp [::]:64702->12.23.34.56:20220: wsasendto: A message sent on a datagram socket was larger than the internal message buffer or some other network limit, or the buffer used to receive a datagram into was smaller than the datagram itself."}

My config.json

{
    "clients": [
        {
            "name": "client",
            "wgListen": ":20222",
            "wgFwmark": 0,
            "wgTrafficClass": 0,
            "proxyEndpoint": "12.23.34.56:20220",
            "proxyMode": "zero-overhead",
            "proxyPSK": "qqyFBQjefNq+rKXqX3dSWzsrFzVnVuUgIqQCkkqJ1lg=",
            "proxyFwmark": 0,
            "proxyTrafficClass": 0,
            "mtu": 1500,
            "batchMode": "",
            "relayBatchSize": 0,
            "mainRecvBatchSize": 0,
            "sendChannelCapacity": 0
        }
    ]
}
database64128 commented 10 months ago

Also, I changed the mtu parameter in the swgp-go config file several times

What MTU values did you try? 1492 is a common MTU for legacy residential networks that use PPPoE for authentication. Have you tried 1492 or even lower?

sergey-protsenko commented 10 months ago

Yes, I just checked the MTU value 1492 (and low) and got the same messages. I checked from two physical computers from different locations.

Also, I captured the network traffic with Wireguard on the client side and got only three UDP packets between my network interface IP and the swgp-go server IP. And, for all UDP packets data length is significantly low than specified MTU value.

swgp-go.exe -confPath config.json -logLevel debug 2023-11-01T12:12:25.198+0300 INFO service/client.go:169 Started service {"client": "client", "listenAddress": ":20222", "proxyAddress": "12.23.34.56:20220", "wgTunnelMTU": 1424} 2023-11-01T12:12:33.343+0300 DEBUG service/client.go:253 Updated client pktinfo {"client": "client", "listenAddress": ":20222", "clientAddress": "[::ffff:127.0.0.1]:32345", "clientPktinfoAddr": "127.0.0.1", "clientPktinfoIfindex": 1} 2023-11-01T12:12:33.345+0300 INFO service/client.go:325 New session {"client": "client", "listenAddress": ":20222", "clientAddress": "[::ffff:127.0.0.1]:32345", "proxyAddress": "12.23.34.56:20220"} 2023-11-01T12:13:03.740+0300 WARN service/client.go:397 Failed to write swgpPacket to proxyConn {"client": "client", "listenAddress": ":20222", "clientAddress": "[::ffff:127.0.0.1]:32345", "proxyAddress": "12.23.34.56:20220", "error": "write udp [::]:57900->12.23.34.56:20220: wsasendto: A message sent on a datagram socket was larger than the internal message buffer or some other network limit, or the buffer used to receive a datagram into was smaller than the datagram itself."}

sergey-protsenko commented 10 months ago

From time to time, I check the server-side command:

wg show

and I see that sometimes Wireguard performs a handshake. But, at the same time, on the Wireguard client side, I see only 92 bytes sent status.

database64128 commented 10 months ago

Also, I captured the network traffic with Wireguard on the client side and got only three UDP packets between my network interface IP and the swgp-go server IP.

The swgp-go client failed to send the large packet, so you won't see it if you capture traffic between your swgp-go client and server.

It'd be a lot easier if swgp-go includes the packet size in send errors. I'll get to this in a few hours. For now, it might help if you capture the traffic between your local WireGuard service and swgp-go client, and observe packet sizes.

Thank you for your patience and detailed responses. Can you share more information on your Windows peer's WireGuard setup? Specifically, is the tunnel configured to be the default gateway? If so, have you turned off the "kill-switch" and added a route to your swgp-go server?

sergey-protsenko commented 10 months ago

Regarding my Windows peer's WireGuard setup:

`[Interface] PrivateKey = 4EyUPkfsDO5RfrUrAV2bRjMlvvjYVTQJjhuI6QifdEc= ListenPort = 32345 Address = 10.30.144.100/24, fd74:130b:74b3::100/64 DNS = 1.1.1.1 MTU = 1424

[Peer] PublicKey = bUD55L75w5/Fgb1WmFeB1GLLAdazoqnPvCibaFpoL2w= PresharedKey = qqyFBQjefNq+rKXQX3dSWwqcFzVnVuUgIqQCkkqJ1lg= AllowedIPs = 0.0.0.0/1, 128.0.0.0/1, ::/1, 8000::/1 Endpoint = 127.0.0.1:20222 PersistentKeepalive = 25`

I have turned off the "kill-switch". My swgp-go server available via my default gateway which specified in the settings of the physical network adapter of my PC.

Unfortunately, I don't know how to capture traffic between my local WireGuard service and swgp-go client. I tried Wireshark and MS Network Monitor but I cannot create an appropriate filter to capture such packets. Maybe there is another approach to solve this task.

database64128 commented 10 months ago

My swgp-go server available via my default gateway which specified in the settings of the physical network adapter of my PC.

What do you mean by this? Is this equivalent to adding a separate route to your swgp-go server?

I tried Wireshark and MS Network Monitor but I cannot create an appropriate filter to capture such packets.

In Wireshark, there's the "Adapter for loopback traffic capture". Use udp port 20222 as the filter.

sergey-protsenko commented 10 months ago

I don't have a separate route to my swgp-go server.

I started Wireshark capture for the "Adapter for loopback traffic capture", set filter "udp.port == 20222" and captured packets. It looks like all the packets are similare. Thank you for the advice.

Please find my screenshot attached. Screenshot 2023-11-01_wg_capture

sergey-protsenko commented 10 months ago

I was wrong the packets have different Length. Screenshot 2023-11-01_wg_capture_001

The Wireguard windows screenshot: Screenshot 2023-11-01_wg_client_001

And, config.json from the clietn side for the screenshots above: { "clients": [ { "name": "client", "wgListen": ":20222", "wgFwmark": 0, "wgTrafficClass": 0, "proxyEndpoint": "12.23.34.56:20220", "proxyMode": "zero-overhead", "proxyPSK": "qqyFBQjefNq+rKXqX3dSWzsrFzVnVuUgIqQCkkqJ1lg=", "proxyFwmark": 0, "proxyTrafficClass": 0, "mtu": 1500, "batchMode": "", "relayBatchSize": 0, "mainRecvBatchSize": 0, "sendChannelCapacity": 0 } ] }

The maximum value of UDP payload is 1472 bytes. I can upload the capture file if you think it will helpful for understanding the problem.

sergey-protsenko commented 10 months ago

In addition to screenshots above, some information from the server side. Only three UDP packets from the client were captured on the server at the same time (I chaged server IP on the screenshot below). Screenshot 2023-11-01_wg_server_001

database64128 commented 10 months ago

I don't have a separate route to my swgp-go server.

This is the problem. When you activate your WireGuard tunnel, it becomes the default network interface for all typical traffic, including swgp-go's. Without a separate route for your swgp-go server's IP, outgoing encapsulated packets to the swgp-go server will take the default route, which now points to the WireGuard tunnel, instead of your physical network adapter.

On Linux and FreeBSD, "proxyFwmark" takes care of the problem with policy-based routing. On Windows policy-based routing is not available, but similar effect can be achieved by adding a route to the swgp-go server. It might be more convenient to just run the swgp-go client on another device.

sergey-protsenko commented 10 months ago

You're right. I added a separate route to the swgp-go server on the client side and the tunnel works. Perfect!

Thank you very much!

sergey-protsenko commented 10 months ago

One more question not on this issue. In the readme, you say about two modes: "Zero overhead" and "Paranoid". Now, I have "proxyMode": "zero-overhead" in the my config file.

If I want to check "Paranoid" mode I need to set "proxyMode": "Paranoid" on both sides of swgp-go. Is it correct?

database64128 commented 10 months ago

If I want to check "Paranoid" mode I need to set "proxyMode": "Paranoid" on both sides of swgp-go. Is it correct?

Yes.

sergey-protsenko commented 10 months ago

Thank you very much! I think we can close this issue.

database64128 commented 10 months ago

I added a separate route to the swgp-go server on the client side and the tunnel works.

You might already know this, but in case you don't, here's a tip: The PreUp and PostDown options in WireGuard can be used to add and remove the route to swgp-go server. On Windows these options are disabled by default, and can be enabled by flipping a switch in registry.

If your LAN IPv4 address (probably assigned by your router) is stable, there's another approach to this problem: bind the outgoing socket to that address. This is not currently supported by swgp-go, but your issue (and maybe some past closed ones, if I had recalled correctly) justifies the need for this feature. I'll see what I can do.

database64128 commented 10 months ago