Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

[BUG] ListenPort = 51820 in default peer.conf disallows >1 peer through NAT loopback #334

Closed
1 task done
jberkh opened this issue May 2, 2024 · 11 comments
Closed
1 task done

Comments

@jberkh
Copy link

jberkh commented May 2, 2024

Is there an existing issue for this?

  • I have searched the existing issues

Current Behavior

When two peers on the same LAN as the server want to connect to the server via its public IP (through NAT loopback), only one is able to do so because the peers use the same port.

Removing the port for the peers allows the wg client to randomly assign a port, thus allowing > 1 connection again.

Expected Behavior

Both peers should be able to connect

Steps To Reproduce

  • Create server on network with NAT loopback and port forwarding
  • Connect peer 1 to the server via public IP
  • Connect peer 2 to the server via public IP
  • Either peer 1 gets booted, or peer 2 does not connect

Environment

- OS:Ubuntu 22.04
- How docker service was installed: apt

CPU architecture

x86-64

Docker creation

vpn:
    image: linuxserver/wireguard
    container_name: vpn
    depends_on:
      - pihole
    cap_add:
      - NET_ADMIN
      - SYS_MODULE
    environment:
      - PUID=1000
      - PGID=1000
      - LOG_CONFS=true

      - SERVERURL=vpn.domain.com
      - SERVERPORT=51820

      - INTERNAL_SUBNET=10.6.0.0
      - ALLOWEDIPS=0.0.0.0/0

      - PEERDNS=${PIHOLE_IP}
      - PEERS=peer1,peer2,peer3
    sysctls:
      - net.ipv4.conf.all.src_valid_mark=1
    networks:
      dns:
        ipv4_address: ${VPN_IP}
    dns:
      - ${PIHOLE_IP}
    ports:
      - ${SERVER_IP}:51820:51820/udp
    volumes:
      - ${NETWORKING}/vpn:/config
      - /lib/modules:/lib/modules
    restart: unless-stopped

Container logs

Uname info: Linux 8bb830f4206b 5.15.0-105-generic #115-Ubuntu SMP Mon Apr 15 09:52:04 UTC 2024 x86_64 x86_64 x86_64 GNU/Linux
**** It seems the wireguard module is already active. Skipping kernel header install and module compilation. ****
**** As the wireguard module is already active you can remove the SYS_MODULE capability from your container run/compose. ****
**** Server mode is selected ****
**** External server address is set to vpn.domain.com ****
**** External server port is set to 51820. Make sure that port is properly forwarded to port 51820 inside this container ****
**** Internal subnet is set to 10.6.0.0 ****
**** AllowedIPs for peers 0.0.0.0/0 ****
**** Peer DNS servers will be set to 192.168.51.2 ****
**** Server mode is selected ****
**** No changes to parameters. Existing configs are used. ****
[custom-init] No custom files found, skipping...
[#] ip link add wg0 type wireguard
[#] wg setconf wg0 /dev/fd/63
[#] ip -4 address add 10.6.0.1 dev wg0
[#] ip link set mtu 1420 up dev wg0
.:53
CoreDNS-1.10.1
linux/amd64, go1.20, 055b2c3
[#] ip -4 route add 10.6.0.9/32 dev wg0
[#] ip -4 route add 10.6.0.8/32 dev wg0
[#] ip -4 route add 10.6.0.7/32 dev wg0
[#] ip -4 route add 10.6.0.6/32 dev wg0
[#] ip -4 route add 10.6.0.10/32 dev wg0
[#] iptables -A FORWARD -i wg0 -j ACCEPT; iptables -A FORWARD -o wg0 -j ACCEPT; iptables -t nat -A POSTROUTING -o eth0 -j MASQUERADE
[ls.io-init] done.
Copy link

github-actions bot commented May 2, 2024

Thanks for opening your first issue here! Be sure to follow the relevant issue templates, or risk having this issue marked as invalid.

@j0nnymoe
Copy link
Member

j0nnymoe commented May 2, 2024

Could you explain your use case for this please? Because I'm not entirely sure why you'd need this.

@jberkh
Copy link
Author

jberkh commented May 2, 2024

Yes, of course. As example, two persons in a household, who both have always-on VPNs to their home network on their phones, will run into this issue every time they're at home simultaneously

@j0nnymoe
Copy link
Member

j0nnymoe commented May 2, 2024

Are you not able to set these clients to not connect when they're on their home network? You'll be causing network performance issues and an additional layer of NAT.

@jberkh
Copy link
Author

jberkh commented May 3, 2024

As far as I know, this is not possible automatically. Manual switching would be very bothersome.

Networking isn't my area of expertise, so I'm not sure if/why this would cause performance issues. I'd expect a randomly assigned port to perform equally to a predetermined port, to be honest. Moreover, random client ports is also how other wireguard implementations, like pivpn, generate peer configs: https://github.com/pivpn/pivpn/blob/master/scripts/wireguard/makeCONF.sh (158-188)

Nevertheless, if it indeed does cause performance issues, maybe a fix could be added with an optional env variable, like for instance $NO_PEER_PORT. I think people with similar use cases would rather take the decrease in performance over a largely non-functional configuration

@j0nnymoe
Copy link
Member

j0nnymoe commented May 3, 2024

The performance hit isn't due to how the wireguard configs are generated, it's due to you relying on NAT hairpin to route the traffic internally.

Any decent wireguard client can connect dependant on SSID https://github.com/zaneschepke/wgtunnel

@jberkh
Copy link
Author

jberkh commented May 3, 2024

That feature is not supported on the official wireguard clients for android, iOS, Windows, and probably also Linux. It is not unreasonable to expect a wireguard server image to work OOTB with these clients.

Regarding performance, can you confirm if I am understanding correctly? It seems to me that removing the ListenPort=51820 from the peer.conf:

  • would not negatively affect anyone not using NAT hairpin
  • would only decrease performance compared to the hypothetical situation of not using wg on the home network
  • would actually increase performance compared to the current non-functional state of using wg on the home network with NAT hairpinning

@thespad
Copy link
Member

thespad commented May 3, 2024

You can make any changes you like to the peer or server configs, or indeed to the templates that are used to generate them, to suit your requirements and we won't touch them, but at the moment we have no plans to change the default behaviour of the image. It may be something we consider in the future.

@thespad thespad closed this as not planned Won't fix, can't repro, duplicate, stale May 3, 2024
@quietsy
Copy link
Member

quietsy commented May 3, 2024

I have this exact setup and it works fine.
When you say When two peers on the same LAN, does that mean it works fine using mobile data?
The behavior of one phone causing the other to disconnect sounds like you're using the same IP/keys for both.

@jberkh
Copy link
Author

jberkh commented May 3, 2024

I see where you're coming from, but I did exclude those options already. Both devices work on the network without wg enabled, and both work from cellular with wg enabled. Also, the issue disappears immediately upon removal of the listenport in the peer configs.

The relevant lines in the NAT table of my router look as follows with the default peer ListenPort=51820 configuration:

Proto NATed Address                            Destination Address                      State
udp   192.168.1.100:51820                      123.12.123.12:51820                      ASSURED
udp   123.12.123.12:1024                       192.168.1.2:51820                        ASSURED
udp   192.168.1.103:51820                      123.12.123.12:51820                      UNREPLIED

@quietsy
Copy link
Member

quietsy commented May 3, 2024

I see, the ListenPort on peers isn't required in your case, you can remove that line from /config/templates/peer.conf as Spad suggested.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
Archived in project
Development

No branches or pull requests

4 participants