From 3685affc4c8470db64e3255572ecf4ec999a5987 Mon Sep 17 00:00:00 2001 From: Paul Buetow Date: Sat, 17 Jan 2026 00:05:46 +0200 Subject: Update content for html --- about/resources.html | 204 +++++++-------- ...5-05-11-f3s-kubernetes-with-freebsd-part-5.html | 274 +++++++++++++++++++- ...5-07-14-f3s-kubernetes-with-freebsd-part-6.html | 1 + gemfeed/atom.xml | 279 ++++++++++++++++++++- index.html | 2 +- uptime-stats.html | 42 ++-- 6 files changed, 674 insertions(+), 128 deletions(-) diff --git a/about/resources.html b/about/resources.html index 7c4dfacb..6c8a42e8 100644 --- a/about/resources.html +++ b/about/resources.html @@ -50,67 +50,67 @@ In random order:


Technical references



I didn't read them from the beginning to the end, but I am using them to look up things. The books are in random order:


Self-development and soft-skills books


@@ -119,43 +119,43 @@

Here are notes of mine for some of the books

@@ -164,31 +164,31 @@ Some of these were in-person with exams; others were online learning lectures only. In random order:


Technical guides



These are not whole books, but guides (smaller or larger) which I found very useful. in random order:


Podcasts



@@ -197,20 +197,20 @@ In random order:


Podcasts I liked


@@ -218,38 +218,38 @@ I liked them but am not listening to them anymore. The podcasts have either "finished" (no more episodes) or I stopped listening to them due to time constraints or a shift in my interests.


Newsletters I like



This is a mix of tech and non-tech newsletters I am subscribed to. In random order:


Magazines I like(d)



This is a mix of tech I like(d). I may not be a current subscriber, but now and then, I buy an issue. In random order:


diff --git a/gemfeed/2025-05-11-f3s-kubernetes-with-freebsd-part-5.html b/gemfeed/2025-05-11-f3s-kubernetes-with-freebsd-part-5.html index 896d4e04..80a0173f 100644 --- a/gemfeed/2025-05-11-f3s-kubernetes-with-freebsd-part-5.html +++ b/gemfeed/2025-05-11-f3s-kubernetes-with-freebsd-part-5.html @@ -13,7 +13,7 @@

f3s: Kubernetes with FreeBSD - Part 5: WireGuard mesh network



-Published at 2025-05-11T11:35:57+03:00, last updated Sun 11 Jan 21:33:40 EET 2026
+Published at 2025-05-11T11:35:57+03:00, last updated Thu 15 Jan 19:30:46 EET 2026

This is the fifth blog post about my f3s series for my self-hosting demands in my home lab. f3s? The "f" stands for FreeBSD, and the "3s" stands for k3s, the Kubernetes distribution I will use on FreeBSD-based physical machines.

@@ -61,6 +61,18 @@
  • ⇢ ⇢ Installing the wg0.conf files
  • ⇢ ⇢ Re-generating mesh and installing the wg0.conf files again
  • ⇢ ⇢ Setting up roaming clients
  • +
  • Adding IPv6 support to the mesh
  • +
  • ⇢ ⇢ IPv6 addressing scheme
  • +
  • ⇢ ⇢ Updating the mesh generator for IPv6
  • +
  • ⇢ ⇢ IPv6 NAT on OpenBSD gateways
  • +
  • ⇢ ⇢ Manual OpenBSD interface configuration
  • +
  • ⇢ ⇢ Verifying dual-stack connectivity
  • +
  • ⇢ ⇢ Benefits of dual-stack
  • +
  • Manual gateway failover for roaming clients
  • +
  • ⇢ ⇢ Configuration files for pixel7pro (phone)
  • +
  • ⇢ ⇢ Configuration files for earth (laptop)
  • +
  • ⇢ ⇢ Using manual failover on Android
  • +
  • ⇢ ⇢ Using manual failover on Linux
  • Happy WireGuard-ing
  • Managing Roaming Client Tunnels
  • ⇢ ⇢ Starting and stopping on earth (Fedora laptop)
  • @@ -203,6 +215,17 @@ http://www.gnu.org/software/src-highlite --> 192.168.2.110 blowfish.wg0 blowfish.wg0.wan.buetow.org 192.168.2.111 fishfinger.wg0 fishfinger.wg0.wan.buetow.org + +fd42:beef:cafe:2::130 f0.wg0 f0.wg0.wan.buetow.org +fd42:beef:cafe:2::131 f1.wg0 f1.wg0.wan.buetow.org +fd42:beef:cafe:2::132 f2.wg0 f2.wg0.wan.buetow.org + +fd42:beef:cafe:2::120 r0.wg0 r0.wg0.wan.buetow.org +fd42:beef:cafe:2::121 r1.wg0 r1.wg0.wan.buetow.org +fd42:beef:cafe:2::122 r2.wg0 r2.wg0.wan.buetow.org + +fd42:beef:cafe:2::110 blowfish.wg0 blowfish.wg0.wan.buetow.org +fd42:beef:cafe:2::111 fishfinger.wg0 fishfinger.wg0.wan.buetow.org END
    @@ -256,6 +279,17 @@ http://www.gnu.org/software/src-highlite --> 192.168.2.110 blowfish.wg0 blowfish.wg0.wan.buetow.org 192.168.2.111 fishfinger.wg0 fishfinger.wg0.wan.buetow.org + +fd42:beef:cafe:2::130 f0.wg0 f0.wg0.wan.buetow.org +fd42:beef:cafe:2::131 f1.wg0 f1.wg0.wan.buetow.org +fd42:beef:cafe:2::132 f2.wg0 f2.wg0.wan.buetow.org + +fd42:beef:cafe:2::120 r0.wg0 r0.wg0.wan.buetow.org +fd42:beef:cafe:2::121 r1.wg0 r1.wg0.wan.buetow.org +fd42:beef:cafe:2::122 r2.wg0 r2.wg0.wan.buetow.org + +fd42:beef:cafe:2::110 blowfish.wg0 blowfish.wg0.wan.buetow.org +fd42:beef:cafe:2::111 fishfinger.wg0 fishfinger.wg0.wan.buetow.org END
    @@ -312,6 +346,19 @@ http://www.gnu.org/software/src-highlite --> 192.168.2.111 fishfinger.wg0 fishfinger.wg0.wan.buetow.org 192.168.2.200 earth.wg0 earth.wg0.wan.buetow.org 192.168.2.201 pixel7pro.wg0 pixel7pro.wg0.wan.buetow.org + +fd42:beef:cafe:2::130 f0.wg0 f0.wg0.wan.buetow.org +fd42:beef:cafe:2::131 f1.wg0 f1.wg0.wan.buetow.org +fd42:beef:cafe:2::132 f2.wg0 f2.wg0.wan.buetow.org + +fd42:beef:cafe:2::120 r0.wg0 r0.wg0.wan.buetow.org +fd42:beef:cafe:2::121 r1.wg0 r1.wg0.wan.buetow.org +fd42:beef:cafe:2::122 r2.wg0 r2.wg0.wan.buetow.org + +fd42:beef:cafe:2::110 blowfish.wg0 blowfish.wg0.wan.buetow.org +fd42:beef:cafe:2::111 fishfinger.wg0 fishfinger.wg0.wan.buetow.org +fd42:beef:cafe:2::200 earth.wg0 earth.wg0.wan.buetow.org +fd42:beef:cafe:2::201 pixel7pro.wg0 pixel7pro.wg0.wan.buetow.org END
    @@ -524,6 +571,7 @@ hosts: wg0: domain: 'wg0.wan.buetow.org' ip: '192.168.2.130' + ipv6: 'fd42:beef:cafe:2::130' exclude_peers: - earth - pixel7pro @@ -543,6 +591,7 @@ hosts: wg0: domain: 'wg0.wan.buetow.org' ip: '192.168.2.120' + ipv6: 'fd42:beef:cafe:2::120' exclude_peers: - earth - pixel7pro @@ -562,6 +611,7 @@ hosts: wg0: domain: 'wg0.wan.buetow.org' ip: '192.168.2.110' + ipv6: 'fd42:beef:cafe:2::110' exclude_peers: - earth - pixel7pro @@ -579,6 +629,7 @@ hosts: wg0: domain: 'wg0.wan.buetow.org' ip: '192.168.2.111' + ipv6: 'fd42:beef:cafe:2::111' exclude_peers: - earth - pixel7pro @@ -587,6 +638,7 @@ hosts: wg0: domain: 'wg0.wan.buetow.org' ip: '192.168.2.200' + ipv6: 'fd42:beef:cafe:2::200' exclude_peers: - f0 - f1 @@ -600,6 +652,7 @@ hosts: wg0: domain: 'wg0.wan.buetow.org' ip: '192.168.2.201' + ipv6: 'fd42:beef:cafe:2::201' exclude_peers: - f0 - f1 @@ -939,6 +992,225 @@ http://www.gnu.org/software/src-highlite -->
    The service is disabled from auto-start so the VPN is only active when manually started. This allows selective VPN usage based on need.

    +

    Adding IPv6 support to the mesh


    +
    +After setting up the IPv4-only mesh network, I decided to add dual-stack IPv6 support to enable more networking capabilities and prepare for the future. All 10 hosts (8 infrastructure + 2 roaming clients) now have both IPv4 and IPv6 addresses on their WireGuard interfaces.
    +
    +

    IPv6 addressing scheme


    +
    +We use ULA (Unique Local Address) private IPv6 space, analogous to RFC1918 private IPv4 addresses:
    +
    +
    +All hosts receive dual-stack addresses:
    +
    +
    +fd42:beef:cafe:2::110/64  - blowfish.wg0 (OpenBSD gateway)
    +fd42:beef:cafe:2::111/64  - fishfinger.wg0 (OpenBSD gateway)
    +fd42:beef:cafe:2::120/64  - r0.wg0 (Rocky Linux VM)
    +fd42:beef:cafe:2::121/64  - r1.wg0 (Rocky Linux VM)
    +fd42:beef:cafe:2::122/64  - r2.wg0 (Rocky Linux VM)
    +fd42:beef:cafe:2::130/64  - f0.wg0 (FreeBSD host)
    +fd42:beef:cafe:2::131/64  - f1.wg0 (FreeBSD host)
    +fd42:beef:cafe:2::132/64  - f2.wg0 (FreeBSD host)
    +fd42:beef:cafe:2::200/64  - earth.wg0 (roaming laptop)
    +fd42:beef:cafe:2::201/64  - pixel7pro.wg0 (roaming phone)
    +
    +
    +

    Updating the mesh generator for IPv6


    +
    +The mesh generator required two modifications to support dual-stack configurations:
    +
    +**1. Address generation (address method)**
    +
    +The generator now outputs multiple Address directives when IPv6 is present:
    +
    + +
    def address
    +  return '# No Address = ... for OpenBSD here' if hosts[myself]['os'] == 'OpenBSD'
    +
    +  ipv4 = hosts[myself]['wg0']['ip']
    +  ipv6 = hosts[myself]['wg0']['ipv6']
    +
    +  # WireGuard supports multiple Address directives for dual-stack
    +  if ipv6
    +    "Address = #{ipv4}\nAddress = #{ipv6}/64"
    +  else
    +    "Address = #{ipv4}"
    +  end
    +end
    +
    +
    +**2. AllowedIPs generation (peers method)**
    +
    +For mesh peers, both IPv4 and IPv6 addresses are included in AllowedIPs:
    +
    + +
    if is_roaming
    +  allowed_ips = '0.0.0.0/0, ::/0'
    +else
    +  # For mesh peers, allow both IPv4 and IPv6 if present
    +  ipv4 = data['wg0']['ip']
    +  ipv6 = data['wg0']['ipv6']
    +  allowed_ips = ipv6 ? "#{ipv4}/32, #{ipv6}/128" : "#{ipv4}/32"
    +end
    +
    +
    +Roaming clients keep AllowedIPs = 0.0.0.0/0, ::/0 to route all traffic (IPv4 and IPv6) through the VPN.
    +
    +

    IPv6 NAT on OpenBSD gateways


    +
    +To allow roaming clients to access the internet via IPv6, we added NAT66 rules to the OpenBSD gateways' pf.conf:
    +
    +
    +# NAT for WireGuard clients to access internet (IPv4)
    +match out on vio0 from 192.168.2.0/24 to any nat-to (vio0)
    +
    +# NAT66 for WireGuard clients to access internet (IPv6)
    +# Uses NPTv6 (Network Prefix Translation) to translate ULA to public IPv6
    +match out on vio0 inet6 from fd42:beef:cafe:2::/64 to any nat-to (vio0)
    +
    +# Allow all UDP traffic on WireGuard port (IPv4 and IPv6)
    +pass in inet proto udp from any to any port 56709
    +pass in inet6 proto udp from any to any port 56709
    +
    +
    +OpenBSD's PF firewall supports IPv6 NAT with the same syntax as IPv4, using NPTv6 (RFC 6296) to translate the ULA addresses to the gateway's public IPv6 address.
    +
    +

    Manual OpenBSD interface configuration


    +
    +Since OpenBSD doesn't use the Address directive in WireGuard configs, IPv6 must be manually configured on the wg0 interfaces. On blowfish:
    +
    + +
    rex@blowfish:~ $ doas vi /etc/hostname.wg0
    +
    +
    +Add the IPv6 address (note the order - IPv6 must be configured before up):
    +
    +
    +inet 192.168.2.110 255.255.255.0 NONE
    +inet6 fd42:beef:cafe:2::110 64
    +up
    +!/usr/local/bin/wg setconf wg0 /etc/wireguard/wg0.conf
    +
    +
    +**Important**: The IPv6 address must be specified before the up directive. This ensures the interface has both addresses configured before WireGuard peers are loaded.
    +
    +Apply the configuration:
    +
    + +
    rex@blowfish:~ $ doas sh /etc/netstart wg0
    +rex@blowfish:~ $ ifconfig wg0 | grep inet6
    +inet6 fd42:beef:cafe:2::110 prefixlen 64
    +
    +
    +Repeat for fishfinger with address fd42:beef:cafe:2::111.
    +
    +After reboot, the interface will automatically come up with both IPv4 and IPv6 addresses. WireGuard peers may take 30-60 seconds to establish handshakes after boot.
    +
    +

    Verifying dual-stack connectivity


    +
    +After regenerating and deploying the configurations, both IPv4 and IPv6 work across the mesh:
    +
    + +
    # From r0 (Rocky Linux VM)
    +root@r0:~ # ping -c 2 192.168.2.130  # IPv4 to f0
    +64 bytes from 192.168.2.130: icmp_seq=1 ttl=64 time=2.12 ms
    +64 bytes from 192.168.2.130: icmp_seq=2 ttl=64 time=0.681 ms
    +
    +root@r0:~ # ping6 -c 2 fd42:beef:cafe:2::130  # IPv6 to f0
    +64 bytes from fd42:beef:cafe:2::130: icmp_seq=1 ttl=64 time=2.16 ms
    +64 bytes from fd42:beef:cafe:2::130: icmp_seq=2 ttl=64 time=0.909 ms
    +
    +
    +The dual-stack configuration is backward compatible—hosts without the ipv6 field in the YAML configuration will continue to generate IPv4-only configs.
    +
    +

    Benefits of dual-stack


    +
    +Adding IPv6 to the mesh network provides:
    +
    +
    +

    Manual gateway failover for roaming clients


    +
    +WireGuard doesn't automatically failover between multiple peers with identical AllowedIPs routes. When both gateways (blowfish and fishfinger) are configured with AllowedIPs = 0.0.0.0/0, ::/0, WireGuard uses the first peer with a recent handshake. If that gateway goes down, traffic won't automatically switch to the backup.
    +
    +To enable manual failover, separate configuration files have been created for roaming clients (earth laptop and pixel7pro phone), each containing only a single gateway peer.
    +
    +

    Configuration files for pixel7pro (phone)


    +
    +Two separate configs in /home/paul/git/wireguardmeshgenerator/dist/pixel7pro/etc/wireguard/:
    +
    +
    +

    Configuration files for earth (laptop)


    +
    +Two separate configs in /home/paul/git/wireguardmeshgenerator/dist/earth/etc/wireguard/:
    +
    +
    +

    Using manual failover on Android


    +
    +On the pixel7pro phone, import both QR codes using the WireGuard app to create two separate tunnel profiles:
    +
    + +
    # Generate QR codes
    +qrencode -t ansiutf8 < dist/pixel7pro/etc/wireguard/wg0-blowfish.conf
    +qrencode -t ansiutf8 < dist/pixel7pro/etc/wireguard/wg0-fishfinger.conf
    +
    +
    +In the WireGuard app, you can then manually enable/disable each tunnel to select which gateway to use. Only enable one tunnel at a time.
    +
    +

    Using manual failover on Linux


    +
    +On the earth laptop, copy both configs and use systemd to switch between them:
    +
    + +
    # Install both configurations
    +sudo cp dist/earth/etc/wireguard/wg0-blowfish.conf /etc/wireguard/
    +sudo cp dist/earth/etc/wireguard/wg0-fishfinger.conf /etc/wireguard/
    +
    +# Start with blowfish gateway
    +sudo systemctl start wg-quick@wg0-blowfish.service
    +
    +# To switch to fishfinger gateway
    +sudo systemctl stop wg-quick@wg0-blowfish.service
    +sudo systemctl start wg-quick@wg0-fishfinger.service
    +
    +
    +This approach provides explicit control over which gateway handles roaming client traffic, useful when one gateway needs maintenance or experiences connectivity issues.
    +

    Happy WireGuard-ing



    All is set up now. E.g. on f0:
    diff --git a/gemfeed/2025-07-14-f3s-kubernetes-with-freebsd-part-6.html b/gemfeed/2025-07-14-f3s-kubernetes-with-freebsd-part-6.html index a9aaa5fb..fe828914 100644 --- a/gemfeed/2025-07-14-f3s-kubernetes-with-freebsd-part-6.html +++ b/gemfeed/2025-07-14-f3s-kubernetes-with-freebsd-part-6.html @@ -1008,6 +1008,7 @@ ifconfig_re0_alias0="inet vhid 1 advskew 100 pass testpass
     192.168.2.138 f3s-storage-ha f3s-storage-ha.wg0 f3s-storage-ha.wg0.wan.buetow.org
    +fd42:beef:cafe:2::138 f3s-storage-ha f3s-storage-ha.wg0 f3s-storage-ha.wg0.wan.buetow.org
     

    This allows clients to connect to f3s-storage-ha regardless of which physical server is currently the MASTER.
    diff --git a/gemfeed/atom.xml b/gemfeed/atom.xml index d24610e7..92baa74d 100644 --- a/gemfeed/atom.xml +++ b/gemfeed/atom.xml @@ -1,6 +1,6 @@ - 2026-01-11T22:40:26+02:00 + 2026-01-17T00:03:44+02:00 foo.zone feed To be in the .zone! @@ -7454,6 +7454,7 @@ ifconfig_re0_alias0="inet vhid 1 advskew 100 pass testpass
     192.168.2.138 f3s-storage-ha f3s-storage-ha.wg0 f3s-storage-ha.wg0.wan.buetow.org
    +fd42:beef:cafe:2::138 f3s-storage-ha f3s-storage-ha.wg0 f3s-storage-ha.wg0.wan.buetow.org
     

    This allows clients to connect to f3s-storage-ha regardless of which physical server is currently the MASTER.
    @@ -9566,7 +9567,7 @@ Jul 06 10:f3s: Kubernetes with FreeBSD - Part 5: WireGuard mesh network https://foo.zone/gemfeed/2025-05-11-f3s-kubernetes-with-freebsd-part-5.html - 2025-05-11T11:35:57+03:00, last updated Sun 11 Jan 21:33:40 EET 2026 + 2025-05-11T11:35:57+03:00, last updated Thu 15 Jan 19:30:46 EET 2026 Paul Buetow aka snonux paul@dev.buetow.org @@ -9576,7 +9577,7 @@ Jul 06 10:

    f3s: Kubernetes with FreeBSD - Part 5: WireGuard mesh network



    -Published at 2025-05-11T11:35:57+03:00, last updated Sun 11 Jan 21:33:40 EET 2026
    +Published at 2025-05-11T11:35:57+03:00, last updated Thu 15 Jan 19:30:46 EET 2026

    This is the fifth blog post about my f3s series for my self-hosting demands in my home lab. f3s? The "f" stands for FreeBSD, and the "3s" stands for k3s, the Kubernetes distribution I will use on FreeBSD-based physical machines.

    @@ -9624,6 +9625,18 @@ Jul 06 10:⇢ ⇢ Installing the wg0.conf files
  • ⇢ ⇢ Re-generating mesh and installing the wg0.conf files again
  • ⇢ ⇢ Setting up roaming clients
  • +
  • Adding IPv6 support to the mesh
  • +
  • ⇢ ⇢ IPv6 addressing scheme
  • +
  • ⇢ ⇢ Updating the mesh generator for IPv6
  • +
  • ⇢ ⇢ IPv6 NAT on OpenBSD gateways
  • +
  • ⇢ ⇢ Manual OpenBSD interface configuration
  • +
  • ⇢ ⇢ Verifying dual-stack connectivity
  • +
  • ⇢ ⇢ Benefits of dual-stack
  • +
  • Manual gateway failover for roaming clients
  • +
  • ⇢ ⇢ Configuration files for pixel7pro (phone)
  • +
  • ⇢ ⇢ Configuration files for earth (laptop)
  • +
  • ⇢ ⇢ Using manual failover on Android
  • +
  • ⇢ ⇢ Using manual failover on Linux
  • Happy WireGuard-ing
  • Managing Roaming Client Tunnels
  • ⇢ ⇢ Starting and stopping on earth (Fedora laptop)
  • @@ -9766,6 +9779,17 @@ http://www.gnu.org/software/src-highlite --> 192.168.2.110 blowfish.wg0 blowfish.wg0.wan.buetow.org 192.168.2.111 fishfinger.wg0 fishfinger.wg0.wan.buetow.org + +fd42:beef:cafe:2::130 f0.wg0 f0.wg0.wan.buetow.org +fd42:beef:cafe:2::131 f1.wg0 f1.wg0.wan.buetow.org +fd42:beef:cafe:2::132 f2.wg0 f2.wg0.wan.buetow.org + +fd42:beef:cafe:2::120 r0.wg0 r0.wg0.wan.buetow.org +fd42:beef:cafe:2::121 r1.wg0 r1.wg0.wan.buetow.org +fd42:beef:cafe:2::122 r2.wg0 r2.wg0.wan.buetow.org + +fd42:beef:cafe:2::110 blowfish.wg0 blowfish.wg0.wan.buetow.org +fd42:beef:cafe:2::111 fishfinger.wg0 fishfinger.wg0.wan.buetow.org END
    @@ -9819,6 +9843,17 @@ http://www.gnu.org/software/src-highlite --> 192.168.2.110 blowfish.wg0 blowfish.wg0.wan.buetow.org 192.168.2.111 fishfinger.wg0 fishfinger.wg0.wan.buetow.org + +fd42:beef:cafe:2::130 f0.wg0 f0.wg0.wan.buetow.org +fd42:beef:cafe:2::131 f1.wg0 f1.wg0.wan.buetow.org +fd42:beef:cafe:2::132 f2.wg0 f2.wg0.wan.buetow.org + +fd42:beef:cafe:2::120 r0.wg0 r0.wg0.wan.buetow.org +fd42:beef:cafe:2::121 r1.wg0 r1.wg0.wan.buetow.org +fd42:beef:cafe:2::122 r2.wg0 r2.wg0.wan.buetow.org + +fd42:beef:cafe:2::110 blowfish.wg0 blowfish.wg0.wan.buetow.org +fd42:beef:cafe:2::111 fishfinger.wg0 fishfinger.wg0.wan.buetow.org END
    @@ -9875,6 +9910,19 @@ http://www.gnu.org/software/src-highlite --> 192.168.2.111 fishfinger.wg0 fishfinger.wg0.wan.buetow.org 192.168.2.200 earth.wg0 earth.wg0.wan.buetow.org 192.168.2.201 pixel7pro.wg0 pixel7pro.wg0.wan.buetow.org + +fd42:beef:cafe:2::130 f0.wg0 f0.wg0.wan.buetow.org +fd42:beef:cafe:2::131 f1.wg0 f1.wg0.wan.buetow.org +fd42:beef:cafe:2::132 f2.wg0 f2.wg0.wan.buetow.org + +fd42:beef:cafe:2::120 r0.wg0 r0.wg0.wan.buetow.org +fd42:beef:cafe:2::121 r1.wg0 r1.wg0.wan.buetow.org +fd42:beef:cafe:2::122 r2.wg0 r2.wg0.wan.buetow.org + +fd42:beef:cafe:2::110 blowfish.wg0 blowfish.wg0.wan.buetow.org +fd42:beef:cafe:2::111 fishfinger.wg0 fishfinger.wg0.wan.buetow.org +fd42:beef:cafe:2::200 earth.wg0 earth.wg0.wan.buetow.org +fd42:beef:cafe:2::201 pixel7pro.wg0 pixel7pro.wg0.wan.buetow.org END
    @@ -10087,6 +10135,7 @@ hosts: wg0: domain: 'wg0.wan.buetow.org' ip: '192.168.2.130' + ipv6: 'fd42:beef:cafe:2::130' exclude_peers: - earth - pixel7pro @@ -10106,6 +10155,7 @@ hosts: wg0: domain: 'wg0.wan.buetow.org' ip: '192.168.2.120' + ipv6: 'fd42:beef:cafe:2::120' exclude_peers: - earth - pixel7pro @@ -10125,6 +10175,7 @@ hosts: wg0: domain: 'wg0.wan.buetow.org' ip: '192.168.2.110' + ipv6: 'fd42:beef:cafe:2::110' exclude_peers: - earth - pixel7pro @@ -10142,6 +10193,7 @@ hosts: wg0: domain: 'wg0.wan.buetow.org' ip: '192.168.2.111' + ipv6: 'fd42:beef:cafe:2::111' exclude_peers: - earth - pixel7pro @@ -10150,6 +10202,7 @@ hosts: wg0: domain: 'wg0.wan.buetow.org' ip: '192.168.2.200' + ipv6: 'fd42:beef:cafe:2::200' exclude_peers: - f0 - f1 @@ -10163,6 +10216,7 @@ hosts: wg0: domain: 'wg0.wan.buetow.org' ip: '192.168.2.201' + ipv6: 'fd42:beef:cafe:2::201' exclude_peers: - f0 - f1 @@ -10502,6 +10556,225 @@ http://www.gnu.org/software/src-highlite -->
    The service is disabled from auto-start so the VPN is only active when manually started. This allows selective VPN usage based on need.

    +

    Adding IPv6 support to the mesh


    +
    +After setting up the IPv4-only mesh network, I decided to add dual-stack IPv6 support to enable more networking capabilities and prepare for the future. All 10 hosts (8 infrastructure + 2 roaming clients) now have both IPv4 and IPv6 addresses on their WireGuard interfaces.
    +
    +

    IPv6 addressing scheme


    +
    +We use ULA (Unique Local Address) private IPv6 space, analogous to RFC1918 private IPv4 addresses:
    +
    +
      +
    • Prefix: fd42:beef:cafe::/48
    • +
    • Subnet: fd42:beef:cafe:2::/64 (wg0 interfaces)
    • +

    +All hosts receive dual-stack addresses:
    +
    +
    +fd42:beef:cafe:2::110/64  - blowfish.wg0 (OpenBSD gateway)
    +fd42:beef:cafe:2::111/64  - fishfinger.wg0 (OpenBSD gateway)
    +fd42:beef:cafe:2::120/64  - r0.wg0 (Rocky Linux VM)
    +fd42:beef:cafe:2::121/64  - r1.wg0 (Rocky Linux VM)
    +fd42:beef:cafe:2::122/64  - r2.wg0 (Rocky Linux VM)
    +fd42:beef:cafe:2::130/64  - f0.wg0 (FreeBSD host)
    +fd42:beef:cafe:2::131/64  - f1.wg0 (FreeBSD host)
    +fd42:beef:cafe:2::132/64  - f2.wg0 (FreeBSD host)
    +fd42:beef:cafe:2::200/64  - earth.wg0 (roaming laptop)
    +fd42:beef:cafe:2::201/64  - pixel7pro.wg0 (roaming phone)
    +
    +
    +

    Updating the mesh generator for IPv6


    +
    +The mesh generator required two modifications to support dual-stack configurations:
    +
    +**1. Address generation (address method)**
    +
    +The generator now outputs multiple Address directives when IPv6 is present:
    +
    + +
    def address
    +  return '# No Address = ... for OpenBSD here' if hosts[myself]['os'] == 'OpenBSD'
    +
    +  ipv4 = hosts[myself]['wg0']['ip']
    +  ipv6 = hosts[myself]['wg0']['ipv6']
    +
    +  # WireGuard supports multiple Address directives for dual-stack
    +  if ipv6
    +    "Address = #{ipv4}\nAddress = #{ipv6}/64"
    +  else
    +    "Address = #{ipv4}"
    +  end
    +end
    +
    +
    +**2. AllowedIPs generation (peers method)**
    +
    +For mesh peers, both IPv4 and IPv6 addresses are included in AllowedIPs:
    +
    + +
    if is_roaming
    +  allowed_ips = '0.0.0.0/0, ::/0'
    +else
    +  # For mesh peers, allow both IPv4 and IPv6 if present
    +  ipv4 = data['wg0']['ip']
    +  ipv6 = data['wg0']['ipv6']
    +  allowed_ips = ipv6 ? "#{ipv4}/32, #{ipv6}/128" : "#{ipv4}/32"
    +end
    +
    +
    +Roaming clients keep AllowedIPs = 0.0.0.0/0, ::/0 to route all traffic (IPv4 and IPv6) through the VPN.
    +
    +

    IPv6 NAT on OpenBSD gateways


    +
    +To allow roaming clients to access the internet via IPv6, we added NAT66 rules to the OpenBSD gateways' pf.conf:
    +
    +
    +# NAT for WireGuard clients to access internet (IPv4)
    +match out on vio0 from 192.168.2.0/24 to any nat-to (vio0)
    +
    +# NAT66 for WireGuard clients to access internet (IPv6)
    +# Uses NPTv6 (Network Prefix Translation) to translate ULA to public IPv6
    +match out on vio0 inet6 from fd42:beef:cafe:2::/64 to any nat-to (vio0)
    +
    +# Allow all UDP traffic on WireGuard port (IPv4 and IPv6)
    +pass in inet proto udp from any to any port 56709
    +pass in inet6 proto udp from any to any port 56709
    +
    +
    +OpenBSD's PF firewall supports IPv6 NAT with the same syntax as IPv4, using NPTv6 (RFC 6296) to translate the ULA addresses to the gateway's public IPv6 address.
    +
    +

    Manual OpenBSD interface configuration


    +
    +Since OpenBSD doesn't use the Address directive in WireGuard configs, IPv6 must be manually configured on the wg0 interfaces. On blowfish:
    +
    + +
    rex@blowfish:~ $ doas vi /etc/hostname.wg0
    +
    +
    +Add the IPv6 address (note the order - IPv6 must be configured before up):
    +
    +
    +inet 192.168.2.110 255.255.255.0 NONE
    +inet6 fd42:beef:cafe:2::110 64
    +up
    +!/usr/local/bin/wg setconf wg0 /etc/wireguard/wg0.conf
    +
    +
    +**Important**: The IPv6 address must be specified before the up directive. This ensures the interface has both addresses configured before WireGuard peers are loaded.
    +
    +Apply the configuration:
    +
    + +
    rex@blowfish:~ $ doas sh /etc/netstart wg0
    +rex@blowfish:~ $ ifconfig wg0 | grep inet6
    +inet6 fd42:beef:cafe:2::110 prefixlen 64
    +
    +
    +Repeat for fishfinger with address fd42:beef:cafe:2::111.
    +
    +After reboot, the interface will automatically come up with both IPv4 and IPv6 addresses. WireGuard peers may take 30-60 seconds to establish handshakes after boot.
    +
    +

    Verifying dual-stack connectivity


    +
    +After regenerating and deploying the configurations, both IPv4 and IPv6 work across the mesh:
    +
    + +
    # From r0 (Rocky Linux VM)
    +root@r0:~ # ping -c 2 192.168.2.130  # IPv4 to f0
    +64 bytes from 192.168.2.130: icmp_seq=1 ttl=64 time=2.12 ms
    +64 bytes from 192.168.2.130: icmp_seq=2 ttl=64 time=0.681 ms
    +
    +root@r0:~ # ping6 -c 2 fd42:beef:cafe:2::130  # IPv6 to f0
    +64 bytes from fd42:beef:cafe:2::130: icmp_seq=1 ttl=64 time=2.16 ms
    +64 bytes from fd42:beef:cafe:2::130: icmp_seq=2 ttl=64 time=0.909 ms
    +
    +
    +The dual-stack configuration is backward compatible—hosts without the ipv6 field in the YAML configuration will continue to generate IPv4-only configs.
    +
    +

    Benefits of dual-stack


    +
    +Adding IPv6 to the mesh network provides:
    +
    +
      +
    • **Future-proofing**: Ready for IPv6-only services and networks
    • +
    • **Compatibility**: Dual-stack maintains full IPv4 compatibility
    • +
    • **Learning**: Hands-on experience with IPv6 networking
    • +
    • **Flexibility**: Roaming clients can access both IPv4 and IPv6 internet resources
    • +

    +

    Manual gateway failover for roaming clients


    +
    +WireGuard doesn't automatically failover between multiple peers with identical AllowedIPs routes. When both gateways (blowfish and fishfinger) are configured with AllowedIPs = 0.0.0.0/0, ::/0, WireGuard uses the first peer with a recent handshake. If that gateway goes down, traffic won't automatically switch to the backup.
    +
    +To enable manual failover, separate configuration files have been created for roaming clients (earth laptop and pixel7pro phone), each containing only a single gateway peer.
    +
    +

    Configuration files for pixel7pro (phone)


    +
    +Two separate configs in /home/paul/git/wireguardmeshgenerator/dist/pixel7pro/etc/wireguard/:
    +
    +
      +
    • **wg0-blowfish.conf** - Routes all traffic through blowfish gateway (23.88.35.144)
    • +
    • **wg0-fishfinger.conf** - Routes all traffic through fishfinger gateway (46.23.94.99)
    • +

    +

    Configuration files for earth (laptop)


    +
    +Two separate configs in /home/paul/git/wireguardmeshgenerator/dist/earth/etc/wireguard/:
    +
    +
      +
    • **wg0-blowfish.conf** - Routes all traffic through blowfish gateway
    • +
    • **wg0-fishfinger.conf** - Routes all traffic through fishfinger gateway
    • +

    +

    Using manual failover on Android


    +
    +On the pixel7pro phone, import both QR codes using the WireGuard app to create two separate tunnel profiles:
    +
    + +
    # Generate QR codes
    +qrencode -t ansiutf8 < dist/pixel7pro/etc/wireguard/wg0-blowfish.conf
    +qrencode -t ansiutf8 < dist/pixel7pro/etc/wireguard/wg0-fishfinger.conf
    +
    +
    +In the WireGuard app, you can then manually enable/disable each tunnel to select which gateway to use. Only enable one tunnel at a time.
    +
    +

    Using manual failover on Linux


    +
    +On the earth laptop, copy both configs and use systemd to switch between them:
    +
    + +
    # Install both configurations
    +sudo cp dist/earth/etc/wireguard/wg0-blowfish.conf /etc/wireguard/
    +sudo cp dist/earth/etc/wireguard/wg0-fishfinger.conf /etc/wireguard/
    +
    +# Start with blowfish gateway
    +sudo systemctl start wg-quick@wg0-blowfish.service
    +
    +# To switch to fishfinger gateway
    +sudo systemctl stop wg-quick@wg0-blowfish.service
    +sudo systemctl start wg-quick@wg0-fishfinger.service
    +
    +
    +This approach provides explicit control over which gateway handles roaming client traffic, useful when one gateway needs maintenance or experiences connectivity issues.
    +

    Happy WireGuard-ing



    All is set up now. E.g. on f0:
    diff --git a/index.html b/index.html index d8a84f24..6cc3bf2d 100644 --- a/index.html +++ b/index.html @@ -13,7 +13,7 @@

    Hello!



    -This site was generated at 2026-01-11T22:40:26+02:00 by Gemtexter
    +This site was generated at 2026-01-17T00:03:44+02:00 by Gemtexter

    Welcome to the foo.zone!

    diff --git a/uptime-stats.html b/uptime-stats.html index 92712e63..cca46497 100644 --- a/uptime-stats.html +++ b/uptime-stats.html @@ -13,7 +13,7 @@

    My machine uptime stats



    -This site was last updated at 2026-01-11T22:40:26+02:00
    +This site was last updated at 2026-01-17T00:03:44+02:00

    The following stats were collected via uptimed on all of my personal computers over many years and the output was generated by guprecords, the global uptime records stats analyser of mine.

    @@ -47,12 +47,12 @@ | 11. | uranus | 59 | NetBSD 10.1 | | 12. | pluto | 51 | Linux 3.2.0-4-amd64 | | 13. | *mega-m3-pro | 50 | Darwin 24.6.0 | -| 14. | mega15289 | 50 | Darwin 23.4.0 | -| 15. | *fishfinger | 50 | OpenBSD 7.7 | +| 14. | *fishfinger | 50 | OpenBSD 7.7 | +| 15. | mega15289 | 50 | Darwin 23.4.0 | | 16. | *t450 | 46 | FreeBSD 14.2-RELEASE | | 17. | *blowfish | 45 | OpenBSD 7.7 | -| 18. | mega8477 | 40 | Darwin 13.4.0 | -| 19. | phobos | 40 | Linux 3.4.0-CM-g1dd7cdf | +| 18. | phobos | 40 | Linux 3.4.0-CM-g1dd7cdf | +| 19. | mega8477 | 40 | Darwin 13.4.0 | | 20. | sun | 33 | FreeBSD 10.3-RELEASE-p24 | +-----+----------------+-------+-------------------------------+ @@ -67,7 +67,7 @@ +-----+----------------+-----------------------------+-----------------------------------+ | 1. | vulcan | 4 years, 5 months, 6 days | Linux 3.10.0-1160.81.1.el7.x86_64 | | 2. | *blowfish | 4 years, 1 months, 6 days | OpenBSD 7.7 | -| 3. | *earth | 3 years, 12 months, 19 days | Linux 6.17.12-300.fc43.x86_64 | +| 3. | *earth | 3 years, 12 months, 24 days | Linux 6.17.12-300.fc43.x86_64 | | 4. | sun | 3 years, 9 months, 26 days | FreeBSD 10.3-RELEASE-p24 | | 5. | uranus | 3 years, 9 months, 5 days | NetBSD 10.1 | | 6. | uugrn | 3 years, 5 months, 5 days | FreeBSD 11.2-RELEASE-p4 | @@ -78,7 +78,7 @@ | 11. | mega15289 | 1 years, 12 months, 17 days | Darwin 23.4.0 | | 12. | tauceti-f | 1 years, 9 months, 18 days | Linux 3.2.0-3-amd64 | | 13. | *t450 | 1 years, 7 months, 26 days | FreeBSD 14.2-RELEASE | -| 14. | *mega-m3-pro | 1 years, 7 months, 15 days | Darwin 24.6.0 | +| 14. | *mega-m3-pro | 1 years, 7 months, 22 days | Darwin 24.6.0 | | 15. | mega8477 | 1 years, 3 months, 25 days | Darwin 13.4.0 | | 16. | host0 | 1 years, 3 months, 9 days | FreeBSD 6.2-RELEASE-p5 | | 17. | *makemake | 1 years, 3 months, 7 days | Linux 6.9.9-200.fc40.x86_64 | @@ -112,7 +112,7 @@ | 14. | *makemake | 139 | Linux 6.9.9-200.fc40.x86_64 | | 15. | *t450 | 128 | FreeBSD 14.2-RELEASE | | 16. | tauceti-f | 108 | Linux 3.2.0-3-amd64 | -| 17. | *mega-m3-pro | 104 | Darwin 24.6.0 | +| 17. | *mega-m3-pro | 105 | Darwin 24.6.0 | | 18. | tauceti-e | 96 | Linux 3.2.0-4-amd64 | | 19. | callisto | 86 | Linux 4.0.4-303.fc22.x86_64 | | 20. | mega8477 | 80 | Darwin 13.4.0 | @@ -162,7 +162,7 @@ | 2. | dionysus | 8 years, 6 months, 17 days | FreeBSD 13.0-RELEASE-p11 | | 3. | alphacentauri | 6 years, 9 months, 13 days | FreeBSD 11.4-RELEASE-p7 | | 4. | *makemake | 4 years, 10 months, 16 days | Linux 6.9.9-200.fc40.x86_64 | -| 5. | *earth | 4 years, 6 months, 17 days | Linux 6.17.12-300.fc43.x86_64 | +| 5. | *earth | 4 years, 6 months, 22 days | Linux 6.17.12-300.fc43.x86_64 | | 6. | vulcan | 4 years, 5 months, 6 days | Linux 3.10.0-1160.81.1.el7.x86_64 | | 7. | *blowfish | 4 years, 1 months, 7 days | OpenBSD 7.7 | | 8. | sun | 3 years, 10 months, 2 days | FreeBSD 10.3-RELEASE-p24 | @@ -207,8 +207,8 @@ | 16. | Darwin 15... | 15 | | 17. | Darwin 22... | 12 | | 18. | Darwin 18... | 11 | -| 19. | FreeBSD 7... | 10 | -| 20. | FreeBSD 6... | 10 | +| 19. | FreeBSD 6... | 10 | +| 20. | OpenBSD 4... | 10 | +-----+----------------+-------+
    @@ -224,14 +224,14 @@ | 2. | *OpenBSD 7... | 8 years, 1 months, 7 days | | 3. | FreeBSD 10... | 5 years, 9 months, 9 days | | 4. | Linux 5... | 4 years, 10 months, 21 days | -| 5. | *Linux 6... | 3 years, 3 months, 19 days | +| 5. | *Linux 6... | 3 years, 3 months, 24 days | | 6. | *FreeBSD 14... | 2 years, 11 months, 5 days | | 7. | Linux 4... | 2 years, 7 months, 22 days | | 8. | FreeBSD 11... | 2 years, 4 months, 28 days | | 9. | Linux 2... | 1 years, 11 months, 21 days | | 10. | Darwin 13... | 1 years, 3 months, 25 days | | 11. | FreeBSD 6... | 1 years, 3 months, 9 days | -| 12. | *Darwin 24... | 0 years, 11 months, 21 days | +| 12. | *Darwin 24... | 0 years, 11 months, 28 days | | 13. | Darwin 23... | 0 years, 11 months, 3 days | | 14. | OpenBSD 4... | 0 years, 8 months, 12 days | | 15. | Darwin 21... | 0 years, 8 months, 2 days | @@ -255,22 +255,22 @@ | 2. | *OpenBSD 7... | 517 | | 3. | FreeBSD 10... | 406 | | 4. | Linux 5... | 317 | -| 5. | *Linux 6... | 223 | +| 5. | *Linux 6... | 224 | | 6. | *FreeBSD 14... | 211 | | 7. | Linux 4... | 175 | | 8. | FreeBSD 11... | 159 | | 9. | Linux 2... | 121 | | 10. | Darwin 13... | 80 | | 11. | FreeBSD 6... | 75 | -| 12. | *Darwin 24... | 61 | +| 12. | *Darwin 24... | 62 | | 13. | Darwin 23... | 55 | | 14. | OpenBSD 4... | 39 | | 15. | Darwin 21... | 38 | | 16. | Darwin 18... | 32 | | 17. | Darwin 22... | 30 | | 18. | Darwin 15... | 29 | -| 19. | FreeBSD 13... | 25 | -| 20. | FreeBSD 5... | 25 | +| 19. | FreeBSD 5... | 25 | +| 20. | FreeBSD 13... | 25 | +-----+----------------+-------+
    @@ -298,10 +298,10 @@ +-----+------------+-----------------------------+ | Pos | KernelName | Uptime | +-----+------------+-----------------------------+ -| 1. | *Linux | 28 years, 4 months, 11 days | +| 1. | *Linux | 28 years, 4 months, 16 days | | 2. | *FreeBSD | 12 years, 10 months, 8 days | | 3. | *OpenBSD | 8 years, 8 months, 18 days | -| 4. | *Darwin | 5 years, 3 months, 5 days | +| 4. | *Darwin | 5 years, 3 months, 12 days | | 5. | NetBSD | 0 years, 1 months, 1 days | +-----+------------+-----------------------------+ @@ -314,10 +314,10 @@ +-----+------------+-------+ | Pos | KernelName | Score | +-----+------------+-------+ -| 1. | *Linux | 1882 | +| 1. | *Linux | 1883 | | 2. | *FreeBSD | 912 | | 3. | *OpenBSD | 557 | -| 4. | *Darwin | 342 | +| 4. | *Darwin | 343 | | 5. | NetBSD | 0 | +-----+------------+-------+ -- cgit v1.2.3