<feed xmlns='http://www.w3.org/2005/Atom'>
<title>ansible-distro-configure.git/roles/gateway/templates/gateway-apply-rules.sh.j2, branch main</title>
<subtitle>Ansible Roles to configure different (linux) distros
</subtitle>
<link rel='alternate' type='text/html' href='http://git.a14m.dev/ansible-distro-configure.git/'/>
<entry>
<title>Disable ipv6 completely and remove related code</title>
<updated>2026-07-22T22:42:43+00:00</updated>
<author>
<name>Ahmed Abdelhalim</name>
<email>pm@a14m.dev</email>
</author>
<published>2026-07-22T22:42:43+00:00</published>
<link rel='alternate' type='text/html' href='http://git.a14m.dev/ansible-distro-configure.git/commit/?id=ff4eb129eea3f3743f82e5f1f7858d43625dba3d'/>
<id>ff4eb129eea3f3743f82e5f1f7858d43625dba3d</id>
<content type='text'>
Co-Authored-By: Claude.ai
</content>
<content type='xhtml'>
<div xmlns='http://www.w3.org/1999/xhtml'>
<pre>
Co-Authored-By: Claude.ai
</pre>
</div>
</content>
</entry>
<entry>
<title>Fix IPv6 first-request failure caused by ICMPv6 Redirects</title>
<updated>2026-07-09T20:57:11+00:00</updated>
<author>
<name>Ahmed Abdelhalim</name>
<email>pm@a14m.dev</email>
</author>
<published>2026-07-09T20:57:11+00:00</published>
<link rel='alternate' type='text/html' href='http://git.a14m.dev/ansible-distro-configure.git/commit/?id=1cbb9df950175e698e1edc87953e8f4bfb22b88a'/>
<id>1cbb9df950175e698e1edc87953e8f4bfb22b88a</id>
<content type='text'>
Root cause: Pi, the ISP router (FritzBox), and LAN clients share the same
L2 segment. When Pi forwards a client's IPv6 packet to an external GUA
destination, the Linux kernel detects that the ISP router is a "better"
next-hop on the same link and sends an ICMPv6 Redirect (type 137) to the
client. The client obeys the redirect and sends its first SYN to the ISP
router directly — Pi never forwards the original packet. The ISP router
applies per-device content filtering to the unmasqueraded client GUA and
issues a RST. This produced the symptom of the first IPv6 request failing
with "Connection reset by peer" every ~30-60 seconds (matching the FritzBox
RA interval, after which clients re-resolve their default gateway).

Diagnosis method: tcpdump with MAC addresses (-e flag) on Pi's end0 caught
the ICMPv6 Redirect being sent immediately after the first SYN arrived.
Inserting a DROP rule for icmpv6-type redirect at position 1 in ip6tables
OUTPUT confirmed the fix — 0 failures across extended testing.

Fix:
- Drop ICMPv6 Redirect (type 137) in ip6tables OUTPUT as the first rule,
  before the ACCEPT rule, in both direct and VPN modes
- Flush ip6tables OUTPUT chain on clear_rules() instead of per-rule -D
  deletion, which was fragile and left stale rules accumulating across
  mode switches (previously caused duplicate/conflicting OUTPUT rules)
- Flush ip6tables nat POSTROUTING table instead of per-rule -D deletion
  for the same reason

Also documents the ICMPv6 Redirect issue and IPv6 masquerade rationale
in roles/gateway/README.md for future reference.

Co-Authored-By: Claude Sonnet 4.6 &lt;noreply@anthropic.com&gt;
</content>
<content type='xhtml'>
<div xmlns='http://www.w3.org/1999/xhtml'>
<pre>
Root cause: Pi, the ISP router (FritzBox), and LAN clients share the same
L2 segment. When Pi forwards a client's IPv6 packet to an external GUA
destination, the Linux kernel detects that the ISP router is a "better"
next-hop on the same link and sends an ICMPv6 Redirect (type 137) to the
client. The client obeys the redirect and sends its first SYN to the ISP
router directly — Pi never forwards the original packet. The ISP router
applies per-device content filtering to the unmasqueraded client GUA and
issues a RST. This produced the symptom of the first IPv6 request failing
with "Connection reset by peer" every ~30-60 seconds (matching the FritzBox
RA interval, after which clients re-resolve their default gateway).

Diagnosis method: tcpdump with MAC addresses (-e flag) on Pi's end0 caught
the ICMPv6 Redirect being sent immediately after the first SYN arrived.
Inserting a DROP rule for icmpv6-type redirect at position 1 in ip6tables
OUTPUT confirmed the fix — 0 failures across extended testing.

Fix:
- Drop ICMPv6 Redirect (type 137) in ip6tables OUTPUT as the first rule,
  before the ACCEPT rule, in both direct and VPN modes
- Flush ip6tables OUTPUT chain on clear_rules() instead of per-rule -D
  deletion, which was fragile and left stale rules accumulating across
  mode switches (previously caused duplicate/conflicting OUTPUT rules)
- Flush ip6tables nat POSTROUTING table instead of per-rule -D deletion
  for the same reason

Also documents the ICMPv6 Redirect issue and IPv6 masquerade rationale
in roles/gateway/README.md for future reference.

Co-Authored-By: Claude Sonnet 4.6 &lt;noreply@anthropic.com&gt;
</pre>
</div>
</content>
</entry>
<entry>
<title>Fix IPv6 direct mode routing for LAN clients</title>
<updated>2026-07-09T13:38:15+00:00</updated>
<author>
<name>Ahmed Abdelhalim</name>
<email>pm@a14m.dev</email>
</author>
<published>2026-07-09T13:38:15+00:00</published>
<link rel='alternate' type='text/html' href='http://git.a14m.dev/ansible-distro-configure.git/commit/?id=d295dd0edcd61e094b7bd7ffe8ca3187d0a6da00'/>
<id>d295dd0edcd61e094b7bd7ffe8ca3187d0a6da00</id>
<content type='text'>
- Remove static network_ipv6_gateway from LAN hosts so they pick up
  Pi's radvd RA (pref high) instead of FritzBox (pref low)
- Add missing ip6tables FORWARD ACCEPT rule for new connections in
  direct mode (only ESTABLISHED was present, blocking new flows)
- Flush ip6tables nat POSTROUTING table on clear instead of fragile
  per-rule -D deletion to prevent stale rule accumulation
</content>
<content type='xhtml'>
<div xmlns='http://www.w3.org/1999/xhtml'>
<pre>
- Remove static network_ipv6_gateway from LAN hosts so they pick up
  Pi's radvd RA (pref high) instead of FritzBox (pref low)
- Add missing ip6tables FORWARD ACCEPT rule for new connections in
  direct mode (only ESTABLISHED was present, blocking new flows)
- Flush ip6tables nat POSTROUTING table on clear instead of fragile
  per-rule -D deletion to prevent stale rule accumulation
</pre>
</div>
</content>
</entry>
<entry>
<title>Route IPv6 through WireGuard VPN via radvd and static gateway</title>
<updated>2026-07-08T14:55:30+00:00</updated>
<author>
<name>Ahmed Abdelhalim</name>
<email>pm@a14m.dev</email>
</author>
<published>2026-07-08T12:28:33+00:00</published>
<link rel='alternate' type='text/html' href='http://git.a14m.dev/ansible-distro-configure.git/commit/?id=b8f25e9d80c96f7170d51eb5abcd662a66d55317'/>
<id>b8f25e9d80c96f7170d51eb5abcd662a66d55317</id>
<content type='text'>
Add radvd to gateway role to advertise Pi as high-preference IPv6
default router using the stable ULA prefix (fd1e:.../64). With
FritzBox also sending RAs, devices end up with ECMP between Pi and
FritzBox. To solve this, add network_ipv6_gateway (Pi's link-local)
as a static route with metric 100 to all managed hosts — beats RA
metric 425, ensuring all IPv6 default traffic goes through Pi.

Fix IPv6 MASQUERADE in gateway-apply-rules:
- Direct mode: add MASQUERADE on end0 (LAN devices use ULA source
  addresses not known to FritzBox, so Pi must NAT them)
- FORWARD rules: restrict to RELATED,ESTABLISHED only — previously
  the broad ACCEPT rule passed un-NAT'd packets alongside masqueraded
  copies, causing duplicate SYNs, conntrack corruption, and RSTs
- MASQUERADE/clear rules: match by interface not by source subnet
  (devices may use any source address, not just the ULA prefix)
- VPN mode return traffic: explicitly restrict to wg+→end0 direction

Add network_ipv6_gateway var (optional) to network role NM templates
(ethernet, wifi, bridge) — injects a static IPv6 default route at
metric 100 when set. Add rpi5 static route to FritzBox link-local so
Pi keeps IPv6 after FritzBox RA is disabled.

Force SSH to IPv4 for *.local hosts (AddressFamily inet) — prevents
Ansible from hanging on mDNS returning multiple IPv6 addresses.

Update gateway and pihole READMEs with two-step IPv6 setup process.

Co-Authored-By: Claude.ai
</content>
<content type='xhtml'>
<div xmlns='http://www.w3.org/1999/xhtml'>
<pre>
Add radvd to gateway role to advertise Pi as high-preference IPv6
default router using the stable ULA prefix (fd1e:.../64). With
FritzBox also sending RAs, devices end up with ECMP between Pi and
FritzBox. To solve this, add network_ipv6_gateway (Pi's link-local)
as a static route with metric 100 to all managed hosts — beats RA
metric 425, ensuring all IPv6 default traffic goes through Pi.

Fix IPv6 MASQUERADE in gateway-apply-rules:
- Direct mode: add MASQUERADE on end0 (LAN devices use ULA source
  addresses not known to FritzBox, so Pi must NAT them)
- FORWARD rules: restrict to RELATED,ESTABLISHED only — previously
  the broad ACCEPT rule passed un-NAT'd packets alongside masqueraded
  copies, causing duplicate SYNs, conntrack corruption, and RSTs
- MASQUERADE/clear rules: match by interface not by source subnet
  (devices may use any source address, not just the ULA prefix)
- VPN mode return traffic: explicitly restrict to wg+→end0 direction

Add network_ipv6_gateway var (optional) to network role NM templates
(ethernet, wifi, bridge) — injects a static IPv6 default route at
metric 100 when set. Add rpi5 static route to FritzBox link-local so
Pi keeps IPv6 after FritzBox RA is disabled.

Force SSH to IPv4 for *.local hosts (AddressFamily inet) — prevents
Ansible from hanging on mDNS returning multiple IPv6 addresses.

Update gateway and pihole READMEs with two-step IPv6 setup process.

Co-Authored-By: Claude.ai
</pre>
</div>
</content>
</entry>
<entry>
<title>Implement a working ipv6 on gateway</title>
<updated>2026-07-08T01:15:11+00:00</updated>
<author>
<name>Ahmed Abdelhalim</name>
<email>pm@a14m.dev</email>
</author>
<published>2026-07-08T01:15:11+00:00</published>
<link rel='alternate' type='text/html' href='http://git.a14m.dev/ansible-distro-configure.git/commit/?id=bb0abab8308256c028c29e3732e53ef211cad613'/>
<id>bb0abab8308256c028c29e3732e53ef211cad613</id>
<content type='text'>
</content>
<content type='xhtml'>
<div xmlns='http://www.w3.org/1999/xhtml'>
<pre>
</pre>
</div>
</content>
</entry>
<entry>
<title>Enable ipv6 on the rpi</title>
<updated>2026-07-07T10:28:16+00:00</updated>
<author>
<name>Ahmed Abdelhalim</name>
<email>pm@a14m.dev</email>
</author>
<published>2026-07-07T10:28:16+00:00</published>
<link rel='alternate' type='text/html' href='http://git.a14m.dev/ansible-distro-configure.git/commit/?id=3880136d2d13973825be77934468fed51d01624b'/>
<id>3880136d2d13973825be77934468fed51d01624b</id>
<content type='text'>
</content>
<content type='xhtml'>
<div xmlns='http://www.w3.org/1999/xhtml'>
<pre>
</pre>
</div>
</content>
</entry>
<entry>
<title>Add ipv6 support to gateway VPN role</title>
<updated>2026-01-29T17:16:35+00:00</updated>
<author>
<name>Ahmed Abdelhalim</name>
<email>pm@a14m.dev</email>
</author>
<published>2026-01-24T22:36:50+00:00</published>
<link rel='alternate' type='text/html' href='http://git.a14m.dev/ansible-distro-configure.git/commit/?id=32c738d4ce0336b16eb870419b4ed02af3d6c227'/>
<id>32c738d4ce0336b16eb870419b4ed02af3d6c227</id>
<content type='text'>
After finding issues that vpn ip6 wasn't working reliably (which was
obvious over VPN)
Needed to add the VPN routing table support (similar to ipv4)

This together with disabling ssh (for github and sr.ht) over ipv6 makes
the vpn reliable again

Will test and see, since I saw that the archlinux machine wasn't working
properly over the vpn, but it could be due to the VPN ipv6 wasn't
resolving.
</content>
<content type='xhtml'>
<div xmlns='http://www.w3.org/1999/xhtml'>
<pre>
After finding issues that vpn ip6 wasn't working reliably (which was
obvious over VPN)
Needed to add the VPN routing table support (similar to ipv4)

This together with disabling ssh (for github and sr.ht) over ipv6 makes
the vpn reliable again

Will test and see, since I saw that the archlinux machine wasn't working
properly over the vpn, but it could be due to the VPN ipv6 wasn't
resolving.
</pre>
</div>
</content>
</entry>
<entry>
<title>Implement the gateway role (replacing old wireguard-gateway)</title>
<updated>2025-09-11T22:17:35+00:00</updated>
<author>
<name>Ahmed Abdelhalim</name>
<email>pm@a14m.dev</email>
</author>
<published>2025-09-11T22:17:35+00:00</published>
<link rel='alternate' type='text/html' href='http://git.a14m.dev/ansible-distro-configure.git/commit/?id=4a812a999a79dae501db62e0eeb9e33e34282b83'/>
<id>4a812a999a79dae501db62e0eeb9e33e34282b83</id>
<content type='text'>
</content>
<content type='xhtml'>
<div xmlns='http://www.w3.org/1999/xhtml'>
<pre>
</pre>
</div>
</content>
</entry>
</feed>
