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

Wrong source IP for UDP replies #177

Open
WGH- opened this issue Jan 1, 2025 · 2 comments · May be fixed by #178
Open

Wrong source IP for UDP replies #177

WGH- opened this issue Jan 1, 2025 · 2 comments · May be fixed by #178

Comments

@WGH-
Copy link

WGH- commented Jan 1, 2025

Happy New Year! 🎄

Suppose I have a WireGuard interface configured like this:

Endpoint = [${PREFIX}:${EUI64}]:51821

The endpoint host/port pair is a phantun client. The host IP is a stable IPv6 address derived from the MAC address, and doesn't change.

When WireGuard does the handshake, we get this sequence of packets:

03:41:17.324203 IP6 ${PREFIX}:${WGCLIENT}.40677 > ${PREFIX}:${EUI64}.51821 UDP, length 148
03:41:17.414077 IP6 ${PREFIX}:${TMP}.51821 > ${PREFIX}:${WGCLIENT}.40677: UDP, length 92
03:41:17.414823 IP6 ${PREFIX}:${WGCLIENT}.40677 > ${PREFIX}:${TMP}.51821: UDP, length 32

Note that the phantun client uses a different IP address for replies. Instead of ${PREFIX}:${EUI64} it uses ${PREFIX}:${TMP}.

It doesn't immediately break WireGuard, as it's tolerant to address changes, and simply updates the endpoint address to ${PREFIX}:${TMP} and goes on.

However, phantun keeps using this TMP addresses forever.

See, the TMP is a temporary IPv6 address generated by the privacy extensions. These addresses are periodically rotated. Here is except from ip address output:

2: br0: <BROADCAST,MULTICAST,UP,LOWER_UP> mtu 1500 qdisc noqueue state UP group default qlen 1000
    inet6 ${PREFIX}:${TMP}/64 scope global temporary dynamic
       valid_lft 527568sec preferred_lft 8597sec
    inet6 ${PREFIX}:${TMP2}/64 scope global temporary deprecated dynamic
       valid_lft 441740sec preferred_lft 0sec
    inet6 ${PREFIX}:${TMP3}/64 scope global temporary deprecated dynamic
       valid_lft 355913sec preferred_lft 0sec
    inet6 ${PREFIX}:${TMP4}/64 scope global temporary deprecated dynamic
       valid_lft 270085sec preferred_lft 0sec
    inet6 ${PREFIX}:${TMP5}/64 scope global temporary deprecated dynamic
       valid_lft 184258sec preferred_lft 0sec
    inet6 ${PREFIX}:${TMP6}/64 scope global temporary deprecated dynamic
       valid_lft 98430sec preferred_lft 0sec
    inet6 ${PREFIX}:${TMP7}/64 scope global temporary deprecated dynamic
       valid_lft 12602sec preferred_lft 0sec
    inet6 ${PREFIX}:${EUI64}/64 scope global dynamic mngtmpaddr noprefixroute
       valid_lft 2591800sec preferred_lft 604600sec

The address will become invalid after a week, and the connection will cease functioning.

I think we need to remember the destination IP on which UDP packet initially arrived, and use this IP as source. This is somewhat complicated, as it needs IP_PKTINFO sockopt to retrieve it, and then a bind call to set it. See, for example, quic-go fixing the same problem.

We could let the kernel choose the source IP for every packet instead by forgoing connect and replacing it with bind+sendto, but even then it may break in some scenarios. If WireGuard connection becomes idle for a week, the peer may remember the old temporary address and never get an updated one before the old one becomes invalid.

WGH- added a commit to WGH-/phantun that referenced this issue Jan 1, 2025
This fixes an issue when phantun may choose a source IP different from
the destination IP in the incoming packet.

Closes dndx#177
@WGH- WGH- linked a pull request Jan 1, 2025 that will close this issue
WGH- added a commit to WGH-/phantun that referenced this issue Jan 1, 2025
This fixes an issue when phantun may choose a source IP different from
the destination IP in the incoming packet.

Closes dndx#177
@dndx
Copy link
Owner

dndx commented Jan 2, 2025

Can you create a NAT rule to help Phantun SNAT to the correct source address? Phantun does not have any ability to track dynamically changing IPv6 address yet nor does it understands IPv6 privacy extension.

@WGH-
Copy link
Author

WGH- commented Jan 2, 2025

Can you create a NAT rule to help Phantun SNAT to the correct source address?

Not really? If remote peer does use our temporary address then phantun should reply from the same address. I don't think it's possible to express that in netfilter. I'm pretty sure replies that originate from the wrong source would be considered a new conntrack entry.

Phantun does not have any ability to track dynamically changing IPv6 address yet nor does it understands IPv6 privacy extension.

My proposed fix (#178) is not about tracking anything. It's about replying using the same source address as remote UDP peer used as destination to contact us.

WGH- added a commit to WGH-/phantun that referenced this issue Jan 2, 2025
This fixes an issue when phantun may choose a source IP different from
the destination IP in the incoming packet.

Closes dndx#177
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging a pull request may close this issue.

2 participants