Skip to content

Instantly share code, notes, and snippets.

@Geofferey
Created October 19, 2024 22:43
Show Gist options
  • Save Geofferey/cf5b2eb486a1df62ed16b1ddaeb96326 to your computer and use it in GitHub Desktop.
Save Geofferey/cf5b2eb486a1df62ed16b1ddaeb96326 to your computer and use it in GitHub Desktop.
Wireguard Roaming.md

Certainly! Here’s how the provided iptables rules can be incorporated into the previous explanation, ensuring clarity on their context and usage within the configuration for managing WireGuard connectivity for roaming dynamic peers.


Managing WireGuard Connectivity for Roaming Dynamic Peers

Scenario Overview:

In a WireGuard setup, a static endpoint (e.g., a firewall or server) has a fixed public IP address and an internal IP address (e.g., 203.0.113.10). A dynamic peer (client) connects to this static endpoint and may roam between internal networks (like a LAN) and external networks (such as mobile or public Wi-Fi). When on the same LAN, the dynamic peer learns the static endpoint's internal IP and begins communicating with it using this address. However, once the dynamic peer leaves the LAN, it can no longer reach the static peer’s internal IP, leading to connection issues. This situation necessitates strategies to ensure the dynamic peer can consistently connect to the static endpoint regardless of its network location.

WireGuard Behavior and Challenges

WireGuard binds to all available IP addresses and interfaces, meaning it will attempt to establish connections to peers from any accessible interface/IP address. This behavior results in the following challenges:

  • Learning the Internal IP: When the dynamic peer is on the LAN, it communicates with the static peer using its public IP (203.0.113.10). Since the static peer sees an established from the dynamic peer’s internal IP it then attempts to establish a connection to the dynamic peers internal IP. Consequently the dynamic endpoint then updates it's peer endpoint information to reflect the address the connection originated from. If the dynamic peer later leaves and tries to reconnect from an external network, it attempts to use the internal IP it learned, which is now unreachable outside the LAN.

  • Automatic Endpoint Update: WireGuard's automatic endpoint update mechanism may lead to confusion for the dynamic peer. If it receives a connection from static peers internal IP, it will update the endpoint address in it's tunnel interface and ontinue trying to use this address even when it roams to an external network. Since connections can not be re-established in this manner the endpoint address never gets re-updated. Compounding the issue Wireguard does not regularly resolve the DNS hostname that was initially specified via config.

Mitigation Strategies

To address these challenges, two primary strategies can be employed:

  1. Preventing Egress to the Static Peer’s Internal IP:

    • By configuring firewall rules on either the dynamic peer or the static endpoint, you can block outgoing traffic to the static peer’s internal subnet(s) (192.168.1.0/24). This prevents the dynamic peer from ever learning this internal address, ensuring it continues using the static peer’s public IP (e.g., 203.0.113.10).

    • Implementation: The following iptables rules explicitly deny connections from known internal IPs of remote peers, ensuring that packets from these IP ranges cannot reach the WireGuard listening port:

      # Explicitly deny connections from known internal IP(s) of remote peer(s)
      iptables -D INPUT -i wlan0 -p udp --dport ${LISTEN_PORT} --source 192.168.0.0/16 -j REJECT
      iptables -I INPUT 3 -i wlan0 -p udp --dport ${LISTEN_PORT} --source 192.168.0.0/16 -j REJECT
      
      iptables -D INPUT -i wlan0 -p udp --dport ${LISTEN_PORT} --source 172.16.0.0/12 -j REJECT
      iptables -I INPUT 3 -i wlan0 -p udp --dport ${LISTEN_PORT} --source 172.16.0.0/12 -j REJECT
      
      iptables -D INPUT -i wlan0 -p udp --dport ${LISTEN_PORT} --source 10.0.0.0/8 -j REJECT
      iptables -I INPUT 3 -i wlan0 -p udp --dport ${LISTEN_PORT} --source 10.0.0.0/8 -j REJECT
    • You can also explicitly accept connections from the endpoint IP that was specified in the WireGuard configuration file:

      # Explicitly accept connection from the endpoint IP that was specified in .conf
      iptables -D INPUT -s ${ENDPOINT_IP} -p udp --dport ${LISTEN_PORT} -j ACCEPT
      iptables -I INPUT 3 -s ${ENDPOINT_IP} -p udp --dport ${LISTEN_PORT} -j ACCEPT
  2. Using NAT Redirect on the Dynamic Endpoint:

    • Implementing an iptables NAT redirect allows packets destined for the static peer’s internal IP to be transparently redirected to its public IP. This ensures that even if the dynamic peer attempts to send traffic to the internal IP, those packets are automatically forwarded to the public IP.

    • Important Note: The NAT redirect requires prior knowledge of the static peer's internal IP address.

    • Implementation: You can create an iptables rule to handle this NAT redirection. First, ensure you delete any existing rules for this operation if scripting:

      # Remove any existing OUTPUT NAT rules for the workaround
      iptables -t nat -D OUTPUT $(iptables -t nat -L OUTPUT -v --line-numbers | grep -w "wireguard: roaming LAN issue workaround" | cut -d " " -f1)
    • Then, add the new NAT rule:

      # Redirect packets destined for the static endpoint's internal IP to the public IP
      # This rule comments the purpose for clarity in future reviews
      iptables -t nat -I OUTPUT -m comment --comment "wireguard: roaming LAN issue workaround" -p udp -d ${ENDPOINT_INT_IP} --dport ${ENDPOINT_PORT} -j DNAT --to-destination ${ENDPOINT_IP}:${ENDPOINT_PORT}
    • This setup ensures that if the local peer attempts to establish a connection to the internal IP of the static endpoint, the packets will be redirected to the public IP specified in the configuration.

Benefits of the Combined Approach

  1. Consistent IP Usage: By preventing the dynamic peer from learning the internal IP, you ensure that it always attempts to connect to the static endpoint via its public IP, regardless of whether it is on the LAN or an external network. This eliminates the need for manual updates to the endpoint configuration when roaming.

  2. Seamless Roaming: With NAT redirect in place, even if the dynamic peer learns and continues to send packets to the internal IP after leaving the LAN, the iptables rule will intercept these packets and redirect them to the public IP. This seamless redirection allows the dynamic peer to maintain connectivity without interruption.

  3. Automatic Failover: The NAT redirection automatically handles cases where the dynamic peer tries to use the internal IP, ensuring that packets are sent to the correct destination. This minimizes the risk of connection failures and dramatically increases reliability.

  4. Simplified Configuration: This dual approach requires minimal manual intervention once configured, as it automates the connectivity process for dynamic peers, making it easier to manage roaming scenarios.

Example Scenario

  • While on LAN: The static peer attempts to communicate with the dynamic peer using its internal IP (192.168.1.1) while the dynamic peer attempts communication via the pubic IP of static endpoint (203.0.113.10). Due to lack of blocking rules, the dynamic peer learns this address and begins communication via the private IP (192.168.1.1).

  • When Roaming: After leaving the LAN, the dynamic peer tries to send packets to 192.168.1.1. The iptables rule catches this traffic and redirects it to 203.0.113.10, allowing for a seamless connection to the static endpoint without any manual reconfiguration or connection failures.

Conclusion

By implementing a strategy that involves both preventing egress to the static peer’s internal IP and using iptables NAT redirect, you can effectively manage the connectivity issues faced by dynamic WireGuard peers that roam between internal and external networks. This comprehensive approach ensures consistent and reliable communication between the dynamic peer and static endpoint, enhancing the overall user experience while leveraging WireGuard's capabilities. The key is recognizing that WireGuard's binding behavior leads to potential miscommunication, and by employing these strategies, you can maintain stable and functional connections across different network environments.


This revised explanation integrates the provided iptables rules within the context of managing connectivity for WireGuard peers, ensuring clarity on their application and purpose.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment