diff options
Diffstat (limited to 'roles')
| -rw-r--r-- | roles/gateway/README.md | 26 | ||||
| -rw-r--r-- | roles/gateway/templates/gateway-apply-rules.sh.j2 | 11 | ||||
| -rw-r--r-- | roles/network/meta/argument_specs.yml | 4 | ||||
| -rw-r--r-- | roles/network/templates/bridge.nmconnection.j2 | 5 | ||||
| -rw-r--r-- | roles/network/templates/eth0-connection.nmconnection.j2 | 3 | ||||
| -rw-r--r-- | roles/network/templates/wifi-connection.nmconnection.j2 | 3 | ||||
| -rw-r--r-- | roles/pihole/README.md | 27 |
7 files changed, 55 insertions, 24 deletions
diff --git a/roles/gateway/README.md b/roles/gateway/README.md index cfbe49d3..6c46cc9b 100644 --- a/roles/gateway/README.md +++ b/roles/gateway/README.md @@ -19,20 +19,22 @@ gateway_router_interface: "end0" ### IPv6 Support (Optional) -IPv6 gateway is enabled by setting both `network_ipv6_address` and `gateway_local_ipv6_subnet`: +IPv6 gateway is enabled by setting `gateway_local_ipv6_subnet` to the ULA prefix advertised by radvd: ```yaml -network_ipv6_address: "2a02:xxxx:xxxx:xxxx::254/64" # Pi's IPv6 address -gateway_local_ipv6_subnet: "2a02:xxxx:xxxx:xxxx::/64" # LAN IPv6 subnet +gateway_local_ipv6_subnet: "fd00:xxxx:xxxx:xxxx::/64" # ULA prefix (stable, router-independent) ``` -To disable IPv6 entirely, remove both variables from `host_vars`. The role will: -- Omit `accept_ra` sysctl (no IPv6 interface key written) -- Skip IPv6 iptables masquerade rules (`gateway_local_ipv6_subnet` defaults to `""`) -- Leave `net.ipv6.conf.all.forwarding=0` +When set, this role: +- Enables `net.ipv6.conf.all.forwarding=1` and `accept_ra=2` on `gateway_router_interface` +- Deploys radvd advertising the ULA prefix with `AdvDefaultPreference high` — Pi wins as IPv6 default router +- Adds ip6tables MASQUERADE/FORWARD rules matching by interface (not subnet) so all source addresses are handled -**Note:** `accept_ra` is set per-interface (`gateway_router_interface`) only when IPv6 is enabled. -This prevents rogue RA acceptance on WireGuard and LAN interfaces. +**Prerequisite:** Disable the router's RA (FritzBox: Home Network > IPv6 > Router advertisement > ❌) after +setting `network_ipv6_gateway` in `host_vars` so Pi keeps its static IPv6 default route to the router. +See `roles/pihole/README.md` for the full two-step setup. + +To disable IPv6, leave `gateway_local_ipv6_subnet: ""` (default). The role skips all ip6tables rules and disables radvd. ## Network Architecture @@ -63,9 +65,9 @@ Client Devices (192.168.1.0/24) **Direct Mode Characteristics:** -- All traffic NAT'd through router interface (`end0`) -- Direct IPv4/IPv6 routing to ISP -- Standard internet routing +- IPv4 traffic NAT'd through router interface (`end0`) +- IPv6 forwarded without NAT (globally routable addresses, native routing) +- Standard internet routing via ISP ## Requirements diff --git a/roles/gateway/templates/gateway-apply-rules.sh.j2 b/roles/gateway/templates/gateway-apply-rules.sh.j2 index 0ce9f740..daddb180 100644 --- a/roles/gateway/templates/gateway-apply-rules.sh.j2 +++ b/roles/gateway/templates/gateway-apply-rules.sh.j2 @@ -27,8 +27,8 @@ clear_rules() { iptables -D OUTPUT -o "$GATEWAY_INTERFACE" -j ACCEPT 2>/dev/null || true if [ -n "$GATEWAY_SUBNET_V6" ]; then ip6tables -F FORWARD 2>/dev/null || true - ip6tables -t nat -D POSTROUTING -s "$GATEWAY_SUBNET_V6" -o wg+ -j MASQUERADE 2>/dev/null || true - ip6tables -t nat -D POSTROUTING -s "$GATEWAY_SUBNET_V6" -o "$GATEWAY_INTERFACE" -j MASQUERADE 2>/dev/null || true + ip6tables -t nat -D POSTROUTING -o wg+ -j MASQUERADE 2>/dev/null || true + ip6tables -t nat -D POSTROUTING -o "$GATEWAY_INTERFACE" -j MASQUERADE 2>/dev/null || true ip6tables -D OUTPUT -o wg+ -j ACCEPT 2>/dev/null || true ip6tables -D OUTPUT -o "$GATEWAY_INTERFACE" -j ACCEPT 2>/dev/null || true fi @@ -45,7 +45,7 @@ apply_vpn_mode() { ip6tables -t nat -A POSTROUTING -o wg+ -j MASQUERADE ip6tables -A OUTPUT -o wg+ -j ACCEPT ip6tables -A FORWARD -i "$GATEWAY_INTERFACE" -o wg+ -j ACCEPT - ip6tables -A FORWARD -m conntrack --ctstate RELATED,ESTABLISHED -j ACCEPT + ip6tables -A FORWARD -i wg+ -o "$GATEWAY_INTERFACE" -m conntrack --ctstate RELATED,ESTABLISHED -j ACCEPT fi log_message "VPN mode rules applied - traffic routed through VPN" } @@ -57,10 +57,9 @@ apply_direct_rules() { iptables -A FORWARD -s "$GATEWAY_SUBNET_V4" -o "$GATEWAY_INTERFACE" -j ACCEPT iptables -A FORWARD -m conntrack --ctstate RELATED,ESTABLISHED -j ACCEPT if [ -n "$GATEWAY_SUBNET_V6" ]; then - # No MASQUERADE for IPv6: LAN devices have public SLAAC addresses, native routing applies + ip6tables -t nat -A POSTROUTING -o "$GATEWAY_INTERFACE" -j MASQUERADE ip6tables -A OUTPUT -o "$GATEWAY_INTERFACE" -j ACCEPT - ip6tables -A FORWARD -i "$GATEWAY_INTERFACE" -o "$GATEWAY_INTERFACE" -j ACCEPT - ip6tables -A FORWARD -m conntrack --ctstate RELATED,ESTABLISHED -j ACCEPT + ip6tables -A FORWARD -i "$GATEWAY_INTERFACE" -o "$GATEWAY_INTERFACE" -m conntrack --ctstate RELATED,ESTABLISHED -j ACCEPT fi log_message "Direct mode rules applied - normal routing active" } diff --git a/roles/network/meta/argument_specs.yml b/roles/network/meta/argument_specs.yml index 5f74b45c..c501d8bb 100644 --- a/roles/network/meta/argument_specs.yml +++ b/roles/network/meta/argument_specs.yml @@ -21,6 +21,10 @@ argument_specs: network_ipv4_dns: type: "str" description: "The network IP(4) gateway to configure when provided" + network_ipv6_gateway: + type: "str" + description: "Static IPv6 default route via router link-local (e.g. fe80::1/end0) — set when router RA is disabled" + required: false network_bridge_interface: type: "str" description: "Physical NIC to enslave as vmbr0 bridge port" diff --git a/roles/network/templates/bridge.nmconnection.j2 b/roles/network/templates/bridge.nmconnection.j2 index 0088a1a1..47f723d8 100644 --- a/roles/network/templates/bridge.nmconnection.j2 +++ b/roles/network/templates/bridge.nmconnection.j2 @@ -17,4 +17,7 @@ dns={{ network_ipv4_dns }} [ipv6] addr-gen-mode=default -method=disabled +method=auto +{% if network_ipv6_gateway is defined %} +routes=::/0,{{ network_ipv6_gateway }},100 +{% endif %} diff --git a/roles/network/templates/eth0-connection.nmconnection.j2 b/roles/network/templates/eth0-connection.nmconnection.j2 index b1bc87a8..d6d2ea86 100644 --- a/roles/network/templates/eth0-connection.nmconnection.j2 +++ b/roles/network/templates/eth0-connection.nmconnection.j2 @@ -32,6 +32,9 @@ addr-gen-mode=default method=disabled {% else %} method=auto +{% if network_ipv6_gateway is defined %} +routes=::/0,{{ network_ipv6_gateway }},100 +{% endif %} {% endif %} [proxy] diff --git a/roles/network/templates/wifi-connection.nmconnection.j2 b/roles/network/templates/wifi-connection.nmconnection.j2 index 3d7667c8..5b4ab185 100644 --- a/roles/network/templates/wifi-connection.nmconnection.j2 +++ b/roles/network/templates/wifi-connection.nmconnection.j2 @@ -28,5 +28,8 @@ method=auto [ipv6] addr-gen-mode=default method=auto +{% if network_ipv6_gateway is defined %} +routes=::/0,{{ network_ipv6_gateway }},100 +{% endif %} [proxy] diff --git a/roles/pihole/README.md b/roles/pihole/README.md index c690dffb..e7e0bb20 100644 --- a/roles/pihole/README.md +++ b/roles/pihole/README.md @@ -47,11 +47,10 @@ This role configure the [pihole](https://github.com/pi-hole/pi-hole) DNS Sinkhol #### With IPv6 Support -> **Note:** IPv6 support is currently disabled due to ISP compatibility issues. The steps below are kept -> for future reference. IPv6 on the network template defaults to `method=disabled`. -> To enable: set `method=auto` in `roles/network/templates/eth0-connection.nmconnection.j2` and follow -> the steps below to obtain a stable ULA address via SLAAC. -> Use the `mngtmpaddr` address from `ip address | grep "inet6 fd"` as `{{ pihole_ipv6 }}` — not the `temporary` one. +Setup is a two-step process: first enable FritzBox RA to get the Pi's stable ULA address, +then disable FritzBox RA so Pi becomes the sole IPv6 default router. + +**Step 1 — Enable FritzBox RA temporarily to get Pi's ULA address:** - Internet > Account Information > - IPv6 > IPv6 Support > ✅ @@ -70,4 +69,22 @@ This role configure the [pihole](https://github.com/pi-hole/pi-hole) DNS Sinkhol - DHCPv6 Server in the home network > - Disable DHCPv6 server in the FRITZ!Box for the home network > ✅ - There are no other DHCPv6 servers in the home network. > ✅ + - Internet > Account Information > Internet DNS Server > DNSv6 Server > Use Other DNSv6 Servers > {{ pihole_ipv6 }} + +On the Pi, get the ULA address and the FritzBox link-local default route: +```bash +ip address | grep "inet6 fd" # use the mngtmpaddr address as pihole_ipv6 +ip -6 route show default | grep ra # use the nexthop as network_ipv6_gateway in rpi5 host_vars +``` + +Set `network_ipv6_gateway` in `host_vars/rpi5.local.yml` and run the playbook to deploy the static IPv6 route on Pi. + +**Step 2 — Disable FritzBox RA so Pi becomes sole IPv6 default router:** + +- Home Network > Network > Network Settings > Change Advanced Network Settings > IPv6 > + - Router advertisement enable in the LAN > ❌ + +NOTE: Pi's radvd (deployed by the `gateway` role) takes over sending RAs with `AdvDefaultPreference high`. +All LAN devices use Pi as their IPv6 default router → traffic routes VPN or direct mode. +Pi keeps IPv6 connectivity via the static route to FritzBox set in Step 1. |
