summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorPaul Buetow <paul@buetow.org>2026-02-05 17:44:58 +0200
committerPaul Buetow <paul@buetow.org>2026-02-05 17:44:58 +0200
commite1cc32198c8af69f8716020171149d9ad4c6b31a (patch)
tree7a622e2514e4c3c00456beb8b98ce3a5d6700747
parentb8fcb457c9ab0634b4518276bfd6dfb837ea872b (diff)
Update content for gemtext
-rw-r--r--about/resources.gmi204
-rw-r--r--gemfeed/2025-10-02-f3s-kubernetes-with-freebsd-part-7.gmi240
-rw-r--r--gemfeed/atom.xml277
-rw-r--r--index.gmi2
-rw-r--r--uptime-stats.gmi2
5 files changed, 620 insertions, 105 deletions
diff --git a/about/resources.gmi b/about/resources.gmi
index d8a18025..25a90f47 100644
--- a/about/resources.gmi
+++ b/about/resources.gmi
@@ -35,110 +35,110 @@ You won't find any links on this site because, over time, the links will break.
In random order:
-* Raku Recipes; J.J. Merelo; Apress
-* Think Raku (aka Think Perl 6); Laurent Rosenfeld, Allen B. Downey; O'Reilly
+* The Go Programming Language; Alan A. A. Donovan; Addison-Wesley Professional
+* Distributed Systems: Principles and Paradigms; Andrew S. Tanenbaum; Pearson
+* The KCNA (Kubernetes and Cloud Native Associate) Book; Nigel Poulton
+* Learn You a Haskell for Great Good!; Miran Lipovaca; No Starch Press
+* Higher Order Perl; Mark Dominus; Morgan Kaufmann
* Leanring eBPF; Liz Rice; O'Reilly
-* The Kubernetes Book; Nigel Poulton; Unabridged Audiobook
-* 97 things every SRE should know; Emil Stolarsky, Jaime Woo; O'Reilly
-* Systems Performance Tuning; Gian-Paolo D. Musumeci and others...; O'Reilly
-* Ultimate Go Notebook; Bill Kennedy
-* Effective awk programming; Arnold Robbins; O'Reilly
-* Seeking SRE: Conversations About Running Production Systems at Scale; David N. Blank-Edelman; eBook
-* Hands-on Infrastructure Monitoring with Prometheus; Joel Bastos, Pedro Araujo; Packt
-* The Docker Book; James Turnbull; Kindle
-* C++ Programming Language; Bjarne Stroustrup;
* Systemprogrammierung in Go; Frank Müller; dpunkt
-* Learn You a Haskell for Great Good!; Miran Lipovaca; No Starch Press
-* The Go Programming Language; Alan A. A. Donovan; Addison-Wesley Professional
+* Seeking SRE: Conversations About Running Production Systems at Scale; David N. Blank-Edelman; eBook
+* Go Brain Teasers - Exercise Your Mind; Miki Tebeka; The Pragmatic Programmers
+* Systems Performance Tuning; Gian-Paolo D. Musumeci and others...; O'Reilly
+* Object-Oriented Programming with ANSI-C; Axel-Tobias Schreiner
* Learn You Some Erlang for Great Good; Fred Herbert; No Starch Press
-* Tmux 2: Productive Mouse-free Development; Brain P. Hogan; The Pragmatic Programmers
-* Raku Fundamentals; Moritz Lenz; Apress
-* Modern Perl; Chromatic ; Onyx Neon Press
-* Programming Perl aka "The Camel Book"; Tom Christiansen, brian d foy, Larry Wall & Jon Orwant; O'Reilly
* The DevOps Handbook; Gene Kim, Jez Humble, Patrick Debois, John Willis; Audible
-* 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
+* 97 things every SRE should know; Emil Stolarsky, Jaime Woo; O'Reilly
* Developing Games in Java; David Brackeen and others...; New Riders
-* Terraform Cookbook; Mikael Krief; Packt Publishing
-* DNS and BIND; Cricket Liu; O'Reilly
-* Distributed Systems: Principles and Paradigms; Andrew S. Tanenbaum; Pearson
-* Effective Java; Joshua Bloch; Addison-Wesley Professional
-* Pro Puppet; James Turnbull, Jeffrey McCune; Apress
-* Java ist auch eine Insel; Christian Ullenboom;
+* Programming Ruby 3.3 (5th Edition); Noel Rappin, with Dave Thomas; The Pragmatic Bookshelf
+* The Kubernetes Book; Nigel Poulton; Unabridged Audiobook
+* Hands-on Infrastructure Monitoring with Prometheus; Joel Bastos, Pedro Araujo; Packt
+* Raku Recipes; J.J. Merelo; Apress
+* Modern Perl; Chromatic ; Onyx Neon Press
* Funktionale Programmierung; Peter Pepper; Springer
-* Concurrency in Go; Katherine Cox-Buday; O'Reilly
-* Kubernetes Cookbook; Sameer Naik, Sébastien Goasguen, Jonathan Michaux; O'Reilly
+* Clusterbau mit Linux-HA; Michael Schwartzkopff; O'Reilly
+* Think Raku (aka Think Perl 6); Laurent Rosenfeld, Allen B. Downey; O'Reilly
+* Ultimate Go Notebook; Bill Kennedy
+* Effective awk programming; Arnold Robbins; O'Reilly
+* Terraform Cookbook; Mikael Krief; Packt Publishing
+* Chaos Engineering - System Resiliency in Practice; Casey Rosenthal and Nora Jones; eBook
* 21st Century C: C Tips from the New School; Ben Klemens; O'Reilly
-* Amazon Web Services in Action; Michael Wittig and Andreas Wittig; Manning Publications
-* The Pragmatic Programmer; David Thomas; Addison-Wesley
-* Higher Order Perl; Mark Dominus; Morgan Kaufmann
-* DevOps And Site Reliability Engineering Handbook; Stephen Fleming; Audible
-* The KCNA (Kubernetes and Cloud Native Associate) Book; Nigel Poulton
-* Polished Ruby Programming; Jeremy Evans; Packt Publishing
-* Object-Oriented Programming with ANSI-C; Axel-Tobias Schreiner
-* Site Reliability Engineering; How Google runs production systems; O'Reilly
+* Data Science at the Command Line; Jeroen Janssens; O'Reilly
+* Concurrency in Go; Katherine Cox-Buday; O'Reilly
+* Effective Java; Joshua Bloch; Addison-Wesley Professional
+* DNS and BIND; Cricket Liu; O'Reilly
* Perl New Features; Joshua McAdams, brian d foy; Perl School
-* Programming Ruby 3.3 (5th Edition); Noel Rappin, with Dave Thomas; The Pragmatic Bookshelf
+* Polished Ruby Programming; Jeremy Evans; Packt Publishing
+* Programming Perl aka "The Camel Book"; Tom Christiansen, brian d foy, Larry Wall & Jon Orwant; O'Reilly
+* C++ Programming Language; Bjarne Stroustrup;
+* The Docker Book; James Turnbull; Kindle
+* Tmux 2: Productive Mouse-free Development; Brain P. Hogan; The Pragmatic Programmers
* 100 Go Mistakes and How to Avoid Them; Teiva Harsanyi; Manning Publications
-* Chaos Engineering - System Resiliency in Practice; Casey Rosenthal and Nora Jones; eBook
-* Clusterbau mit Linux-HA; Michael Schwartzkopff; O'Reilly
-* Go Brain Teasers - Exercise Your Mind; Miki Tebeka; The Pragmatic Programmers
-* Data Science at the Command Line; Jeroen Janssens; O'Reilly
+* DevOps And Site Reliability Engineering Handbook; Stephen Fleming; Audible
+* 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
+* Kubernetes Cookbook; Sameer Naik, Sébastien Goasguen, Jonathan Michaux; O'Reilly
+* Site Reliability Engineering; How Google runs production systems; O'Reilly
+* The Pragmatic Programmer; David Thomas; Addison-Wesley
+* Java ist auch eine Insel; Christian Ullenboom;
+* Amazon Web Services in Action; Michael Wittig and Andreas Wittig; Manning Publications
+* Raku Fundamentals; Moritz Lenz; Apress
+* Pro Puppet; James Turnbull, Jeffrey McCune; Apress
## 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:
-* BPF Performance Tools - Linux System and Application Observability, Brendan Gregg; Addison Wesley
-* Implementing Service Level Objectives; Alex Hidalgo; O'Reilly
* Go: Design Patterns for Real-World Projects; Mat Ryer; Packt
+* Implementing Service Level Objectives; Alex Hidalgo; O'Reilly
+* 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
-* Algorithms; Robert Sedgewick, Kevin Wayne; Addison Wesley
-* Groovy Kurz & Gut; Joerg Staudemeier; O'Reilly
* Relayd and Httpd Mastery; Michael W Lucas
-* The Linux Programming Interface; Michael Kerrisk; No Starch Press
+* Groovy Kurz & Gut; Joerg Staudemeier; O'Reilly
+* Algorithms; Robert Sedgewick, Kevin Wayne; Addison Wesley
## Self-development and soft-skills books
In random order:
-* Who Moved My Cheese?; Dr. Spencer Johnson; Vermilion
-* Never Split the Difference; Chris Voss, Tahl Raz; Random House Business
-* The Software Engineer's Guidebook: Navigating senior, tech lead, and staff engineer positions at tech companies and startups; Gergely Orosz; Audiobook
-* So Good They Can't Ignore You; Cal Newport; Business Plus
-* The Joy of Missing Out; Christina Crook; New Society Publishers
-* Ultralearning; Scott Young; Thorsons
-* Eat That Frog!; Brian Tracy; Hodder Paperbacks
-* The Phoenix Project - A Novel About IT, DevOps, and Helping your Business Win; Gene Kim and Kevin Behr; Trade Select
+* The Off Switch; Mark Cropley; Virgin Books (RE-READ 1ST TIME)
+* The Power of Now; Eckhard Tolle; Yellow Kite
* The Good Enough Job; Simone Stolzoff; Ebury Edge
-* The 7 Habits Of Highly Effective People; Stephen R. Covey; Simon & Schuster UK
-* Time Management for System Administrators; Thomas A. Limoncelli; O'Reilly
-* Getting Things Done; David Allen
-* Search Inside Yourself - The Unexpected path to Achieving Success, Happiness (and World Peace); Chade-Meng Tan, Daniel Goleman, Jon Kabat-Zinn; HarperOne
-* Stop starting, start finishing; Arne Roock; Lean-Kanban University
-* The Daily Stoic; Ryan Holiday, Stephen Hanselman; Profile Books
-* Consciousness: A Very Short Introduction; Susan Blackmore; Oxford Uiversity Press
+* Solve for Happy; Mo Gawdat (RE-READ 1ST TIME)
* 101 Essays that change the way you think; Brianna Wiest; Audiobook
-* Digital Minimalism; Cal Newport; Portofolio Penguin
-* The Off Switch; Mark Cropley; Virgin Books (RE-READ 1ST TIME)
-* Ultralearning; Anna Laurent; Self-published via Amazon
-* The Complete Software Developer's Career Guide; John Sonmez; Unabridged Audiobook
+* Consciousness: A Very Short Introduction; Susan Blackmore; Oxford Uiversity Press
+* Never Split the Difference; Chris Voss, Tahl Raz; Random House Business
+* Eat That Frog!; Brian Tracy; Hodder Paperbacks
+* Deep Work; Cal Newport; Piatkus
* The Courage to Be Disliked; Ichiro Kishimi and Fumitake Koga; Audiobook
-* Influence without Authority; A. Cohen, D. Bradford; Wiley
-* Slow Productivity; Cal Newport; Penguin Random House
-* Meditation for Mortals, Oliver Burkeman, Audiobook
-* Soft Skills; John Sommez; Manning Publications
+* The Complete Software Developer's Career Guide; John Sonmez; Unabridged Audiobook
+* Ultralearning; Anna Laurent; Self-published via Amazon
* Psycho-Cybernetics; Maxwell Maltz; Perigee Books
* Eat That Frog; Brian Tracy
-* The Bullet Journal Method; Ryder Carroll; Fourth Estate
-* Deep Work; Cal Newport; Piatkus
+* Coders at Work - Reflections on the craft of programming, Peter Seibel and Mitchell Dorian et al., Audiobook
+* Slow Productivity; Cal Newport; Penguin Random House
+* Time Management for System Administrators; Thomas A. Limoncelli; O'Reilly
+* So Good They Can't Ignore You; Cal Newport; Business Plus
* 97 Things Every Engineering Manager Should Know; Camille Fournier; Audiobook
-* The Power of Now; Eckhard Tolle; Yellow Kite
+* Soft Skills; John Sommez; Manning Publications
+* The Joy of Missing Out; Christina Crook; New Society Publishers
+* The Obstacle Is The Way; Ryan Holiday; Profile Books Ltd
* Staff Engineer: Leadership beyond the management track; Will Larson; Audiobook
* Atomic Habits; James Clear; Random House Business
-* The Obstacle Is The Way; Ryan Holiday; Profile Books Ltd
+* The Bullet Journal Method; Ryder Carroll; Fourth Estate
+* The Daily Stoic; Ryan Holiday, Stephen Hanselman; Profile Books
+* Search Inside Yourself - The Unexpected path to Achieving Success, Happiness (and World Peace); Chade-Meng Tan, Daniel Goleman, Jon Kabat-Zinn; HarperOne
+* The Software Engineer's Guidebook: Navigating senior, tech lead, and staff engineer positions at tech companies and startups; Gergely Orosz; Audiobook
* Buddah and Einstein walk into a Bar; Guy Joseph Ale, Claire Bloom; Blackstone Publishing
-* Coders at Work - Reflections on the craft of programming, Peter Seibel and Mitchell Dorian et al., Audiobook
-* Solve for Happy; Mo Gawdat (RE-READ 1ST TIME)
+* Stop starting, start finishing; Arne Roock; Lean-Kanban University
+* The Phoenix Project - A Novel About IT, DevOps, and Helping your Business Win; Gene Kim and Kevin Behr; Trade Select
+* Ultralearning; Scott Young; Thorsons
+* Influence without Authority; A. Cohen, D. Bradford; Wiley
+* Who Moved My Cheese?; Dr. Spencer Johnson; Vermilion
+* The 7 Habits Of Highly Effective People; Stephen R. Covey; Simon & Schuster UK
+* Getting Things Done; David Allen
+* Meditation for Mortals, Oliver Burkeman, Audiobook
+* Digital Minimalism; Cal Newport; Portofolio Penguin
=> ../notes/index.gmi Here are notes of mine for some of the books
@@ -146,22 +146,22 @@ In random order:
Some of these were in-person with exams; others were online learning lectures only. In random order:
-* Apache Tomcat Best Practises; 3-day on-site training
-* Algorithms Video Lectures; Robert Sedgewick; O'Reilly Online
-* The Ultimate Kubernetes Bootcamp; School of Devops; O'Reilly Online
* 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)
-* Developing IaC with Terraform (with Live Lessons); O'Reilly Online
* Ultimate Go Programming; Bill Kennedy; O'Reilly Online
-* Functional programming lecture; Remote University of Hagen
-* Structure and Interpretation of Computer Programs; Harold Abelson and more...;
+* Linux Security and Isolation APIs Training; Michael Kerrisk; 3-day on-site training
+* AWS Immersion Day; Amazon; 1-day interactive online training
+* Scripting Vim; Damian Conway; O'Reilly Online
* MySQL Deep Dive Workshop; 2-day on-site training
-* Protocol buffers; O'Reilly Online
+* Functional programming lecture; Remote University of Hagen
+* Apache Tomcat Best Practises; 3-day on-site training
+* The Ultimate Kubernetes Bootcamp; School of Devops; O'Reilly Online
+* Algorithms Video Lectures; Robert Sedgewick; 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
-* AWS Immersion Day; Amazon; 1-day interactive online training
+* Developing IaC with Terraform (with Live Lessons); O'Reilly Online
* F5 Loadbalancers Training; 2-day on-site training; F5, Inc.
+* Structure and Interpretation of Computer Programs; Harold Abelson and more...;
+* Protocol buffers; O'Reilly Online
* The Well-Grounded Rubyist Video Edition; David. A. Black; O'Reilly Online
-* Linux Security and Isolation APIs Training; Michael Kerrisk; 3-day on-site training
## Technical guides
@@ -178,57 +178,57 @@ These are not whole books, but guides (smaller or larger) which I found very use
In random order:
* Deep Questions with Cal Newport
-* Maintainable
-* Fallthrough [Golang]
-* Wednesday Wisdom
* The Pragmatic Engineer Podcast
+* Pratical AI
+* Wednesday Wisdom
* The Changelog Podcast(s)
-* Modern Mentor
+* Backend Banter
+* BSD Now [BSD]
+* Dev Interrupted
* Cup o' Go [Golang]
+* The ProdCast (Google SRE Podcast)
+* Modern Mentor
+* Fallthrough [Golang]
* Hidden Brain
-* Dev Interrupted
-* BSD Now [BSD]
-* Pratical AI
-* Backend Banter
* Fork Around And Find Out
-* The ProdCast (Google SRE Podcast)
+* Maintainable
### 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.
* Ship It (predecessor of Fork Around And Find Out)
-* Go Time (predecessor of fallthrough)
+* Java Pub House
* FLOSS weekly
* CRE: Chaosradio Express [german]
* Modern Mentor
-* Java Pub House
+* Go Time (predecessor of fallthrough)
## 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)
+* The Pragmatic Engineer
* Ruby Weekly
-* The Valuable Dev
+* Golang Weekly
* Register Spill
+* Andreas Brandhorst Newsletter (Sci-Fi author)
* Applied Go Weekly Newsletter
-* The Imperfectionist
* Changelog News
-* Golang Weekly
* VK Newsletter
-* The Pragmatic Engineer
-* byteSizeGo
+* The Valuable Dev
* Monospace Mentor
+* The Imperfectionist
+* byteSizeGo
## 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
* LWN (online only)
* Linux User
-* Linux Magazine
-* freeX (not published anymore)
# Formal education
diff --git a/gemfeed/2025-10-02-f3s-kubernetes-with-freebsd-part-7.gmi b/gemfeed/2025-10-02-f3s-kubernetes-with-freebsd-part-7.gmi
index 1156b0a7..45b17dd7 100644
--- a/gemfeed/2025-10-02-f3s-kubernetes-with-freebsd-part-7.gmi
+++ b/gemfeed/2025-10-02-f3s-kubernetes-with-freebsd-part-7.gmi
@@ -32,6 +32,7 @@ This is the seventh blog post about the f3s series for my self-hosting demands i
* ⇢ ⇢ ⇢ OpenBSD relayd configuration
* ⇢ ⇢ ⇢ Automatic failover when f3s cluster is down
* ⇢ ⇢ ⇢ OpenBSD httpd fallback configuration
+* ⇢ ⇢ Exposing services via LAN ingress
* ⇢ ⇢ Deploying the private Docker image registry
* ⇢ ⇢ ⇢ Prepare the NFS-backed storage
* ⇢ ⇢ ⇢ Install (or upgrade) the chart
@@ -813,6 +814,245 @@ This approach provides several benefits:
This fallback mechanism has proven invaluable during maintenance windows and unexpected outages, ensuring that users always get a response even when the home lab is offline.
+## Exposing services via LAN ingress
+
+In addition to external access through the OpenBSD relays, services can also be exposed on the local network using LAN-specific ingresses. This is useful for accessing services from within the home network without going through the internet, reducing latency and providing an alternative path if the external relays are unavailable.
+
+The LAN ingress architecture leverages the existing FreeBSD CARP (Common Address Redundancy Protocol) failover infrastructure that's already in place for NFS-over-TLS (see Part 5). Instead of deploying MetalLB or another LoadBalancer implementation, we reuse the CARP virtual IP (`192.168.1.138`) by adding HTTP/HTTPS forwarding alongside the existing stunnel service on port 2323.
+
+*Architecture overview*:
+
+The LAN access path differs from external access:
+
+**External access (*.f3s.foo.zone):**
+```
+Internet → OpenBSD relayd (TLS termination, Let's Encrypt)
+ → WireGuard tunnel
+ → k3s Traefik :80 (HTTP)
+ → Service
+```
+
+**LAN access (*.f3s.lan.foo.zone):**
+```
+LAN → FreeBSD CARP VIP (192.168.1.138)
+ → FreeBSD relayd (TCP forwarding)
+ → k3s Traefik :443 (TLS termination, cert-manager)
+ → Service
+```
+
+The key architectural decisions:
+
+* FreeBSD `relayd` performs pure TCP forwarding (Layer 4) for ports 80 and 443, not TLS termination
+* Traefik inside k3s handles TLS offloading using certificates from cert-manager
+* Self-signed CA for LAN domains (no external dependencies)
+* CARP provides automatic failover between f0 and f1
+* No code changes to applications—just add a LAN ingress resource
+
+*Installing cert-manager*:
+
+First, install cert-manager to handle certificate lifecycle management for LAN services. The installation is automated with a Justfile:
+
+=> https://codeberg.org/snonux/conf/src/branch/master/f3s/cert-manager codeberg.org/snonux/conf/f3s/cert-manager
+
+```sh
+$ cd conf/f3s/cert-manager
+$ just install
+kubectl apply -f cert-manager.yaml
+# ... cert-manager CRDs and resources created ...
+kubectl apply -f self-signed-issuer.yaml
+clusterissuer.cert-manager.io/selfsigned-issuer created
+clusterissuer.cert-manager.io/selfsigned-ca-issuer created
+kubectl apply -f ca-certificate.yaml
+certificate.cert-manager.io/selfsigned-ca created
+kubectl apply -f wildcard-certificate.yaml
+certificate.cert-manager.io/f3s-lan-wildcard created
+```
+
+This creates:
+
+* A self-signed ClusterIssuer
+* A CA certificate (`f3s-lan-ca`) valid for 10 years
+* A CA-signed ClusterIssuer
+* A wildcard certificate (`*.f3s.lan.foo.zone`) valid for 90 days with automatic renewal
+
+Verify the certificates:
+
+```sh
+$ kubectl get certificate -n cert-manager
+NAME READY SECRET AGE
+f3s-lan-wildcard True f3s-lan-tls 5m
+selfsigned-ca True selfsigned-ca-secret 5m
+```
+
+The wildcard certificate (`f3s-lan-tls`) needs to be copied to any namespace that uses it:
+
+```sh
+$ kubectl get secret f3s-lan-tls -n cert-manager -o yaml | \
+ sed 's/namespace: cert-manager/namespace: services/' | \
+ kubectl apply -f -
+```
+
+*Configuring FreeBSD relayd for LAN access*:
+
+On both FreeBSD hosts (f0, f1), install and configure `relayd` for TCP forwarding:
+
+```sh
+paul@f0:~ % doas pkg install -y relayd
+```
+
+Create `/usr/local/etc/relayd.conf`:
+
+```
+# k3s nodes backend table
+table <k3s_nodes> { 192.168.1.120 192.168.1.121 192.168.1.122 }
+
+# TCP forwarding to Traefik (no TLS termination)
+relay "lan_http" {
+ listen on 192.168.1.138 port 80
+ forward to <k3s_nodes> port 80 check tcp
+}
+
+relay "lan_https" {
+ listen on 192.168.1.138 port 443
+ forward to <k3s_nodes> port 443 check tcp
+}
+```
+
+Note: The IP addresses `192.168.1.120-122` are the LAN IPs of the k3s nodes (r0, r1, r2), not their WireGuard IPs. FreeBSD `relayd` requires PF (Packet Filter) to be enabled. Create a minimal `/etc/pf.conf`:
+
+```
+# Basic PF rules for relayd
+set skip on lo0
+pass in quick
+pass out quick
+```
+
+Enable PF and relayd:
+
+```sh
+paul@f0:~ % doas sysrc pf_enable=YES pflog_enable=YES relayd_enable=YES
+paul@f0:~ % doas service pf start
+paul@f0:~ % doas service pflog start
+paul@f0:~ % doas service relayd start
+```
+
+Verify `relayd` is listening on the CARP VIP:
+
+```sh
+paul@f0:~ % doas sockstat -4 -l | grep 192.168.1.138
+_relayd relayd 2903 11 tcp4 192.168.1.138:80 *:*
+_relayd relayd 2903 12 tcp4 192.168.1.138:443 *:*
+```
+
+Repeat the same configuration on f1. Both hosts will run `relayd` listening on the CARP VIP, but only the CARP MASTER will respond to traffic. When failover occurs, the new MASTER takes over seamlessly.
+
+*Adding LAN ingress to services*:
+
+To expose a service on the LAN, add a second Ingress resource to its Helm chart. Here's an example for Navidrome:
+
+```yaml
+---
+# LAN Ingress for navidrome.f3s.lan.foo.zone
+apiVersion: networking.k8s.io/v1
+kind: Ingress
+metadata:
+ name: navidrome-ingress-lan
+ namespace: services
+ annotations:
+ spec.ingressClassName: traefik
+ traefik.ingress.kubernetes.io/router.entrypoints: web,websecure
+spec:
+ tls:
+ - hosts:
+ - navidrome.f3s.lan.foo.zone
+ secretName: f3s-lan-tls
+ rules:
+ - host: navidrome.f3s.lan.foo.zone
+ http:
+ paths:
+ - path: /
+ pathType: Prefix
+ backend:
+ service:
+ name: navidrome-service
+ port:
+ number: 4533
+```
+
+Key points:
+
+* Use `web,websecure` entrypoints (both HTTP and HTTPS)
+* Reference the `f3s-lan-tls` secret in the `tls` section
+* Use `.f3s.lan.foo.zone` subdomain pattern
+* Same backend service as the external ingress
+
+Apply the ingress and test:
+
+```sh
+$ kubectl apply -f navidrome-ingress-lan.yaml
+ingress.networking.k8s.io/navidrome-ingress-lan created
+
+$ curl -k https://navidrome.f3s.lan.foo.zone
+HTTP/2 302
+location: /app/
+```
+
+*Client-side DNS and CA setup*:
+
+To access LAN services, clients need DNS entries and must trust the self-signed CA.
+
+Add DNS entries to `/etc/hosts` on your laptop:
+
+```sh
+$ sudo tee -a /etc/hosts << 'EOF'
+# f3s LAN services
+192.168.1.138 navidrome.f3s.lan.foo.zone
+EOF
+```
+
+The CARP VIP `192.168.1.138` provides high availability—traffic automatically fails over to the backup host if the master goes down.
+
+Export the self-signed CA certificate:
+
+```sh
+$ kubectl get secret selfsigned-ca-secret -n cert-manager -o jsonpath='{.data.ca\.crt}' | \
+ base64 -d > f3s-lan-ca.crt
+```
+
+Install the CA certificate on Linux (Fedora/Rocky):
+
+```sh
+$ sudo cp f3s-lan-ca.crt /etc/pki/ca-trust/source/anchors/
+$ sudo update-ca-trust
+```
+
+After trusting the CA, browsers will accept the LAN certificates without warnings.
+
+*Scaling to other services*:
+
+The same pattern can be applied to any service. To add LAN access:
+
+1. Copy the `f3s-lan-tls` secret to the service's namespace (if not already there)
+2. Add a LAN Ingress resource using the pattern above
+3. Configure DNS: `192.168.1.138 service.f3s.lan.foo.zone`
+4. Commit and push (ArgoCD will deploy automatically)
+
+No changes needed to:
+
+* relayd configuration (forwards all traffic)
+* cert-manager (wildcard cert covers all `*.f3s.lan.foo.zone`)
+* CARP configuration (VIP shared by all services)
+
+*TLS offloaders summary*:
+
+The f3s infrastructure now has three distinct TLS offloaders:
+
+* **OpenBSD relayd**: External internet traffic (`*.f3s.foo.zone`) using Let's Encrypt
+* **Traefik (k3s)**: LAN HTTPS traffic (`*.f3s.lan.foo.zone`) using cert-manager
+* **stunnel**: NFS-over-TLS (port 2323) using custom PKI
+
+Each serves a different purpose with appropriate certificate management for its use case.
+
## Deploying the private Docker image registry
As not all Docker images I want to deploy are available on public Docker registries and as I also build some of them by myself, there is the need of a private registry.
diff --git a/gemfeed/atom.xml b/gemfeed/atom.xml
index b524d33d..92f98541 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-02-05T17:38:26+02:00</updated>
+ <updated>2026-02-05T17:44:05+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" />
@@ -4675,6 +4675,7 @@ p hash.values_at(:a, :c)
<li>⇢ ⇢ <a href='#openbsd-relayd-configuration'>OpenBSD relayd configuration</a></li>
<li>⇢ ⇢ <a href='#automatic-failover-when-f3s-cluster-is-down'>Automatic failover when f3s cluster is down</a></li>
<li>⇢ ⇢ <a href='#openbsd-httpd-fallback-configuration'>OpenBSD httpd fallback configuration</a></li>
+<li>⇢ <a href='#exposing-services-via-lan-ingress'>Exposing services via LAN ingress</a></li>
<li>⇢ <a href='#deploying-the-private-docker-image-registry'>Deploying the private Docker image registry</a></li>
<li>⇢ ⇢ <a href='#prepare-the-nfs-backed-storage'>Prepare the NFS-backed storage</a></li>
<li>⇢ ⇢ <a href='#install-or-upgrade-the-chart'>Install (or upgrade) the chart</a></li>
@@ -5523,6 +5524,280 @@ http://www.gnu.org/software/src-highlite -->
</ul><br />
<span>This fallback mechanism has proven invaluable during maintenance windows and unexpected outages, ensuring that users always get a response even when the home lab is offline.</span><br />
<br />
+<h2 style='display: inline' id='exposing-services-via-lan-ingress'>Exposing services via LAN ingress</h2><br />
+<br />
+<span>In addition to external access through the OpenBSD relays, services can also be exposed on the local network using LAN-specific ingresses. This is useful for accessing services from within the home network without going through the internet, reducing latency and providing an alternative path if the external relays are unavailable.</span><br />
+<br />
+<span>The LAN ingress architecture leverages the existing FreeBSD CARP (Common Address Redundancy Protocol) failover infrastructure that&#39;s already in place for NFS-over-TLS (see Part 5). Instead of deploying MetalLB or another LoadBalancer implementation, we reuse the CARP virtual IP (<span class='inlinecode'>192.168.1.138</span>) by adding HTTP/HTTPS forwarding alongside the existing stunnel service on port 2323.</span><br />
+<br />
+<span>*Architecture overview*:</span><br />
+<br />
+<span>The LAN access path differs from external access:</span><br />
+<br />
+<span>**External access (*.f3s.foo.zone):**</span><br />
+<pre>
+Internet → OpenBSD relayd (TLS termination, Let&#39;s Encrypt)
+ → WireGuard tunnel
+ → k3s Traefik :80 (HTTP)
+ → Service
+</pre>
+<br />
+<span>**LAN access (*.f3s.lan.foo.zone):**</span><br />
+<pre>
+LAN → FreeBSD CARP VIP (192.168.1.138)
+ → FreeBSD relayd (TCP forwarding)
+ → k3s Traefik :443 (TLS termination, cert-manager)
+ → Service
+</pre>
+<br />
+<span>The key architectural decisions:</span><br />
+<br />
+<ul>
+<li>FreeBSD <span class='inlinecode'>relayd</span> performs pure TCP forwarding (Layer 4) for ports 80 and 443, not TLS termination</li>
+<li>Traefik inside k3s handles TLS offloading using certificates from cert-manager</li>
+<li>Self-signed CA for LAN domains (no external dependencies)</li>
+<li>CARP provides automatic failover between f0 and f1</li>
+<li>No code changes to applications—just add a LAN ingress resource</li>
+</ul><br />
+<span>*Installing cert-manager*:</span><br />
+<br />
+<span>First, install cert-manager to handle certificate lifecycle management for LAN services. The installation is automated with a Justfile:</span><br />
+<br />
+<a class='textlink' href='https://codeberg.org/snonux/conf/src/branch/master/f3s/cert-manager'>codeberg.org/snonux/conf/f3s/cert-manager</a><br />
+<br />
+<!-- Generator: GNU source-highlight 3.1.9
+by Lorenzo Bettini
+http://www.lorenzobettini.it
+http://www.gnu.org/software/src-highlite -->
+<pre>$ cd conf/f3s/cert-manager
+$ just install
+kubectl apply -f cert-manager.yaml
+<i><font color="silver"># ... cert-manager CRDs and resources created ...</font></i>
+kubectl apply -f self-signed-issuer.yaml
+clusterissuer.cert-manager.io/selfsigned-issuer created
+clusterissuer.cert-manager.io/selfsigned-ca-issuer created
+kubectl apply -f ca-certificate.yaml
+certificate.cert-manager.io/selfsigned-ca created
+kubectl apply -f wildcard-certificate.yaml
+certificate.cert-manager.io/f3s-lan-wildcard created
+</pre>
+<br />
+<span>This creates:</span><br />
+<br />
+<ul>
+<li>A self-signed ClusterIssuer</li>
+<li>A CA certificate (<span class='inlinecode'>f3s-lan-ca</span>) valid for 10 years</li>
+<li>A CA-signed ClusterIssuer</li>
+<li>A wildcard certificate (<span class='inlinecode'>*.f3s.lan.foo.zone</span>) valid for 90 days with automatic renewal</li>
+</ul><br />
+<span>Verify the certificates:</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>$ kubectl get certificate -n cert-manager
+NAME READY SECRET AGE
+f3s-lan-wildcard True f3s-lan-tls 5m
+selfsigned-ca True selfsigned-ca-secret 5m
+</pre>
+<br />
+<span>The wildcard certificate (<span class='inlinecode'>f3s-lan-tls</span>) needs to be copied to any namespace that uses it:</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>$ kubectl get secret f3s-lan-tls -n cert-manager -o yaml | \
+ sed <font color="#808080">'s/namespace: cert-manager/namespace: services/'</font> | \
+ kubectl apply -f -
+</pre>
+<br />
+<span>*Configuring FreeBSD relayd for LAN access*:</span><br />
+<br />
+<span>On both FreeBSD hosts (f0, f1), install and configure <span class='inlinecode'>relayd</span> for TCP forwarding:</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>paul@f0:~ % doas pkg install -y relayd
+</pre>
+<br />
+<span>Create <span class='inlinecode'>/usr/local/etc/relayd.conf</span>:</span><br />
+<br />
+<pre>
+# k3s nodes backend table
+table &lt;k3s_nodes&gt; { 192.168.1.120 192.168.1.121 192.168.1.122 }
+
+# TCP forwarding to Traefik (no TLS termination)
+relay "lan_http" {
+ listen on 192.168.1.138 port 80
+ forward to &lt;k3s_nodes&gt; port 80 check tcp
+}
+
+relay "lan_https" {
+ listen on 192.168.1.138 port 443
+ forward to &lt;k3s_nodes&gt; port 443 check tcp
+}
+</pre>
+<br />
+<span>Note: The IP addresses <span class='inlinecode'>192.168.1.120-122</span> are the LAN IPs of the k3s nodes (r0, r1, r2), not their WireGuard IPs. FreeBSD <span class='inlinecode'>relayd</span> requires PF (Packet Filter) to be enabled. Create a minimal <span class='inlinecode'>/etc/pf.conf</span>:</span><br />
+<br />
+<pre>
+# Basic PF rules for relayd
+set skip on lo0
+pass in quick
+pass out quick
+</pre>
+<br />
+<span>Enable PF and relayd:</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>paul@f0:~ % doas sysrc pf_enable=YES pflog_enable=YES relayd_enable=YES
+paul@f0:~ % doas service pf start
+paul@f0:~ % doas service pflog start
+paul@f0:~ % doas service relayd start
+</pre>
+<br />
+<span>Verify <span class='inlinecode'>relayd</span> is listening on the CARP VIP:</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>paul@f0:~ % doas sockstat -<font color="#000000">4</font> -l | grep <font color="#000000">192.168</font>.<font color="#000000">1.138</font>
+_relayd relayd <font color="#000000">2903</font> <font color="#000000">11</font> tcp4 <font color="#000000">192.168</font>.<font color="#000000">1.138</font>:<font color="#000000">80</font> *:*
+_relayd relayd <font color="#000000">2903</font> <font color="#000000">12</font> tcp4 <font color="#000000">192.168</font>.<font color="#000000">1.138</font>:<font color="#000000">443</font> *:*
+</pre>
+<br />
+<span>Repeat the same configuration on f1. Both hosts will run <span class='inlinecode'>relayd</span> listening on the CARP VIP, but only the CARP MASTER will respond to traffic. When failover occurs, the new MASTER takes over seamlessly.</span><br />
+<br />
+<span>*Adding LAN ingress to services*:</span><br />
+<br />
+<span>To expose a service on the LAN, add a second Ingress resource to its Helm chart. Here&#39;s an example for Navidrome:</span><br />
+<br />
+<pre>
+---
+# LAN Ingress for navidrome.f3s.lan.foo.zone
+apiVersion: networking.k8s.io/v1
+kind: Ingress
+metadata:
+ name: navidrome-ingress-lan
+ namespace: services
+ annotations:
+ spec.ingressClassName: traefik
+ traefik.ingress.kubernetes.io/router.entrypoints: web,websecure
+spec:
+ tls:
+ - hosts:
+ - navidrome.f3s.lan.foo.zone
+ secretName: f3s-lan-tls
+ rules:
+ - host: navidrome.f3s.lan.foo.zone
+ http:
+ paths:
+ - path: /
+ pathType: Prefix
+ backend:
+ service:
+ name: navidrome-service
+ port:
+ number: 4533
+</pre>
+<br />
+<span>Key points:</span><br />
+<br />
+<ul>
+<li>Use <span class='inlinecode'>web,websecure</span> entrypoints (both HTTP and HTTPS)</li>
+<li>Reference the <span class='inlinecode'>f3s-lan-tls</span> secret in the <span class='inlinecode'>tls</span> section</li>
+<li>Use <span class='inlinecode'>.f3s.lan.foo.zone</span> subdomain pattern</li>
+<li>Same backend service as the external ingress</li>
+</ul><br />
+<span>Apply the ingress and test:</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>$ kubectl apply -f navidrome-ingress-lan.yaml
+ingress.networking.k8s.io/navidrome-ingress-lan created
+
+$ curl -k https://navidrome.f3s.lan.foo.zone
+HTTP/<font color="#000000">2</font> <font color="#000000">302</font>
+location: /app/
+</pre>
+<br />
+<span>*Client-side DNS and CA setup*:</span><br />
+<br />
+<span>To access LAN services, clients need DNS entries and must trust the self-signed CA.</span><br />
+<br />
+<span>Add DNS entries to <span class='inlinecode'>/etc/hosts</span> on your laptop:</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>$ sudo tee -a /etc/hosts &lt;&lt; <font color="#808080">'EOF'</font>
+<i><font color="silver"># f3s LAN services</font></i>
+<font color="#000000">192.168</font>.<font color="#000000">1.138</font> navidrome.f3s.lan.foo.zone
+EOF
+</pre>
+<br />
+<span>The CARP VIP <span class='inlinecode'>192.168.1.138</span> provides high availability—traffic automatically fails over to the backup host if the master goes down.</span><br />
+<br />
+<span>Export the self-signed CA certificate:</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>$ kubectl get secret selfsigned-ca-secret -n cert-manager -o jsonpath=<font color="#808080">'{.data.ca</font>\.<font color="#808080">crt}'</font> | \
+ base64 -d &gt; f3s-lan-ca.crt
+</pre>
+<br />
+<span>Install the CA certificate on Linux (Fedora/Rocky):</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>$ sudo cp f3s-lan-ca.crt /etc/pki/ca-trust/source/anchors/
+$ sudo update-ca-trust
+</pre>
+<br />
+<span>After trusting the CA, browsers will accept the LAN certificates without warnings.</span><br />
+<br />
+<span>*Scaling to other services*:</span><br />
+<br />
+<span>The same pattern can be applied to any service. To add LAN access:</span><br />
+<br />
+<span>1. Copy the <span class='inlinecode'>f3s-lan-tls</span> secret to the service&#39;s namespace (if not already there)</span><br />
+<span>2. Add a LAN Ingress resource using the pattern above</span><br />
+<span>3. Configure DNS: <span class='inlinecode'>192.168.1.138 service.f3s.lan.foo.zone</span></span><br />
+<span>4. Commit and push (ArgoCD will deploy automatically)</span><br />
+<br />
+<span>No changes needed to:</span><br />
+<br />
+<ul>
+<li>relayd configuration (forwards all traffic)</li>
+<li>cert-manager (wildcard cert covers all <span class='inlinecode'>*.f3s.lan.foo.zone</span>)</li>
+<li>CARP configuration (VIP shared by all services)</li>
+</ul><br />
+<span>*TLS offloaders summary*:</span><br />
+<br />
+<span>The f3s infrastructure now has three distinct TLS offloaders:</span><br />
+<br />
+<ul>
+<li>**OpenBSD relayd**: External internet traffic (<span class='inlinecode'>*.f3s.foo.zone</span>) using Let&#39;s Encrypt</li>
+<li>**Traefik (k3s)**: LAN HTTPS traffic (<span class='inlinecode'>*.f3s.lan.foo.zone</span>) using cert-manager</li>
+<li>**stunnel**: NFS-over-TLS (port 2323) using custom PKI</li>
+</ul><br />
+<span>Each serves a different purpose with appropriate certificate management for its use case.</span><br />
+<br />
<h2 style='display: inline' id='deploying-the-private-docker-image-registry'>Deploying the private Docker image registry</h2><br />
<br />
<span>As not all Docker images I want to deploy are available on public Docker registries and as I also build some of them by myself, there is the need of a private registry.</span><br />
diff --git a/index.gmi b/index.gmi
index 7da9af7a..abd79a3f 100644
--- a/index.gmi
+++ b/index.gmi
@@ -1,6 +1,6 @@
# Hello!
-> This site was generated at 2026-02-05T17:38:26+02:00 by `Gemtexter`
+> This site was generated at 2026-02-05T17:44:05+02:00 by `Gemtexter`
Welcome to the foo.zone!
diff --git a/uptime-stats.gmi b/uptime-stats.gmi
index 6c0d00ff..f7bb4a71 100644
--- a/uptime-stats.gmi
+++ b/uptime-stats.gmi
@@ -1,6 +1,6 @@
# My machine uptime stats
-> This site was last updated at 2026-02-05T17:38:26+02:00
+> This site was last updated at 2026-02-05T17:44:05+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.