summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorPaul Buetow <paul@buetow.org>2026-01-17 00:05:48 +0200
committerPaul Buetow <paul@buetow.org>2026-01-17 00:05:48 +0200
commit05e5dd253f1b0c45e78980ea648994dd79276a18 (patch)
tree1e2563958efd9db6c3a1197ad7e510f88cb7c4ca
parent591cfb6238b3d4c03028ede842cf8de191b0b217 (diff)
Update content for gemtext
-rw-r--r--about/resources.gmi204
-rw-r--r--gemfeed/2025-05-11-f3s-kubernetes-with-freebsd-part-5.gmi249
-rw-r--r--gemfeed/2025-07-14-f3s-kubernetes-with-freebsd-part-6.gmi1
-rw-r--r--gemfeed/atom.xml279
-rw-r--r--index.gmi2
-rw-r--r--uptime-stats.gmi42
6 files changed, 649 insertions, 128 deletions
diff --git a/about/resources.gmi b/about/resources.gmi
index c775c73d..09b94014 100644
--- a/about/resources.gmi
+++ b/about/resources.gmi
@@ -35,66 +35,66 @@ You won't find any links on this site because, over time, the links will break.
In random order:
-* Go Brain Teasers - Exercise Your Mind; Miki Tebeka; The Pragmatic Programmers
-* Learn You Some Erlang for Great Good; Fred Herbert; No Starch Press
-* Tmux 2: Productive Mouse-free Development; Brain P. Hogan; The Pragmatic Programmers
-* The Go Programming Language; Alan A. A. Donovan; Addison-Wesley Professional
-* The Docker Book; James Turnbull; Kindle
-* Site Reliability Engineering; How Google runs production systems; O'Reilly
-* The Practise of System and Network Administration; Thomas A. Limoncelli, Christina J. Hogan, Strata R. Chalup; Addison-Wesley Professional Pro Git; Scott Chacon, Ben Straub; Apress
-* DNS and BIND; Cricket Liu; O'Reilly
-* Systemprogrammierung in Go; Frank Müller; dpunkt
-* Java ist auch eine Insel; Christian Ullenboom;
-* 100 Go Mistakes and How to Avoid Them; Teiva Harsanyi; Manning Publications
+* Higher Order Perl; Mark Dominus; Morgan Kaufmann
* The Kubernetes Book; Nigel Poulton; Unabridged Audiobook
-* Leanring eBPF; Liz Rice; O'Reilly
* Chaos Engineering - System Resiliency in Practice; Casey Rosenthal and Nora Jones; eBook
-* Modern Perl; Chromatic ; Onyx Neon Press
+* Polished Ruby Programming; Jeremy Evans; Packt Publishing
* The KCNA (Kubernetes and Cloud Native Associate) Book; Nigel Poulton
-* Object-Oriented Programming with ANSI-C; Axel-Tobias Schreiner
-* Systems Performance Tuning; Gian-Paolo D. Musumeci and others...; O'Reilly
-* Effective awk programming; Arnold Robbins; O'Reilly
* Effective Java; Joshua Bloch; Addison-Wesley Professional
-* Seeking SRE: Conversations About Running Production Systems at Scale; David N. Blank-Edelman; eBook
-* Higher Order Perl; Mark Dominus; Morgan Kaufmann
-* Learn You a Haskell for Great Good!; Miran Lipovaca; No Starch Press
-* Perl New Features; Joshua McAdams, brian d foy; Perl School
-* Concurrency in Go; Katherine Cox-Buday; O'Reilly
-* Raku Fundamentals; Moritz Lenz; Apress
-* The DevOps Handbook; Gene Kim, Jez Humble, Patrick Debois, John Willis; Audible
-* Pro Puppet; James Turnbull, Jeffrey McCune; Apress
-* Funktionale Programmierung; Peter Pepper; Springer
-* Kubernetes Cookbook; Sameer Naik, Sébastien Goasguen, Jonathan Michaux; O'Reilly
-* Data Science at the Command Line; Jeroen Janssens; O'Reilly
-* Distributed Systems: Principles and Paradigms; Andrew S. Tanenbaum; Pearson
-* Terraform Cookbook; Mikael Krief; Packt Publishing
-* Amazon Web Services in Action; Michael Wittig and Andreas Wittig; Manning Publications
+* Go Brain Teasers - Exercise Your Mind; Miki Tebeka; The Pragmatic Programmers
+* Site Reliability Engineering; How Google runs production systems; O'Reilly
+* 21st Century C: C Tips from the New School; Ben Klemens; O'Reilly
+* Systems Performance Tuning; Gian-Paolo D. Musumeci and others...; O'Reilly
* C++ Programming Language; Bjarne Stroustrup;
+* The DevOps Handbook; Gene Kim, Jez Humble, Patrick Debois, John Willis; Audible
+* DNS and BIND; Cricket Liu; O'Reilly
+* The Docker Book; James Turnbull; Kindle
* Programming Ruby 3.3 (5th Edition); Noel Rappin, with Dave Thomas; The Pragmatic Bookshelf
-* 21st Century C: C Tips from the New School; Ben Klemens; O'Reilly
* DevOps And Site Reliability Engineering Handbook; Stephen Fleming; Audible
+* Perl New Features; Joshua McAdams, brian d foy; Perl School
+* Raku Fundamentals; Moritz Lenz; Apress
+* Systemprogrammierung in Go; Frank Müller; dpunkt
+* Java ist auch eine Insel; Christian Ullenboom;
+* The Go Programming Language; Alan A. A. Donovan; Addison-Wesley Professional
+* Data Science at the Command Line; Jeroen Janssens; O'Reilly
+* Funktionale Programmierung; Peter Pepper; Springer
* Think Raku (aka Think Perl 6); Laurent Rosenfeld, Allen B. Downey; O'Reilly
+* Kubernetes Cookbook; Sameer Naik, Sébastien Goasguen, Jonathan Michaux; O'Reilly
+* Modern Perl; Chromatic ; Onyx Neon Press
* The Pragmatic Programmer; David Thomas; Addison-Wesley
-* Raku Recipes; J.J. Merelo; Apress
* Ultimate Go Notebook; Bill Kennedy
-* Clusterbau mit Linux-HA; Michael Schwartzkopff; O'Reilly
-* Hands-on Infrastructure Monitoring with Prometheus; Joel Bastos, Pedro Araujo; Packt
-* 97 things every SRE should know; Emil Stolarsky, Jaime Woo; O'Reilly
+* 100 Go Mistakes and How to Avoid Them; Teiva Harsanyi; Manning Publications
+* Learn You Some Erlang for Great Good; Fred Herbert; No Starch Press
* Developing Games in Java; David Brackeen and others...; New Riders
-* Polished Ruby Programming; Jeremy Evans; Packt Publishing
+* Concurrency in Go; Katherine Cox-Buday; O'Reilly
+* Leanring eBPF; Liz Rice; O'Reilly
+* Amazon Web Services in Action; Michael Wittig and Andreas Wittig; Manning Publications
+* Clusterbau mit Linux-HA; Michael Schwartzkopff; O'Reilly
+* Effective awk programming; Arnold Robbins; O'Reilly
* Programming Perl aka "The Camel Book"; Tom Christiansen, brian d foy, Larry Wall & Jon Orwant; O'Reilly
+* Object-Oriented Programming with ANSI-C; Axel-Tobias Schreiner
+* 97 things every SRE should know; Emil Stolarsky, Jaime Woo; O'Reilly
+* Distributed Systems: Principles and Paradigms; Andrew S. Tanenbaum; Pearson
+* The Practise of System and Network Administration; Thomas A. Limoncelli, Christina J. Hogan, Strata R. Chalup; Addison-Wesley Professional Pro Git; Scott Chacon, Ben Straub; Apress
+* Seeking SRE: Conversations About Running Production Systems at Scale; David N. Blank-Edelman; eBook
+* Terraform Cookbook; Mikael Krief; Packt Publishing
+* Learn You a Haskell for Great Good!; Miran Lipovaca; No Starch Press
+* Hands-on Infrastructure Monitoring with Prometheus; Joel Bastos, Pedro Araujo; Packt
+* Pro Puppet; James Turnbull, Jeffrey McCune; Apress
+* Raku Recipes; J.J. Merelo; Apress
+* Tmux 2: Productive Mouse-free Development; Brain P. Hogan; The Pragmatic Programmers
## 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:
-* Go: Design Patterns for Real-World Projects; Mat Ryer; Packt
+* Algorithms; Robert Sedgewick, Kevin Wayne; Addison Wesley
+* BPF Performance Tools - Linux System and Application Observability, Brendan Gregg; Addison Wesley
* The Linux Programming Interface; Michael Kerrisk; No Starch Press
-* Understanding the Linux Kernel; Daniel P. Bovet, Marco Cesati; O'Reilly
* Implementing Service Level Objectives; Alex Hidalgo; O'Reilly
+* Understanding the Linux Kernel; Daniel P. Bovet, Marco Cesati; O'Reilly
+* Go: Design Patterns for Real-World Projects; Mat Ryer; Packt
* Relayd and Httpd Mastery; Michael W Lucas
-* BPF Performance Tools - Linux System and Application Observability, Brendan Gregg; Addison Wesley
-* Algorithms; Robert Sedgewick, Kevin Wayne; Addison Wesley
* Groovy Kurz & Gut; Joerg Staudemeier; O'Reilly
## Self-development and soft-skills books
@@ -102,43 +102,43 @@ I didn't read them from the beginning to the end, but I am using them to look up
In random order:
* Consciousness: A Very Short Introduction; Susan Blackmore; Oxford Uiversity Press
-* The Obstacle Is The Way; Ryan Holiday; Profile Books Ltd
-* The Joy of Missing Out; Christina Crook; New Society Publishers
-* Who Moved My Cheese?; Dr. Spencer Johnson; Vermilion
-* Search Inside Yourself - The Unexpected path to Achieving Success, Happiness (and World Peace); Chade-Meng Tan, Daniel Goleman, Jon Kabat-Zinn; HarperOne
-* The Power of Now; Eckhard Tolle; Yellow Kite
+* Psycho-Cybernetics; Maxwell Maltz; Perigee Books
* Eat That Frog!; Brian Tracy; Hodder Paperbacks
-* Soft Skills; John Sommez; Manning Publications
-* Getting Things Done; David Allen
-* Eat That Frog; Brian Tracy
-* Influence without Authority; A. Cohen, D. Bradford; Wiley
* Solve for Happy; Mo Gawdat (RE-READ 1ST TIME)
-* The Phoenix Project - A Novel About IT, DevOps, and Helping your Business Win; Gene Kim and Kevin Behr; Trade Select
-* The Complete Software Developer's Career Guide; John Sonmez; Unabridged Audiobook
+* Who Moved My Cheese?; Dr. Spencer Johnson; Vermilion
+* The Daily Stoic; Ryan Holiday, Stephen Hanselman; Profile Books
* Staff Engineer: Leadership beyond the management track; Will Larson; Audiobook
-* Ultralearning; Scott Young; Thorsons
-* Deep Work; Cal Newport; Piatkus
-* 101 Essays that change the way you think; Brianna Wiest; Audiobook
-* The Software Engineer's Guidebook: Navigating senior, tech lead, and staff engineer positions at tech companies and startups; Gergely Orosz; Audiobook
-* The Good Enough Job; Simone Stolzoff; Ebury Edge
+* Atomic Habits; James Clear; Random House Business
+* The Joy of Missing Out; Christina Crook; New Society Publishers
* So Good They Can't Ignore You; Cal Newport; Business Plus
-* Digital Minimalism; Cal Newport; Portofolio Penguin
-* The Daily Stoic; Ryan Holiday, Stephen Hanselman; Profile Books
+* Soft Skills; John Sommez; Manning Publications
+* The Good Enough Job; Simone Stolzoff; Ebury Edge
+* Never Split the Difference; Chris Voss, Tahl Raz; Random House Business
+* The Obstacle Is The Way; Ryan Holiday; Profile Books Ltd
+* Search Inside Yourself - The Unexpected path to Achieving Success, Happiness (and World Peace); Chade-Meng Tan, Daniel Goleman, Jon Kabat-Zinn; HarperOne
+* The 7 Habits Of Highly Effective People; Stephen R. Covey; Simon & Schuster UK
+* The Complete Software Developer's Career Guide; John Sonmez; Unabridged Audiobook
* The Off Switch; Mark Cropley; Virgin Books (RE-READ 1ST TIME)
+* The Bullet Journal Method; Ryder Carroll; Fourth Estate
+* Ultralearning; Scott Young; Thorsons
+* The Power of Now; Eckhard Tolle; Yellow Kite
+* Meditation for Mortals, Oliver Burkeman, Audiobook
+* Slow Productivity; Cal Newport; Penguin Random House
+* The Courage to Be Disliked; Ichiro Kishimi and Fumitake Koga; Audiobook
+* Deep Work; Cal Newport; Piatkus
* Buddah and Einstein walk into a Bar; Guy Joseph Ale, Claire Bloom; Blackstone Publishing
-* 97 Things Every Engineering Manager Should Know; Camille Fournier; Audiobook
+* Digital Minimalism; Cal Newport; Portofolio Penguin
+* The Phoenix Project - A Novel About IT, DevOps, and Helping your Business Win; Gene Kim and Kevin Behr; Trade Select
* Time Management for System Administrators; Thomas A. Limoncelli; O'Reilly
-* The Courage to Be Disliked; Ichiro Kishimi and Fumitake Koga; Audiobook
-* Meditation for Mortals, Oliver Burkeman, Audiobook
-* The Bullet Journal Method; Ryder Carroll; Fourth Estate
-* Psycho-Cybernetics; Maxwell Maltz; Perigee Books
* Coders at Work - Reflections on the craft of programming, Peter Seibel and Mitchell Dorian et al., Audiobook
-* Atomic Habits; James Clear; Random House Business
-* Stop starting, start finishing; Arne Roock; Lean-Kanban University
-* Never Split the Difference; Chris Voss, Tahl Raz; Random House Business
-* Slow Productivity; Cal Newport; Penguin Random House
-* The 7 Habits Of Highly Effective People; Stephen R. Covey; Simon & Schuster UK
+* Eat That Frog; Brian Tracy
+* Influence without Authority; A. Cohen, D. Bradford; Wiley
+* 97 Things Every Engineering Manager Should Know; Camille Fournier; Audiobook
* Ultralearning; Anna Laurent; Self-published via Amazon
+* 101 Essays that change the way you think; Brianna Wiest; Audiobook
+* Getting Things Done; David Allen
+* Stop starting, start finishing; Arne Roock; Lean-Kanban University
+* The Software Engineer's Guidebook: Navigating senior, tech lead, and staff engineer positions at tech companies and startups; Gergely Orosz; Audiobook
=> ../notes/index.gmi Here are notes of mine for some of the books
@@ -146,30 +146,30 @@ In random order:
Some of these were in-person with exams; others were online learning lectures only. In random order:
-* Scripting Vim; Damian Conway; O'Reilly Online
-* Ultimate Go Programming; Bill Kennedy; O'Reilly Online
-* MySQL Deep Dive Workshop; 2-day on-site training
+* Structure and Interpretation of Computer Programs; Harold Abelson and more...;
* F5 Loadbalancers Training; 2-day on-site training; F5, Inc.
-* The Ultimate Kubernetes Bootcamp; School of Devops; O'Reilly Online
-* Developing IaC with Terraform (with Live Lessons); O'Reilly Online
-* Apache Tomcat Best Practises; 3-day on-site training
-* Algorithms Video Lectures; Robert Sedgewick; O'Reilly Online
-* Protocol buffers; O'Reilly Online
+* Cloud Operations on AWS - Learn how to configure, deploy, maintain, and troubleshoot your AWS environments; 3-day online live training with labs; Amazon
* Linux Security and Isolation APIs Training; Michael Kerrisk; 3-day on-site training
+* The Well-Grounded Rubyist Video Edition; David. A. Black; O'Reilly Online
+* Developing IaC with Terraform (with Live Lessons); O'Reilly Online
+* MySQL Deep Dive Workshop; 2-day on-site training
* AWS Immersion Day; Amazon; 1-day interactive online training
-* Structure and Interpretation of Computer Programs; Harold Abelson and more...;
* Red Hat Certified System Administrator; Course + certification (Although I had the option, I decided not to take the next course as it is more effective to self learn what I need)
+* Apache Tomcat Best Practises; 3-day on-site training
+* The Ultimate Kubernetes Bootcamp; School of Devops; O'Reilly Online
+* Protocol buffers; O'Reilly Online
+* Ultimate Go Programming; Bill Kennedy; O'Reilly Online
+* Algorithms Video Lectures; Robert Sedgewick; O'Reilly Online
* Functional programming lecture; Remote University of Hagen
-* The Well-Grounded Rubyist Video Edition; David. A. Black; O'Reilly Online
-* Cloud Operations on AWS - Learn how to configure, deploy, maintain, and troubleshoot your AWS environments; 3-day online live training with labs; Amazon
+* Scripting Vim; Damian Conway; O'Reilly Online
## Technical guides
These are not whole books, but guides (smaller or larger) which I found very useful. in random order:
-* Advanced Bash-Scripting Guide
-* Raku Guide at https://raku.guide
* How CPUs work at https://cpu.land
+* Raku Guide at https://raku.guide
+* Advanced Bash-Scripting Guide
## Podcasts
@@ -177,56 +177,56 @@ These are not whole books, but guides (smaller or larger) which I found very use
In random order:
+* Pratical AI
+* Modern Mentor
* Backend Banter
-* The Pragmatic Engineer Podcast
-* Fallthrough [Golang]
-* Deep Questions with Cal Newport
* Maintainable
+* The Pragmatic Engineer Podcast
* Fork Around And Find Out
-* The ProdCast (Google SRE Podcast)
-* Modern Mentor
-* The Changelog Podcast(s)
-* Pratical AI
* Hidden Brain
* BSD Now [BSD]
-* Wednesday Wisdom
+* Deep Questions with Cal Newport
* Cup o' Go [Golang]
+* The ProdCast (Google SRE Podcast)
+* Wednesday Wisdom
+* The Changelog Podcast(s)
+* Fallthrough [Golang]
* Dev Interrupted
### Podcasts I liked
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.
-* Modern Mentor
-* Go Time (predecessor of fallthrough)
+* CRE: Chaosradio Express [german]
* FLOSS weekly
* Java Pub House
* Ship It (predecessor of Fork Around And Find Out)
-* CRE: Chaosradio Express [german]
+* Go Time (predecessor of fallthrough)
+* Modern Mentor
## Newsletters I like
This is a mix of tech and non-tech newsletters I am subscribed to. In random order:
-* Andreas Brandhorst Newsletter (Sci-Fi author)
-* VK Newsletter
-* The Imperfectionist
-* Applied Go Weekly Newsletter
-* The Valuable Dev
-* Changelog News
+* Register Spill
+* The Pragmatic Engineer
* Golang Weekly
+* Applied Go Weekly Newsletter
* byteSizeGo
-* Monospace Mentor
-* The Pragmatic Engineer
+* Changelog News
+* Andreas Brandhorst Newsletter (Sci-Fi author)
* Ruby Weekly
-* Register Spill
+* The Imperfectionist
+* VK Newsletter
+* Monospace Mentor
+* The Valuable Dev
## 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:
-* freeX (not published anymore)
* Linux Magazine
+* freeX (not published anymore)
* LWN (online only)
* Linux User
diff --git a/gemfeed/2025-05-11-f3s-kubernetes-with-freebsd-part-5.gmi b/gemfeed/2025-05-11-f3s-kubernetes-with-freebsd-part-5.gmi
index d41bd722..7b0fd9fe 100644
--- a/gemfeed/2025-05-11-f3s-kubernetes-with-freebsd-part-5.gmi
+++ b/gemfeed/2025-05-11-f3s-kubernetes-with-freebsd-part-5.gmi
@@ -1,6 +1,6 @@
# 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.
@@ -47,6 +47,18 @@ Let's begin...
* ⇢ ⇢ ⇢ 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)
@@ -175,6 +187,17 @@ paul@f0:~ % cat <<END | doas tee -a /etc/hosts
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
```
@@ -219,6 +242,17 @@ We also update the `hosts` file accordingly:
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
```
@@ -266,6 +300,19 @@ blowfish$ cat <<END | doas tee -a /etc/hosts
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
```
@@ -466,6 +513,7 @@ hosts:
wg0:
domain: 'wg0.wan.buetow.org'
ip: '192.168.2.130'
+ ipv6: 'fd42:beef:cafe:2::130'
exclude_peers:
- earth
- pixel7pro
@@ -485,6 +533,7 @@ hosts:
wg0:
domain: 'wg0.wan.buetow.org'
ip: '192.168.2.120'
+ ipv6: 'fd42:beef:cafe:2::120'
exclude_peers:
- earth
- pixel7pro
@@ -504,6 +553,7 @@ hosts:
wg0:
domain: 'wg0.wan.buetow.org'
ip: '192.168.2.110'
+ ipv6: 'fd42:beef:cafe:2::110'
exclude_peers:
- earth
- pixel7pro
@@ -521,6 +571,7 @@ hosts:
wg0:
domain: 'wg0.wan.buetow.org'
ip: '192.168.2.111'
+ ipv6: 'fd42:beef:cafe:2::111'
exclude_peers:
- earth
- pixel7pro
@@ -529,6 +580,7 @@ hosts:
wg0:
domain: 'wg0.wan.buetow.org'
ip: '192.168.2.200'
+ ipv6: 'fd42:beef:cafe:2::200'
exclude_peers:
- f0
- f1
@@ -542,6 +594,7 @@ hosts:
wg0:
domain: 'wg0.wan.buetow.org'
ip: '192.168.2.201'
+ ipv6: 'fd42:beef:cafe:2::201'
exclude_peers:
- f0
- f1
@@ -856,6 +909,200 @@ For the laptop, manually copy the generated configuration:
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:
+
+```ruby
+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:
+
+```ruby
+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`:
+
+```sh
+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:
+
+```sh
+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:
+
+```sh
+# 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:
+
+```sh
+# 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:
+
+```sh
+# 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.gmi b/gemfeed/2025-07-14-f3s-kubernetes-with-freebsd-part-6.gmi
index a136ee39..b215a560 100644
--- a/gemfeed/2025-07-14-f3s-kubernetes-with-freebsd-part-6.gmi
+++ b/gemfeed/2025-07-14-f3s-kubernetes-with-freebsd-part-6.gmi
@@ -879,6 +879,7 @@ Next, update `/etc/hosts` on all nodes (`f0`, `f1`, `f2`, `r0`, `r1`, `r2`) to r
```
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 26147725..3f3cff03 100644
--- a/gemfeed/atom.xml
+++ b/gemfeed/atom.xml
@@ -1,6 +1,6 @@
<?xml version="1.0" encoding="utf-8"?>
<feed xmlns="http://www.w3.org/2005/Atom">
- <updated>2026-01-11T22:40:26+02:00</updated>
+ <updated>2026-01-17T00:03:44+02:00</updated>
<title>foo.zone feed</title>
<subtitle>To be in the .zone!</subtitle>
<link href="gemini://foo.zone/gemfeed/atom.xml" rel="self" />
@@ -7454,6 +7454,7 @@ ifconfig_re0_alias0=<font color="#808080">"inet vhid 1 advskew 100 pass testpass
<br />
<pre>
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
</pre>
<br />
<span>This allows clients to connect to <span class='inlinecode'>f3s-storage-ha</span> regardless of which physical server is currently the MASTER.</span><br />
@@ -9566,7 +9567,7 @@ Jul <font color="#000000">06</font> <font color="#000000">10</font>:<font color=
<title>f3s: Kubernetes with FreeBSD - Part 5: WireGuard mesh network</title>
<link href="gemini://foo.zone/gemfeed/2025-05-11-f3s-kubernetes-with-freebsd-part-5.gmi" />
<id>gemini://foo.zone/gemfeed/2025-05-11-f3s-kubernetes-with-freebsd-part-5.gmi</id>
- <updated>2025-05-11T11:35:57+03:00, last updated Sun 11 Jan 21:33:40 EET 2026</updated>
+ <updated>2025-05-11T11:35:57+03:00, last updated Thu 15 Jan 19:30:46 EET 2026</updated>
<author>
<name>Paul Buetow aka snonux</name>
<email>paul@dev.buetow.org</email>
@@ -9576,7 +9577,7 @@ Jul <font color="#000000">06</font> <font color="#000000">10</font>:<font color=
<div xmlns="http://www.w3.org/1999/xhtml">
<h1 style='display: inline' id='f3s-kubernetes-with-freebsd---part-5-wireguard-mesh-network'>f3s: Kubernetes with FreeBSD - Part 5: WireGuard mesh network</h1><br />
<br />
-<span class='quote'>Published at 2025-05-11T11:35:57+03:00, last updated Sun 11 Jan 21:33:40 EET 2026</span><br />
+<span class='quote'>Published at 2025-05-11T11:35:57+03:00, last updated Thu 15 Jan 19:30:46 EET 2026</span><br />
<br />
<span>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.</span><br />
<br />
@@ -9624,6 +9625,18 @@ Jul <font color="#000000">06</font> <font color="#000000">10</font>:<font color=
<li>⇢ ⇢ <a href='#installing-the-wg0conf-files'>Installing the <span class='inlinecode'>wg0.conf</span> files</a></li>
<li>⇢ ⇢ <a href='#re-generating-mesh-and-installing-the-wg0conf-files-again'>Re-generating mesh and installing the <span class='inlinecode'>wg0.conf</span> files again</a></li>
<li>⇢ ⇢ <a href='#setting-up-roaming-clients'>Setting up roaming clients</a></li>
+<li>⇢ <a href='#adding-ipv6-support-to-the-mesh'>Adding IPv6 support to the mesh</a></li>
+<li>⇢ ⇢ <a href='#ipv6-addressing-scheme'>IPv6 addressing scheme</a></li>
+<li>⇢ ⇢ <a href='#updating-the-mesh-generator-for-ipv6'>Updating the mesh generator for IPv6</a></li>
+<li>⇢ ⇢ <a href='#ipv6-nat-on-openbsd-gateways'>IPv6 NAT on OpenBSD gateways</a></li>
+<li>⇢ ⇢ <a href='#manual-openbsd-interface-configuration'>Manual OpenBSD interface configuration</a></li>
+<li>⇢ ⇢ <a href='#verifying-dual-stack-connectivity'>Verifying dual-stack connectivity</a></li>
+<li>⇢ ⇢ <a href='#benefits-of-dual-stack'>Benefits of dual-stack</a></li>
+<li>⇢ <a href='#manual-gateway-failover-for-roaming-clients'>Manual gateway failover for roaming clients</a></li>
+<li>⇢ ⇢ <a href='#configuration-files-for-pixel7pro-phone'>Configuration files for pixel7pro (phone)</a></li>
+<li>⇢ ⇢ <a href='#configuration-files-for-earth-laptop'>Configuration files for earth (laptop)</a></li>
+<li>⇢ ⇢ <a href='#using-manual-failover-on-android'>Using manual failover on Android</a></li>
+<li>⇢ ⇢ <a href='#using-manual-failover-on-linux'>Using manual failover on Linux</a></li>
<li>⇢ <a href='#happy-wireguard-ing'>Happy WireGuard-ing</a></li>
<li>⇢ <a href='#managing-roaming-client-tunnels'>Managing Roaming Client Tunnels</a></li>
<li>⇢ ⇢ <a href='#starting-and-stopping-on-earth-fedora-laptop'>Starting and stopping on earth (Fedora laptop)</a></li>
@@ -9766,6 +9779,17 @@ http://www.gnu.org/software/src-highlite -->
<font color="#000000">192.168</font>.<font color="#000000">2.110</font> blowfish.wg0 blowfish.wg0.wan.buetow.org
<font color="#000000">192.168</font>.<font color="#000000">2.111</font> fishfinger.wg0 fishfinger.wg0.wan.buetow.org
+
+fd42:beef:cafe:<font color="#000000">2</font>::<font color="#000000">130</font> f0.wg0 f0.wg0.wan.buetow.org
+fd42:beef:cafe:<font color="#000000">2</font>::<font color="#000000">131</font> f1.wg0 f1.wg0.wan.buetow.org
+fd42:beef:cafe:<font color="#000000">2</font>::<font color="#000000">132</font> f2.wg0 f2.wg0.wan.buetow.org
+
+fd42:beef:cafe:<font color="#000000">2</font>::<font color="#000000">120</font> r0.wg0 r0.wg0.wan.buetow.org
+fd42:beef:cafe:<font color="#000000">2</font>::<font color="#000000">121</font> r1.wg0 r1.wg0.wan.buetow.org
+fd42:beef:cafe:<font color="#000000">2</font>::<font color="#000000">122</font> r2.wg0 r2.wg0.wan.buetow.org
+
+fd42:beef:cafe:<font color="#000000">2</font>::<font color="#000000">110</font> blowfish.wg0 blowfish.wg0.wan.buetow.org
+fd42:beef:cafe:<font color="#000000">2</font>::<font color="#000000">111</font> fishfinger.wg0 fishfinger.wg0.wan.buetow.org
END
</pre>
<br />
@@ -9819,6 +9843,17 @@ http://www.gnu.org/software/src-highlite -->
<font color="#000000">192.168</font>.<font color="#000000">2.110</font> blowfish.wg0 blowfish.wg0.wan.buetow.org
<font color="#000000">192.168</font>.<font color="#000000">2.111</font> fishfinger.wg0 fishfinger.wg0.wan.buetow.org
+
+fd42:beef:cafe:<font color="#000000">2</font>::<font color="#000000">130</font> f0.wg0 f0.wg0.wan.buetow.org
+fd42:beef:cafe:<font color="#000000">2</font>::<font color="#000000">131</font> f1.wg0 f1.wg0.wan.buetow.org
+fd42:beef:cafe:<font color="#000000">2</font>::<font color="#000000">132</font> f2.wg0 f2.wg0.wan.buetow.org
+
+fd42:beef:cafe:<font color="#000000">2</font>::<font color="#000000">120</font> r0.wg0 r0.wg0.wan.buetow.org
+fd42:beef:cafe:<font color="#000000">2</font>::<font color="#000000">121</font> r1.wg0 r1.wg0.wan.buetow.org
+fd42:beef:cafe:<font color="#000000">2</font>::<font color="#000000">122</font> r2.wg0 r2.wg0.wan.buetow.org
+
+fd42:beef:cafe:<font color="#000000">2</font>::<font color="#000000">110</font> blowfish.wg0 blowfish.wg0.wan.buetow.org
+fd42:beef:cafe:<font color="#000000">2</font>::<font color="#000000">111</font> fishfinger.wg0 fishfinger.wg0.wan.buetow.org
END
</pre>
<br />
@@ -9875,6 +9910,19 @@ http://www.gnu.org/software/src-highlite -->
<font color="#000000">192.168</font>.<font color="#000000">2.111</font> fishfinger.wg0 fishfinger.wg0.wan.buetow.org
<font color="#000000">192.168</font>.<font color="#000000">2.200</font> earth.wg0 earth.wg0.wan.buetow.org
<font color="#000000">192.168</font>.<font color="#000000">2.201</font> pixel7pro.wg0 pixel7pro.wg0.wan.buetow.org
+
+fd42:beef:cafe:<font color="#000000">2</font>::<font color="#000000">130</font> f0.wg0 f0.wg0.wan.buetow.org
+fd42:beef:cafe:<font color="#000000">2</font>::<font color="#000000">131</font> f1.wg0 f1.wg0.wan.buetow.org
+fd42:beef:cafe:<font color="#000000">2</font>::<font color="#000000">132</font> f2.wg0 f2.wg0.wan.buetow.org
+
+fd42:beef:cafe:<font color="#000000">2</font>::<font color="#000000">120</font> r0.wg0 r0.wg0.wan.buetow.org
+fd42:beef:cafe:<font color="#000000">2</font>::<font color="#000000">121</font> r1.wg0 r1.wg0.wan.buetow.org
+fd42:beef:cafe:<font color="#000000">2</font>::<font color="#000000">122</font> r2.wg0 r2.wg0.wan.buetow.org
+
+fd42:beef:cafe:<font color="#000000">2</font>::<font color="#000000">110</font> blowfish.wg0 blowfish.wg0.wan.buetow.org
+fd42:beef:cafe:<font color="#000000">2</font>::<font color="#000000">111</font> fishfinger.wg0 fishfinger.wg0.wan.buetow.org
+fd42:beef:cafe:<font color="#000000">2</font>::<font color="#000000">200</font> earth.wg0 earth.wg0.wan.buetow.org
+fd42:beef:cafe:<font color="#000000">2</font>::<font color="#000000">201</font> pixel7pro.wg0 pixel7pro.wg0.wan.buetow.org
END
</pre>
<br />
@@ -10087,6 +10135,7 @@ hosts:
wg0:
domain: &#39;wg0.wan.buetow.org&#39;
ip: &#39;192.168.2.130&#39;
+ ipv6: &#39;fd42:beef:cafe:2::130&#39;
exclude_peers:
- earth
- pixel7pro
@@ -10106,6 +10155,7 @@ hosts:
wg0:
domain: &#39;wg0.wan.buetow.org&#39;
ip: &#39;192.168.2.120&#39;
+ ipv6: &#39;fd42:beef:cafe:2::120&#39;
exclude_peers:
- earth
- pixel7pro
@@ -10125,6 +10175,7 @@ hosts:
wg0:
domain: &#39;wg0.wan.buetow.org&#39;
ip: &#39;192.168.2.110&#39;
+ ipv6: &#39;fd42:beef:cafe:2::110&#39;
exclude_peers:
- earth
- pixel7pro
@@ -10142,6 +10193,7 @@ hosts:
wg0:
domain: &#39;wg0.wan.buetow.org&#39;
ip: &#39;192.168.2.111&#39;
+ ipv6: &#39;fd42:beef:cafe:2::111&#39;
exclude_peers:
- earth
- pixel7pro
@@ -10150,6 +10202,7 @@ hosts:
wg0:
domain: &#39;wg0.wan.buetow.org&#39;
ip: &#39;192.168.2.200&#39;
+ ipv6: &#39;fd42:beef:cafe:2::200&#39;
exclude_peers:
- f0
- f1
@@ -10163,6 +10216,7 @@ hosts:
wg0:
domain: &#39;wg0.wan.buetow.org&#39;
ip: &#39;192.168.2.201&#39;
+ ipv6: &#39;fd42:beef:cafe:2::201&#39;
exclude_peers:
- f0
- f1
@@ -10502,6 +10556,225 @@ http://www.gnu.org/software/src-highlite -->
<br />
<span>The service is disabled from auto-start so the VPN is only active when manually started. This allows selective VPN usage based on need.</span><br />
<br />
+<h2 style='display: inline' id='adding-ipv6-support-to-the-mesh'>Adding IPv6 support to the mesh</h2><br />
+<br />
+<span>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.</span><br />
+<br />
+<h3 style='display: inline' id='ipv6-addressing-scheme'>IPv6 addressing scheme</h3><br />
+<br />
+<span>We use ULA (Unique Local Address) private IPv6 space, analogous to RFC1918 private IPv4 addresses:</span><br />
+<br />
+<ul>
+<li>Prefix: <span class='inlinecode'>fd42:beef:cafe::/48</span></li>
+<li>Subnet: <span class='inlinecode'>fd42:beef:cafe:2::/64</span> (wg0 interfaces)</li>
+</ul><br />
+<span>All hosts receive dual-stack addresses:</span><br />
+<br />
+<pre>
+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)
+</pre>
+<br />
+<h3 style='display: inline' id='updating-the-mesh-generator-for-ipv6'>Updating the mesh generator for IPv6</h3><br />
+<br />
+<span>The mesh generator required two modifications to support dual-stack configurations:</span><br />
+<br />
+<span>**1. Address generation (<span class='inlinecode'>address</span> method)**</span><br />
+<br />
+<span>The generator now outputs multiple <span class='inlinecode'>Address</span> directives when IPv6 is present:</span><br />
+<br />
+<!-- Generator: GNU source-highlight 3.1.9
+by Lorenzo Bettini
+http://www.lorenzobettini.it
+http://www.gnu.org/software/src-highlite -->
+<pre><b><u><font color="#000000">def</font></u></b> address
+ <b><u><font color="#000000">return</font></u></b> <font color="#808080">'# No Address = ... for OpenBSD here'</font> <b><u><font color="#000000">if</font></u></b> hosts[myself][<font color="#808080">'os'</font>] == <font color="#808080">'OpenBSD'</font>
+
+ ipv4 = hosts[myself][<font color="#808080">'wg0'</font>][<font color="#808080">'ip'</font>]
+ ipv6 = hosts[myself][<font color="#808080">'wg0'</font>][<font color="#808080">'ipv6'</font>]
+
+ <i><font color="silver"># WireGuard supports multiple Address directives for dual-stack</font></i>
+ <b><u><font color="#000000">if</font></u></b> ipv6
+ <font color="#808080">"Address = #{ipv4}\nAddress = #{ipv6}/64"</font>
+ <b><u><font color="#000000">else</font></u></b>
+ <font color="#808080">"Address = #{ipv4}"</font>
+ <b><u><font color="#000000">end</font></u></b>
+<b><u><font color="#000000">end</font></u></b>
+</pre>
+<br />
+<span>**2. AllowedIPs generation (<span class='inlinecode'>peers</span> method)**</span><br />
+<br />
+<span>For mesh peers, both IPv4 and IPv6 addresses are included in AllowedIPs:</span><br />
+<br />
+<!-- Generator: GNU source-highlight 3.1.9
+by Lorenzo Bettini
+http://www.lorenzobettini.it
+http://www.gnu.org/software/src-highlite -->
+<pre><b><u><font color="#000000">if</font></u></b> is_roaming
+ allowed_ips = <font color="#808080">'0.0.0.0/0, ::/0'</font>
+<b><u><font color="#000000">else</font></u></b>
+ <i><font color="silver"># For mesh peers, allow both IPv4 and IPv6 if present</font></i>
+ ipv4 = data[<font color="#808080">'wg0'</font>][<font color="#808080">'ip'</font>]
+ ipv6 = data[<font color="#808080">'wg0'</font>][<font color="#808080">'ipv6'</font>]
+ allowed_ips = ipv6 ? <font color="#808080">"#{ipv4}/32, #{ipv6}/128"</font> : <font color="#808080">"#{ipv4}/32"</font>
+<b><u><font color="#000000">end</font></u></b>
+</pre>
+<br />
+<span>Roaming clients keep <span class='inlinecode'>AllowedIPs = 0.0.0.0/0, ::/0</span> to route all traffic (IPv4 and IPv6) through the VPN.</span><br />
+<br />
+<h3 style='display: inline' id='ipv6-nat-on-openbsd-gateways'>IPv6 NAT on OpenBSD gateways</h3><br />
+<br />
+<span>To allow roaming clients to access the internet via IPv6, we added NAT66 rules to the OpenBSD gateways&#39; <span class='inlinecode'>pf.conf</span>:</span><br />
+<br />
+<pre>
+# 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
+</pre>
+<br />
+<span>OpenBSD&#39;s PF firewall supports IPv6 NAT with the same syntax as IPv4, using NPTv6 (RFC 6296) to translate the ULA addresses to the gateway&#39;s public IPv6 address.</span><br />
+<br />
+<h3 style='display: inline' id='manual-openbsd-interface-configuration'>Manual OpenBSD interface configuration</h3><br />
+<br />
+<span>Since OpenBSD doesn&#39;t use the <span class='inlinecode'>Address</span> directive in WireGuard configs, IPv6 must be manually configured on the wg0 interfaces. On <span class='inlinecode'>blowfish</span>:</span><br />
+<br />
+<!-- Generator: GNU source-highlight 3.1.9
+by Lorenzo Bettini
+http://www.lorenzobettini.it
+http://www.gnu.org/software/src-highlite -->
+<pre>rex@blowfish:~ $ doas vi /etc/hostname.wg0
+</pre>
+<br />
+<span>Add the IPv6 address (note the order - IPv6 must be configured before <span class='inlinecode'>up</span>):</span><br />
+<br />
+<pre>
+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
+</pre>
+<br />
+<span>**Important**: The IPv6 address must be specified before the <span class='inlinecode'>up</span> directive. This ensures the interface has both addresses configured before WireGuard peers are loaded.</span><br />
+<br />
+<span>Apply the configuration:</span><br />
+<br />
+<!-- Generator: GNU source-highlight 3.1.9
+by Lorenzo Bettini
+http://www.lorenzobettini.it
+http://www.gnu.org/software/src-highlite -->
+<pre>rex@blowfish:~ $ doas sh /etc/netstart wg0
+rex@blowfish:~ $ ifconfig wg0 | grep inet6
+inet6 fd42:beef:cafe:<font color="#000000">2</font>::<font color="#000000">110</font> prefixlen <font color="#000000">64</font>
+</pre>
+<br />
+<span>Repeat for <span class='inlinecode'>fishfinger</span> with address <span class='inlinecode'>fd42:beef:cafe:2::111</span>.</span><br />
+<br />
+<span>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.</span><br />
+<br />
+<h3 style='display: inline' id='verifying-dual-stack-connectivity'>Verifying dual-stack connectivity</h3><br />
+<br />
+<span>After regenerating and deploying the configurations, both IPv4 and IPv6 work across the mesh:</span><br />
+<br />
+<!-- Generator: GNU source-highlight 3.1.9
+by Lorenzo Bettini
+http://www.lorenzobettini.it
+http://www.gnu.org/software/src-highlite -->
+<pre><i><font color="silver"># From r0 (Rocky Linux VM)</font></i>
+root@r0:~ <i><font color="silver"># ping -c 2 192.168.2.130 # IPv4 to f0</font></i>
+<font color="#000000">64</font> bytes from <font color="#000000">192.168</font>.<font color="#000000">2.130</font>: icmp_seq=<font color="#000000">1</font> ttl=<font color="#000000">64</font> time=<font color="#000000">2.12</font> ms
+<font color="#000000">64</font> bytes from <font color="#000000">192.168</font>.<font color="#000000">2.130</font>: icmp_seq=<font color="#000000">2</font> ttl=<font color="#000000">64</font> time=<font color="#000000">0.681</font> ms
+
+root@r0:~ <i><font color="silver"># ping6 -c 2 fd42:beef:cafe:2::130 # IPv6 to f0</font></i>
+<font color="#000000">64</font> bytes from fd42:beef:cafe:<font color="#000000">2</font>::<font color="#000000">130</font>: icmp_seq=<font color="#000000">1</font> ttl=<font color="#000000">64</font> time=<font color="#000000">2.16</font> ms
+<font color="#000000">64</font> bytes from fd42:beef:cafe:<font color="#000000">2</font>::<font color="#000000">130</font>: icmp_seq=<font color="#000000">2</font> ttl=<font color="#000000">64</font> time=<font color="#000000">0.909</font> ms
+</pre>
+<br />
+<span>The dual-stack configuration is backward compatible—hosts without the <span class='inlinecode'>ipv6</span> field in the YAML configuration will continue to generate IPv4-only configs.</span><br />
+<br />
+<h3 style='display: inline' id='benefits-of-dual-stack'>Benefits of dual-stack</h3><br />
+<br />
+<span>Adding IPv6 to the mesh network provides:</span><br />
+<br />
+<ul>
+<li>**Future-proofing**: Ready for IPv6-only services and networks</li>
+<li>**Compatibility**: Dual-stack maintains full IPv4 compatibility</li>
+<li>**Learning**: Hands-on experience with IPv6 networking</li>
+<li>**Flexibility**: Roaming clients can access both IPv4 and IPv6 internet resources</li>
+</ul><br />
+<h2 style='display: inline' id='manual-gateway-failover-for-roaming-clients'>Manual gateway failover for roaming clients</h2><br />
+<br />
+<span>WireGuard doesn&#39;t automatically failover between multiple peers with identical <span class='inlinecode'>AllowedIPs</span> routes. When both gateways (blowfish and fishfinger) are configured with <span class='inlinecode'>AllowedIPs = 0.0.0.0/0, ::/0</span>, WireGuard uses the first peer with a recent handshake. If that gateway goes down, traffic won&#39;t automatically switch to the backup.</span><br />
+<br />
+<span>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.</span><br />
+<br />
+<h3 style='display: inline' id='configuration-files-for-pixel7pro-phone'>Configuration files for pixel7pro (phone)</h3><br />
+<br />
+<span>Two separate configs in <span class='inlinecode'>/home/paul/git/wireguardmeshgenerator/dist/pixel7pro/etc/wireguard/</span>:</span><br />
+<br />
+<ul>
+<li>**wg0-blowfish.conf** - Routes all traffic through blowfish gateway (23.88.35.144)</li>
+<li>**wg0-fishfinger.conf** - Routes all traffic through fishfinger gateway (46.23.94.99)</li>
+</ul><br />
+<h3 style='display: inline' id='configuration-files-for-earth-laptop'>Configuration files for earth (laptop)</h3><br />
+<br />
+<span>Two separate configs in <span class='inlinecode'>/home/paul/git/wireguardmeshgenerator/dist/earth/etc/wireguard/</span>:</span><br />
+<br />
+<ul>
+<li>**wg0-blowfish.conf** - Routes all traffic through blowfish gateway</li>
+<li>**wg0-fishfinger.conf** - Routes all traffic through fishfinger gateway</li>
+</ul><br />
+<h3 style='display: inline' id='using-manual-failover-on-android'>Using manual failover on Android</h3><br />
+<br />
+<span>On the pixel7pro phone, import both QR codes using the WireGuard app to create two separate tunnel profiles:</span><br />
+<br />
+<!-- Generator: GNU source-highlight 3.1.9
+by Lorenzo Bettini
+http://www.lorenzobettini.it
+http://www.gnu.org/software/src-highlite -->
+<pre><i><font color="silver"># Generate QR codes</font></i>
+qrencode -t ansiutf8 &lt; dist/pixel7pro/etc/wireguard/wg<font color="#000000">0</font>-blowfish.conf
+qrencode -t ansiutf8 &lt; dist/pixel7pro/etc/wireguard/wg<font color="#000000">0</font>-fishfinger.conf
+</pre>
+<br />
+<span>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.</span><br />
+<br />
+<h3 style='display: inline' id='using-manual-failover-on-linux'>Using manual failover on Linux</h3><br />
+<br />
+<span>On the earth laptop, copy both configs and use systemd to switch between them:</span><br />
+<br />
+<!-- Generator: GNU source-highlight 3.1.9
+by Lorenzo Bettini
+http://www.lorenzobettini.it
+http://www.gnu.org/software/src-highlite -->
+<pre><i><font color="silver"># Install both configurations</font></i>
+sudo cp dist/earth/etc/wireguard/wg<font color="#000000">0</font>-blowfish.conf /etc/wireguard/
+sudo cp dist/earth/etc/wireguard/wg<font color="#000000">0</font>-fishfinger.conf /etc/wireguard/
+
+<i><font color="silver"># Start with blowfish gateway</font></i>
+sudo systemctl start wg-quick@wg0-blowfish.service
+
+<i><font color="silver"># To switch to fishfinger gateway</font></i>
+sudo systemctl stop wg-quick@wg0-blowfish.service
+sudo systemctl start wg-quick@wg0-fishfinger.service
+</pre>
+<br />
+<span>This approach provides explicit control over which gateway handles roaming client traffic, useful when one gateway needs maintenance or experiences connectivity issues.</span><br />
+<br />
<h2 style='display: inline' id='happy-wireguard-ing'>Happy WireGuard-ing</h2><br />
<br />
<span>All is set up now. E.g. on <span class='inlinecode'>f0</span>:</span><br />
diff --git a/index.gmi b/index.gmi
index 38898233..dad505ed 100644
--- a/index.gmi
+++ b/index.gmi
@@ -1,6 +1,6 @@
# 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.gmi b/uptime-stats.gmi
index 596fe5e8..fe548d7f 100644
--- a/uptime-stats.gmi
+++ b/uptime-stats.gmi
@@ -1,6 +1,6 @@
# 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.
@@ -34,12 +34,12 @@ Boots is the total number of host boots over the entire lifespan.
| 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 |
+-----+----------------+-------+-------------------------------+
```
@@ -54,7 +54,7 @@ Uptime is the total uptime of a host over the entire lifespan.
+-----+----------------+-----------------------------+-----------------------------------+
| 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 |
@@ -65,7 +65,7 @@ Uptime is the total uptime of a host over the entire lifespan.
| 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 |
@@ -99,7 +99,7 @@ Score is calculated by combining all other metrics.
| 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 |
@@ -149,7 +149,7 @@ Lifespan is the total uptime + the total downtime of a host.
| 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 |
@@ -194,8 +194,8 @@ Boots is the total number of host boots over the entire lifespan.
| 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 |
+-----+----------------+-------+
```
@@ -211,14 +211,14 @@ Uptime is the total uptime of a host over the entire lifespan.
| 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 |
@@ -242,22 +242,22 @@ Score is calculated by combining all other metrics.
| 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 |
+-----+----------------+-------+
```
@@ -285,10 +285,10 @@ Uptime is the total uptime of a host over the entire lifespan.
+-----+------------+-----------------------------+
| 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 |
+-----+------------+-----------------------------+
```
@@ -301,10 +301,10 @@ Score is calculated by combining all other metrics.
+-----+------------+-------+
| Pos | KernelName | Score |
+-----+------------+-------+
-| 1. | *Linux | 1882 |
+| 1. | *Linux | 1883 |
| 2. | *FreeBSD | 912 |
| 3. | *OpenBSD | 557 |
-| 4. | *Darwin | 342 |
+| 4. | *Darwin | 343 |
| 5. | NetBSD | 0 |
+-----+------------+-------+
```