wireguard_addresses: - "{{ nat_map[inventory_hostname].vpn_ipv6 }}" # wireguard_endpoint: "{{ nat_map[inventory_hostname].vpn_ipv6 }}" wireguard_endpoint: "" # Don't set this # wireguard_dns: 10.0.123.123 # don't route local addresses through the wg tunnel # wireguard_preup: # - ip route add 10.0.0.0/16 via 10.0.0.1 dev eth0 proto static onlink # wireguard_postdown: # - ip route del 10.0.0.0/16 via 10.0.0.1 dev eth0 proto static onlink # Ok, I could not get the stuff below working properly. What I _wanted_ to do # was make it so that _only_ traffic that was sent from the wireguard tunnel # gets sent back to the wireguard tunnel, rather than blindly routing based # on network. In other words, I wanted policy-based-routing (PBR). # # While I got TCP to work perfectly, what seems to happen for UDP is: # - An application listens on 0.0.0.0: # - Inbound packet on wg0 is marked in conntrack and sent to 10.4.4.33: # on the wg0 iface # - Outbound packet is generated with a source IP of 10.0.29.40 on the eth0 # interface # - Restoring the mark then fails because the source/dest IPs don't match and # the PBR never happens. # # What's puzzling is that this _only_ happens for UDP. The 3-way handshake on # TCP seems to work, as well as subsequent conversation. # # If we bind on 10.4.4.33: on the wg0 iface instead, the conntrack mark # is properly restored. But binding on the wg0 iface is undesirable because that # means we wouldn't be able to access the port over LAN. # # (Copium): It's not thaaat bad that we don't have PBR. In fact, on the bright # side, game servers that STUN itself will end up STUN'ing to the VPS's IP # without PBR! # # Don't add routing tables. We manage them manually so we only send conntrack- # # marked packets from the wireguard interface back into the interface. # wireguard_table: "off" # # This is a table we'll create ourselves. We can't use the `wireguard_table` # # variable because that's used by a role, and setting it to anything other than # # `"off"` will create entries in the table that we don't want. # wireguard_manual_table: 200 # # The mark we'll set on inbound packets from the wireguard interface. Doesn't # # really matter what this is as long as it doesn't collide with another mark, # # which it shouldn't. # conntrack_mark: 101 # # Following a similar pattern to [this answer](https://serverfault.com/a/1107872). # wireguard_postup: # # Mark incoming packets on wireguard interface with a mark and use conntrack # # to create an association # - iptables -t mangle -A PREROUTING -i wg0 -m conntrack --ctstate NEW -j CONNMARK --set-mark {{ conntrack_mark }} # # Outbound packets try to use the conntrack association to restore the mark # - iptables -t mangle -A OUTPUT -j CONNMARK --restore-mark # # Create a new table to route to the wireguard server # - ip route add table {{ wireguard_manual_table }} default via 10.4.4.1 dev wg0 proto static onlink # # Outbound packets with the mark # - ip rule add fwmark {{ conntrack_mark }} table {{ wireguard_manual_table }} # # Also, allow routing on the wireguard network to the server. This makes # # debugging easier and it would be strange if this weren't added. # - ip rule add to 10.4.4.0/24 table {{ wireguard_manual_table }} # # - ip route add 10.4.4.0/24 via 10.4.4.1 dev wg0 proto static onlink # wireguard_predown: # # - ip route del 10.4.4.0/24 via 10.4.4.1 dev wg0 proto static onlink # - ip rule del to 10.4.4.0/24 table {{ wireguard_manual_table }} # - ip rule del fwmark {{ conntrack_mark }} table {{ wireguard_manual_table }} # - ip route del table {{ wireguard_manual_table }} default via 10.4.4.1 dev wg0 proto static onlink # - iptables -t mangle -D OUTPUT -j CONNMARK --restore-mark # - iptables -t mangle -D PREROUTING -i wg0 -m conntrack --ctstate NEW -j CONNMARK --set-mark {{ conntrack_mark }}