summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--about/resources.md212
-rw-r--r--gemfeed/2025-07-14-f3s-kubernetes-with-freebsd-part-6.md12
-rw-r--r--gemfeed/DRAFT-ipv6test-deployment.md274
-rw-r--r--index.md2
-rw-r--r--uptime-stats.md44
5 files changed, 410 insertions, 134 deletions
diff --git a/about/resources.md b/about/resources.md
index c4e71606..c2c6d3fe 100644
--- a/about/resources.md
+++ b/about/resources.md
@@ -35,110 +35,110 @@ You won't find any links on this site because, over time, the links will break.
In random order:
-* Data Science at the Command Line; Jeroen Janssens; O'Reilly
-* Effective Java; Joshua Bloch; Addison-Wesley Professional
-* Leanring eBPF; Liz Rice; 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
+* 21st Century C: C Tips from the New School; Ben Klemens; O'Reilly
+* DevOps And Site Reliability Engineering Handbook; Stephen Fleming; Audible
+* C++ Programming Language; Bjarne Stroustrup;
* The DevOps Handbook; Gene Kim, Jez Humble, Patrick Debois, John Willis; Audible
-* Effective awk programming; Arnold Robbins; O'Reilly
-* Funktionale Programmierung; Peter Pepper; Springer
-* Kubernetes Cookbook; Sameer Naik, Sébastien Goasguen, Jonathan Michaux; O'Reilly
-* 100 Go Mistakes and How to Avoid Them; Teiva Harsanyi; Manning Publications
+* Clusterbau mit Linux-HA; Michael Schwartzkopff; O'Reilly
+* Chaos Engineering - System Resiliency in Practice; Casey Rosenthal and Nora Jones; eBook
+* Amazon Web Services in Action; Michael Wittig and Andreas Wittig; Manning Publications
+* Data Science at the Command Line; Jeroen Janssens; O'Reilly
+* Raku Recipes; J.J. Merelo; Apress
+* Programming Ruby 3.3 (5th Edition); Noel Rappin, with Dave Thomas; The Pragmatic Bookshelf
* Concurrency in Go; Katherine Cox-Buday; O'Reilly
* Hands-on Infrastructure Monitoring with Prometheus; Joel Bastos, Pedro Araujo; Packt
-* Go Brain Teasers - Exercise Your Mind; Miki Tebeka; The Pragmatic Programmers
-* Chaos Engineering - System Resiliency in Practice; Casey Rosenthal and Nora Jones; eBook
-* Ultimate Go Notebook; Bill Kennedy
+* Higher Order Perl; Mark Dominus; Morgan Kaufmann
* Learn You Some Erlang for Great Good; Fred Herbert; No Starch Press
+* Kubernetes Cookbook; Sameer Naik, Sébastien Goasguen, Jonathan Michaux; O'Reilly
+* The Pragmatic Programmer; David Thomas; Addison-Wesley
+* Effective Java; Joshua Bloch; Addison-Wesley Professional
* Developing Games in Java; David Brackeen and others...; New Riders
-* Pro Puppet; James Turnbull, Jeffrey McCune; Apress
-* The KCNA (Kubernetes and Cloud Native Associate) Book; Nigel Poulton
-* Tmux 2: Productive Mouse-free Development; Brain P. Hogan; The Pragmatic Programmers
-* The Docker Book; James Turnbull; Kindle
-* Amazon Web Services in Action; Michael Wittig and Andreas Wittig; Manning Publications
-* C++ Programming Language; Bjarne Stroustrup;
-* Raku Fundamentals; Moritz Lenz; Apress
-* The Go Programming Language; Alan A. A. Donovan; Addison-Wesley Professional
+* 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
+* Effective awk programming; Arnold Robbins; O'Reilly
+* Seeking SRE: Conversations About Running Production Systems at Scale; David N. Blank-Edelman; eBook
* Think Raku (aka Think Perl 6); Laurent Rosenfeld, Allen B. Downey; O'Reilly
-* DevOps And Site Reliability Engineering Handbook; Stephen Fleming; Audible
+* The Go Programming Language; Alan A. A. Donovan; Addison-Wesley Professional
+* Object-Oriented Programming with ANSI-C; Axel-Tobias Schreiner
+* Perl New Features; Joshua McAdams, brian d foy; Perl School
+* Systemprogrammierung in Go; Frank Müller; dpunkt
* Programming Perl aka "The Camel Book"; Tom Christiansen, brian d foy, Larry Wall & Jon Orwant; O'Reilly
-* Raku Recipes; J.J. Merelo; Apress
-* Clusterbau mit Linux-HA; Michael Schwartzkopff; O'Reilly
-* 21st Century C: C Tips from the New School; Ben Klemens; O'Reilly
-* Java ist auch eine Insel; Christian Ullenboom;
+* The Docker Book; James Turnbull; Kindle
* Terraform Cookbook; Mikael Krief; Packt Publishing
-* Modern Perl; Chromatic ; Onyx Neon Press
-* Perl New Features; Joshua McAdams, brian d foy; Perl School
-* Higher Order Perl; Mark Dominus; Morgan Kaufmann
-* Learn You a Haskell for Great Good!; Miran Lipovaca; No Starch Press
-* Object-Oriented Programming with ANSI-C; Axel-Tobias Schreiner
-* Systems Performance Tuning; Gian-Paolo D. Musumeci and others...; O'Reilly
-* Site Reliability Engineering; How Google runs production systems; O'Reilly
* 97 things every SRE should know; Emil Stolarsky, Jaime Woo; O'Reilly
-* DNS and BIND; Cricket Liu; O'Reilly
-* Systemprogrammierung in Go; Frank Müller; dpunkt
+* Funktionale Programmierung; Peter Pepper; Springer
+* The KCNA (Kubernetes and Cloud Native Associate) Book; Nigel Poulton
+* Leanring eBPF; Liz Rice; O'Reilly
+* Learn You a Haskell for Great Good!; Miran Lipovaca; No Starch Press
+* Raku Fundamentals; Moritz Lenz; Apress
+* Pro Puppet; James Turnbull, Jeffrey McCune; Apress
+* Go Brain Teasers - Exercise Your Mind; Miki Tebeka; The Pragmatic Programmers
* Polished Ruby Programming; Jeremy Evans; Packt Publishing
-* The Pragmatic Programmer; David Thomas; Addison-Wesley
-* Distributed Systems: Principles and Paradigms; Andrew S. Tanenbaum; Pearson
-* Seeking SRE: Conversations About Running Production Systems at Scale; David N. Blank-Edelman; eBook
-* Programming Ruby 3.3 (5th Edition); Noel Rappin, with Dave Thomas; The Pragmatic Bookshelf
+* Java ist auch eine Insel; Christian Ullenboom;
* The Kubernetes Book; Nigel Poulton; Unabridged Audiobook
+* Ultimate Go Notebook; Bill Kennedy
+* Tmux 2: Productive Mouse-free Development; Brain P. Hogan; The Pragmatic Programmers
+* Distributed Systems: Principles and Paradigms; Andrew S. Tanenbaum; Pearson
+* Systems Performance Tuning; Gian-Paolo D. Musumeci and others...; O'Reilly
+* 100 Go Mistakes and How to Avoid Them; Teiva Harsanyi; Manning Publications
+* Site Reliability Engineering; How Google runs production systems; O'Reilly
+* Modern Perl; Chromatic ; Onyx Neon Press
## 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:
-* Groovy Kurz & Gut; Joerg Staudemeier; O'Reilly
+* Understanding the Linux Kernel; Daniel P. Bovet, Marco Cesati; O'Reilly
* BPF Performance Tools - Linux System and Application Observability, Brendan Gregg; Addison Wesley
-* Go: Design Patterns for Real-World Projects; Mat Ryer; Packt
* 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
* Relayd and Httpd Mastery; Michael W Lucas
+* Groovy Kurz & Gut; Joerg Staudemeier; O'Reilly
+* Go: Design Patterns for Real-World Projects; Mat Ryer; Packt
+* Implementing Service Level Objectives; Alex Hidalgo; O'Reilly
* Algorithms; Robert Sedgewick, Kevin Wayne; Addison Wesley
## Self-development and soft-skills books
In random order:
-* Digital Minimalism; Cal Newport; Portofolio Penguin
-* Consciousness: A Very Short Introduction; Susan Blackmore; Oxford Uiversity Press
-* The Courage to Be Disliked; Ichiro Kishimi and Fumitake Koga; Audiobook
-* The Phoenix Project - A Novel About IT, DevOps, and Helping your Business Win; Gene Kim and Kevin Behr; Trade Select
-* 97 Things Every Engineering Manager Should Know; Camille Fournier; Audiobook
+* Influence without Authority; A. Cohen, D. Bradford; Wiley
+* Slow Productivity; Cal Newport; Penguin Random House
+* Psycho-Cybernetics; Maxwell Maltz; Perigee Books
+* Who Moved My Cheese?; Dr. Spencer Johnson; Vermilion
* Atomic Habits; James Clear; Random House Business
-* Soft Skills; John Sommez; Manning Publications
+* The Daily Stoic; Ryan Holiday, Stephen Hanselman; Profile Books
* Ultralearning; Scott Young; Thorsons
-* Coders at Work - Reflections on the craft of programming, Peter Seibel and Mitchell Dorian et al., Audiobook
-* The Good Enough Job; Simone Stolzoff; Ebury Edge
-* Psycho-Cybernetics; Maxwell Maltz; Perigee Books
+* The Off Switch; Mark Cropley; Virgin Books (RE-READ 1ST TIME)
+* 97 Things Every Engineering Manager Should Know; Camille Fournier; Audiobook
+* The Joy of Missing Out; Christina Crook; New Society Publishers
* So Good They Can't Ignore You; Cal Newport; Business Plus
-* Time Management for System Administrators; Thomas A. Limoncelli; O'Reilly
-* The Power of Now; Eckhard Tolle; Yellow Kite
-* The Daily Stoic; Ryan Holiday, Stephen Hanselman; Profile Books
-* Eat That Frog!; Brian Tracy; Hodder Paperbacks
-* Eat That Frog; Brian Tracy
-* Staff Engineer: Leadership beyond the management track; Will Larson; Audiobook
+* Search Inside Yourself - The Unexpected path to Achieving Success, Happiness (and World Peace); Chade-Meng Tan, Daniel Goleman, Jon Kabat-Zinn; HarperOne
* Never Split the Difference; Chris Voss, Tahl Raz; Random House Business
-* The Bullet Journal Method; Ryder Carroll; Fourth Estate
-* Deep Work; Cal Newport; Piatkus
+* Buddah and Einstein walk into a Bar; Guy Joseph Ale, Claire Bloom; Blackstone Publishing
* The Obstacle Is The Way; Ryan Holiday; Profile Books Ltd
-* The Joy of Missing Out; Christina Crook; New Society Publishers
-* Getting Things Done; David Allen
-* Stop starting, start finishing; Arne Roock; Lean-Kanban University
-* Meditation for Mortals, Oliver Burkeman, Audiobook
-* Who Moved My Cheese?; Dr. Spencer Johnson; Vermilion
-* 101 Essays that change the way you think; Brianna Wiest; Audiobook
-* The Complete Software Developer's Career Guide; John Sonmez; Unabridged Audiobook
-* Influence without Authority; A. Cohen, D. Bradford; Wiley
* The Software Engineer's Guidebook: Navigating senior, tech lead, and staff engineer positions at tech companies and startups; Gergely Orosz; Audiobook
-* The 7 Habits Of Highly Effective People; Stephen R. Covey; Simon & Schuster UK
-* Buddah and Einstein walk into a Bar; Guy Joseph Ale, Claire Bloom; Blackstone Publishing
-* Slow Productivity; Cal Newport; Penguin Random House
-* Ultralearning; Anna Laurent; Self-published via Amazon
-* Search Inside Yourself - The Unexpected path to Achieving Success, Happiness (and World Peace); Chade-Meng Tan, Daniel Goleman, Jon Kabat-Zinn; HarperOne
+* Digital Minimalism; Cal Newport; Portofolio Penguin
+* Eat That Frog!; Brian Tracy; Hodder Paperbacks
+* The Courage to Be Disliked; Ichiro Kishimi and Fumitake Koga; Audiobook
+* Deep Work; Cal Newport; Piatkus
+* Consciousness: A Very Short Introduction; Susan Blackmore; Oxford Uiversity Press
+* The Good Enough Job; Simone Stolzoff; Ebury Edge
* Solve for Happy; Mo Gawdat (RE-READ 1ST TIME)
-* The Off Switch; Mark Cropley; Virgin Books (RE-READ 1ST TIME)
+* Staff Engineer: Leadership beyond the management track; Will Larson; Audiobook
+* Time Management for System Administrators; Thomas A. Limoncelli; O'Reilly
+* Ultralearning; Anna Laurent; Self-published via Amazon
+* The 7 Habits Of Highly Effective People; Stephen R. Covey; Simon & Schuster UK
+* Eat That Frog; Brian Tracy
+* Meditation for Mortals, Oliver Burkeman, Audiobook
+* Coders at Work - Reflections on the craft of programming, Peter Seibel and Mitchell Dorian et al., Audiobook
+* Stop starting, start finishing; Arne Roock; Lean-Kanban University
+* Soft Skills; John Sommez; Manning Publications
+* The Complete Software Developer's Career Guide; John Sonmez; Unabridged Audiobook
+* Getting Things Done; David Allen
+* 101 Essays that change the way you think; Brianna Wiest; Audiobook
+* The Bullet Journal Method; Ryder Carroll; Fourth Estate
+* The Power of Now; Eckhard Tolle; Yellow Kite
+* The Phoenix Project - A Novel About IT, DevOps, and Helping your Business Win; Gene Kim and Kevin Behr; Trade Select
[Here are notes of mine for some of the books](../notes/index.md)
@@ -146,30 +146,30 @@ In random order:
Some of these were in-person with exams; others were online learning lectures only. In random order:
-* 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)
-* Linux Security and Isolation APIs Training; Michael Kerrisk; 3-day on-site training
-* AWS Immersion Day; Amazon; 1-day interactive online training
* Functional programming lecture; Remote University of Hagen
-* Ultimate Go Programming; Bill Kennedy; O'Reilly Online
* Structure and Interpretation of Computer Programs; Harold Abelson and more...;
-* Algorithms Video Lectures; Robert Sedgewick; O'Reilly Online
-* MySQL Deep Dive Workshop; 2-day on-site training
-* Apache Tomcat Best Practises; 3-day on-site training
-* Developing IaC with Terraform (with Live Lessons); O'Reilly Online
-* The Ultimate Kubernetes Bootcamp; School of Devops; O'Reilly Online
* F5 Loadbalancers Training; 2-day on-site training; F5, Inc.
+* The Ultimate Kubernetes Bootcamp; School of Devops; O'Reilly Online
+* Apache Tomcat Best Practises; 3-day on-site training
+* MySQL Deep Dive Workshop; 2-day on-site training
+* Ultimate Go Programming; Bill Kennedy; O'Reilly Online
+* Linux Security and Isolation APIs Training; Michael Kerrisk; 3-day on-site training
+* Cloud Operations on AWS - Learn how to configure, deploy, maintain, and troubleshoot your AWS environments; 3-day online live training with labs; Amazon
* Protocol buffers; 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)
* The Well-Grounded Rubyist Video Edition; David. A. Black; O'Reilly Online
* Scripting Vim; Damian Conway; 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
+* Developing IaC with Terraform (with Live Lessons); O'Reilly Online
+* AWS Immersion Day; Amazon; 1-day interactive online training
+* Algorithms Video Lectures; Robert Sedgewick; 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
## Podcasts
@@ -177,57 +177,57 @@ These are not whole books, but guides (smaller or larger) which I found very use
In random order:
-* The Changelog Podcast(s)
+* Hidden Brain
* Cup o' Go [Golang]
-* Fallthrough [Golang]
+* BSD Now [BSD]
+* Pratical AI
* Deep Questions with Cal Newport
-* Fork Around And Find Out
-* Wednesday Wisdom
-* Dev Interrupted
-* Hidden Brain
-* Backend Banter
* The ProdCast (Google SRE Podcast)
-* Maintainable
+* Wednesday Wisdom
* The Pragmatic Engineer Podcast
+* Fallthrough [Golang]
* Modern Mentor
-* Pratical AI
-* BSD Now [BSD]
+* Fork Around And Find Out
+* Backend Banter
+* Dev Interrupted
+* Maintainable
+* The Changelog Podcast(s)
### 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.
-* CRE: Chaosradio Express [german]
+* Go Time (predecessor of fallthrough)
* FLOSS weekly
-* Java Pub House
-* Ship It (predecessor of Fork Around And Find Out)
+* CRE: Chaosradio Express [german]
* Modern Mentor
-* Go Time (predecessor of fallthrough)
+* Ship It (predecessor of Fork Around And Find Out)
+* Java Pub House
## Newsletters I like
This is a mix of tech and non-tech newsletters I am subscribed to. In random order:
-* byteSizeGo
+* Changelog News
+* VK Newsletter
* The Imperfectionist
+* Andreas Brandhorst Newsletter (Sci-Fi author)
* The Pragmatic Engineer
-* Changelog News
-* Ruby Weekly
-* Golang Weekly
-* Applied Go Weekly Newsletter
-* The Valuable Dev
* Register Spill
+* Applied Go Weekly Newsletter
+* Golang Weekly
* Monospace Mentor
-* Andreas Brandhorst Newsletter (Sci-Fi author)
-* VK Newsletter
+* The Valuable Dev
+* byteSizeGo
+* Ruby Weekly
## 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:
-* LWN (online only)
* freeX (not published anymore)
* Linux User
+* LWN (online only)
* Linux Magazine
# Formal education
diff --git a/gemfeed/2025-07-14-f3s-kubernetes-with-freebsd-part-6.md b/gemfeed/2025-07-14-f3s-kubernetes-with-freebsd-part-6.md
index c588985f..63505c9e 100644
--- a/gemfeed/2025-07-14-f3s-kubernetes-with-freebsd-part-6.md
+++ b/gemfeed/2025-07-14-f3s-kubernetes-with-freebsd-part-6.md
@@ -1070,6 +1070,8 @@ paul@f0:~ % doas sh -c 'for client in r0 r1 r2 earth; do
-subj "/C=US/ST=State/L=City/O=F3S Storage/CN=${client}.lan.buetow.org"
openssl x509 -req -days 3650 -in ${client}.csr -CA ca-cert.pem \
-CAkey ca-key.pem -CAcreateserial -out ${client}-cert.pem
+ # Combine cert and key into a single file for stunnel client
+ cat ${client}-cert.pem ${client}-key.pem > ${client}-stunnel.pem
done'
```
@@ -1515,12 +1517,12 @@ On the Rocky Linux VMs, we run:
[root@r0 ~]# dnf install -y stunnel nfs-utils
# Copy client certificate and CA certificate from f0
-[root@r0 ~]# scp f0:/usr/local/etc/stunnel/ca/r0-key.pem /etc/stunnel/
+[root@r0 ~]# scp f0:/usr/local/etc/stunnel/ca/r0-stunnel.pem /etc/stunnel/
[root@r0 ~]# scp f0:/usr/local/etc/stunnel/ca/ca-cert.pem /etc/stunnel/
# Configure stunnel client with certificate authentication
[root@r0 ~]# tee /etc/stunnel/stunnel.conf <<'EOF'
-cert = /etc/stunnel/r0-key.pem
+cert = /etc/stunnel/r0-stunnel.pem
CAfile = /etc/stunnel/ca-cert.pem
client = yes
verify = 2
@@ -1536,7 +1538,7 @@ EOF
# Repeat for r1 and r2 with their respective certificates
```
-Note: Each client must use its certificate file (`r0-key.pem`, `r1-key.pem`, `r2-key.pem`, or `earth-key.pem` - the latter is for my Laptop, which can also mount the NFS shares).
+Note: Each client must use its certificate file (`r0-stunnel.pem`, `r1-stunnel.pem`, `r2-stunnel.pem`, or `earth-stunnel.pem` - the latter is for my Laptop, which can also mount the NFS shares).
### NFSv4 user mapping config on Rocky
@@ -1578,11 +1580,11 @@ To mount NFS through the stunnel encrypted tunnel, we run:
[root@r0 ~]# mkdir -p /data/nfs/k3svolumes
# Mount through stunnel (using localhost and NFSv4)
-[root@r0 ~]# mount -t nfs4 -o port=2323 127.0.0.1:/data/nfs/k3svolumes /data/nfs/k3svolumes
+[root@r0 ~]# mount -t nfs4 -o port=2323 127.0.0.1:/k3svolumes /data/nfs/k3svolumes
# Verify mount
[root@r0 ~]# mount | grep k3svolumes
-127.0.0.1:/data/nfs/k3svolumes on /data/nfs/k3svolumes
+127.0.0.1:/k3svolumes on /data/nfs/k3svolumes
type nfs4 (rw,relatime,vers=4.2,rsize=131072,wsize=131072,
namlen=255,hard,proto=tcp,port=2323,timeo=600,retrans=2,sec=sys,
clientaddr=127.0.0.1,local_lock=none,addr=127.0.0.1)
diff --git a/gemfeed/DRAFT-ipv6test-deployment.md b/gemfeed/DRAFT-ipv6test-deployment.md
new file mode 100644
index 00000000..290b0f07
--- /dev/null
+++ b/gemfeed/DRAFT-ipv6test-deployment.md
@@ -0,0 +1,274 @@
+# Deploying an IPv6 Test Service on Kubernetes
+
+## Introduction
+
+This post covers deploying a simple IPv6/IPv4 connectivity test application to the f3s Kubernetes cluster. The application displays visitors' IP addresses and determines whether they're connecting via IPv6 or IPv4—useful for testing dual-stack connectivity.
+
+The interesting technical challenge was preserving the original client IP address through multiple reverse proxies: from the OpenBSD relayd frontends, through Traefik ingress, to the Apache CGI backend.
+
+[f3s series](./2024-11-17-f3s-kubernetes-with-freebsd-part-1.md)
+
+## Architecture Overview
+
+The request flow looks like this:
+
+```
+Client → relayd (OpenBSD) → Traefik (k3s) → Apache + CGI (Pod)
+```
+
+Each hop needs to preserve the client's real IP address via the `X-Forwarded-For` header.
+
+## The Application
+
+The application is a simple Perl CGI script that:
+
+1. Detects whether the client is using IPv4 or IPv6
+2. Performs DNS lookups on client and server addresses
+3. Displays diagnostic information
+
+```perl
+#!/usr/bin/perl
+use strict;
+use warnings;
+
+print "Content-type: text/html\n\n";
+
+my $is_ipv4 = ($ENV{REMOTE_ADDR} =~ /(?:\d+\.){3}\d/);
+print "You are using: " . ($is_ipv4 ? "IPv4" : "IPv6") . "\n";
+print "Client address: $ENV{REMOTE_ADDR}\n";
+```
+
+## Docker Image
+
+The Docker image uses Apache httpd with CGI and `mod_remoteip` enabled:
+
+```dockerfile
+FROM httpd:2.4-alpine
+
+RUN apk add --no-cache perl bind-tools
+
+# Enable CGI and remoteip modules
+RUN sed -i 's/#LoadModule cgid_module/LoadModule cgid_module/' \
+ /usr/local/apache2/conf/httpd.conf && \
+ sed -i 's/#LoadModule remoteip_module/LoadModule remoteip_module/' \
+ /usr/local/apache2/conf/httpd.conf && \
+ echo 'RemoteIPHeader X-Forwarded-For' >> /usr/local/apache2/conf/httpd.conf && \
+ echo 'RemoteIPInternalProxy 10.0.0.0/8' >> /usr/local/apache2/conf/httpd.conf && \
+ echo 'RemoteIPInternalProxy 192.168.0.0/16' >> /usr/local/apache2/conf/httpd.conf
+
+COPY index.pl /usr/local/apache2/cgi-bin/index.pl
+```
+
+The key is `mod_remoteip`: it reads the `X-Forwarded-For` header and sets `REMOTE_ADDR` to the original client IP. The `RemoteIPInternalProxy` directives tell Apache which upstream proxies to trust.
+
+## Kubernetes Deployment
+
+The Helm chart is straightforward:
+
+```yaml
+apiVersion: apps/v1
+kind: Deployment
+metadata:
+ name: ipv6test
+ namespace: services
+spec:
+ replicas: 1
+ selector:
+ matchLabels:
+ app: ipv6test
+ template:
+ spec:
+ containers:
+ - name: ipv6test
+ image: registry.lan.buetow.org:30001/ipv6test:1.1.0
+ ports:
+ - containerPort: 80
+```
+
+## Configuring Traefik to Trust Forwarded Headers
+
+By default, Traefik overwrites `X-Forwarded-For` with its own view of the client IP (which is the upstream proxy, not the real client). To preserve the original header, Traefik needs to trust the upstream proxies.
+
+In k3s, this is configured via a HelmChartConfig:
+
+```yaml
+apiVersion: helm.cattle.io/v1
+kind: HelmChartConfig
+metadata:
+ name: traefik
+ namespace: kube-system
+spec:
+ valuesContent: |-
+ additionalArguments:
+ - "--entryPoints.web.forwardedHeaders.trustedIPs=192.168.0.0/16,10.0.0.0/8"
+ - "--entryPoints.websecure.forwardedHeaders.trustedIPs=192.168.0.0/16,10.0.0.0/8"
+```
+
+This tells Traefik to trust `X-Forwarded-For` headers from the WireGuard tunnel IPs (where relayd connects from) and internal pod networks.
+
+## Relayd Configuration
+
+The OpenBSD relayd proxy already sets the `X-Forwarded-For` header:
+
+```
+http protocol "https" {
+ match request header set "X-Forwarded-For" value "$REMOTE_ADDR"
+ match request header set "X-Forwarded-Proto" value "https"
+}
+```
+
+## IPv4-Only and IPv6-Only Subdomains
+
+To properly test IPv4 and IPv6 connectivity separately, three hostnames are configured:
+
+* ipv6test.f3s.buetow.org - Dual stack (A + AAAA records)
+* ipv4.ipv6test.f3s.buetow.org - IPv4 only (A record only)
+* ipv6.ipv6test.f3s.buetow.org - IPv6 only (AAAA record only)
+
+The NSD zone template dynamically generates the correct record types:
+
+```perl
+<% for my $host (@$f3s_hosts) {
+ my $is_ipv6_only = $host =~ /^ipv6\./;
+ my $is_ipv4_only = $host =~ /^ipv4\./;
+-%>
+<% unless ($is_ipv6_only) { -%>
+<%= $host %>. 300 IN A <%= $ips->{current_master}{ipv4} %>
+<% } -%>
+<% unless ($is_ipv4_only) { -%>
+<%= $host %>. 300 IN AAAA <%= $ips->{current_master}{ipv6} %>
+<% } -%>
+<% } -%>
+```
+
+This ensures:
+* Hosts starting with `ipv6.` get only AAAA records
+* Hosts starting with `ipv4.` get only A records
+* All other hosts get both A and AAAA records
+
+The Kubernetes ingress handles all three hostnames, routing to the same backend service.
+
+## TLS Certificates with Subject Alternative Names
+
+Since Let's Encrypt validates domains via HTTP, the IPv6-only subdomain (`ipv6.ipv6test.f3s.buetow.org`) cannot be validated directly—Let's Encrypt's validation servers use IPv4. The solution is to include all subdomains as Subject Alternative Names (SANs) in the parent certificate.
+
+The ACME client configuration template dynamically builds the SAN list:
+
+```perl
+<% for my $host (@$acme_hosts) {
+ # Skip ipv4/ipv6 subdomains - they're included as SANs in parent cert
+ next if $host =~ /^(ipv4|ipv6)\./;
+-%>
+<% my @alt_names = ("www.$host");
+ for my $sub_host (@$acme_hosts) {
+ if ($sub_host =~ /^(ipv4|ipv6)\.\Q$host\E$/) {
+ push @alt_names, $sub_host;
+ }
+ }
+-%>
+domain <%= $host %> {
+ alternative names { <%= join(' ', @alt_names) %> }
+ ...
+}
+<% } -%>
+```
+
+This generates a single certificate for `ipv6test.f3s.buetow.org` that includes:
+* www.ipv6test.f3s.buetow.org
+* ipv4.ipv6test.f3s.buetow.org
+* ipv6.ipv6test.f3s.buetow.org
+
+## DNS and TLS Deployment
+
+The DNS records and ACME certificates are managed via Rex automation:
+
+```perl
+our @f3s_hosts = qw/
+ ...
+ ipv6test.f3s.buetow.org
+ ipv4.ipv6test.f3s.buetow.org
+ ipv6.ipv6test.f3s.buetow.org
+/;
+
+our @acme_hosts = qw/
+ ...
+ ipv6test.f3s.buetow.org
+ ipv4.ipv6test.f3s.buetow.org
+ ipv6.ipv6test.f3s.buetow.org
+/;
+```
+
+Running `rex nsd httpd acme acme_invoke relayd` deploys the DNS zone, configures httpd for ACME challenges, obtains the certificates, and reloads relayd.
+
+## Testing
+
+Verify DNS records are correct:
+
+```sh
+$ dig ipv4.ipv6test.f3s.buetow.org A +short
+46.23.94.99
+
+$ dig ipv4.ipv6test.f3s.buetow.org AAAA +short
+(no output - IPv4 only)
+
+$ dig ipv6.ipv6test.f3s.buetow.org AAAA +short
+2a03:6000:6f67:624::99
+
+$ dig ipv6.ipv6test.f3s.buetow.org A +short
+(no output - IPv6 only)
+```
+
+Verify the application shows the correct test type:
+
+```sh
+$ curl -s https://ipv4.ipv6test.f3s.buetow.org/cgi-bin/index.pl | grep "Test Results"
+<h3>IPv4 Only Test Results:</h3>
+```
+
+The displayed IP should be the real client IP, not an internal cluster address.
+
+## W3C Compliant HTML
+
+The CGI script generates valid HTML5 that passes W3C validation. Key considerations:
+
+* Proper DOCTYPE, charset, and lang attributes
+* HTML-escaping command outputs (dig output contains `<<>>` characters)
+
+```perl
+sub html_escape {
+ my $str = shift;
+ $str =~ s/&/&amp;/g;
+ $str =~ s/</&lt;/g;
+ $str =~ s/>/&gt;/g;
+ return $str;
+}
+
+my $digremote = html_escape(`dig -x $ENV{REMOTE_ADDR}`);
+```
+
+You can verify the output passes validation:
+
+[W3C Validator](https://validator.w3.org/nu/?doc=https%3A%2F%2Fipv6test.f3s.buetow.org%2Fcgi-bin%2Findex.pl)
+
+## Summary
+
+Preserving client IP addresses through multiple reverse proxies requires configuration at each layer:
+
+1. **relayd**: Sets `X-Forwarded-For` header
+2. **Traefik**: Trusts headers from known proxy IPs via `forwardedHeaders.trustedIPs`
+3. **Apache**: Uses `mod_remoteip` to set `REMOTE_ADDR` from the header
+
+Additional challenges solved:
+
+* **TLS for IPv6-only hosts**: Use SANs to include all subdomains in a single certificate validated via the dual-stack parent domain
+* **W3C compliance**: HTML-escape all command outputs to handle special characters
+
+The configuration is managed via GitOps with ArgoCD, including the Traefik HelmChartConfig.
+
+[Source code](https://codeberg.org/snonux/ipv6test)
+[Kubernetes manifests](https://codeberg.org/snonux/conf/src/branch/master/f3s/ipv6test)
+[Traefik configuration](https://codeberg.org/snonux/conf/src/branch/master/f3s/traefik-config)
+
+E-Mail your comments to paul@paulbias.net :-)
+
+[← Back to the index](./index.md)
diff --git a/index.md b/index.md
index 1b853994..54eab337 100644
--- a/index.md
+++ b/index.md
@@ -1,6 +1,6 @@
# Hello!
-> This site was generated at 2026-01-27T10:09:14+02:00 by `Gemtexter`
+> This site was generated at 2026-01-31T19:49:46+02:00 by `Gemtexter`
Welcome to the foo.zone!
diff --git a/uptime-stats.md b/uptime-stats.md
index 3a5b47c5..a70fc7cf 100644
--- a/uptime-stats.md
+++ b/uptime-stats.md
@@ -1,6 +1,6 @@
# My machine uptime stats
-> This site was last updated at 2026-01-27T10:09:14+02:00
+> This site was last updated at 2026-01-31T19:49:46+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.
@@ -33,9 +33,9 @@ Boots is the total number of host boots over the entire lifespan.
| 10. | *makemake | 81 | Linux 6.9.9-200.fc40.x86_64 |
| 11. | uranus | 59 | NetBSD 10.1 |
| 12. | pluto | 51 | Linux 3.2.0-4-amd64 |
-| 13. | *fishfinger | 50 | OpenBSD 7.7 |
+| 13. | *mega-m3-pro | 50 | Darwin 24.6.0 |
| 14. | mega15289 | 50 | Darwin 23.4.0 |
-| 15. | *mega-m3-pro | 50 | Darwin 24.6.0 |
+| 15. | *fishfinger | 50 | OpenBSD 7.7 |
| 16. | *t450 | 46 | FreeBSD 14.2-RELEASE |
| 17. | *blowfish | 45 | OpenBSD 7.7 |
| 18. | phobos | 40 | Linux 3.4.0-CM-g1dd7cdf |
@@ -53,8 +53,8 @@ Uptime is the total uptime of a host over the entire lifespan.
| Pos | Host | Uptime | Last Kernel |
+-----+----------------+-----------------------------+-----------------------------------+
| 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 | 4 years, 1 months, 5 days | Linux 6.18.4-200.fc43.x86_64 |
+| 2. | *earth | 4 years, 1 months, 8 days | Linux 6.18.4-200.fc43.x86_64 |
+| 3. | *blowfish | 4 years, 1 months, 6 days | OpenBSD 7.7 |
| 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 |
@@ -64,7 +64,7 @@ Uptime is the total uptime of a host over the entire lifespan.
| 10. | tauceti | 2 years, 3 months, 19 days | Linux 3.2.0-4-amd64 |
| 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. | *mega-m3-pro | 1 years, 8 months, 3 days | Darwin 24.6.0 |
+| 13. | *mega-m3-pro | 1 years, 8 months, 8 days | Darwin 24.6.0 |
| 14. | *t450 | 1 years, 7 months, 26 days | FreeBSD 14.2-RELEASE |
| 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 |
@@ -98,8 +98,8 @@ Score is calculated by combining all other metrics.
| 13. | tauceti | 141 | Linux 3.2.0-4-amd64 |
| 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 | 108 | Darwin 24.6.0 |
+| 16. | *mega-m3-pro | 108 | Darwin 24.6.0 |
+| 17. | tauceti-f | 108 | Linux 3.2.0-3-amd64 |
| 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, 7 months, 4 days | Linux 6.18.4-200.fc43.x86_64 |
+| 5. | *earth | 4 years, 7 months, 8 days | Linux 6.18.4-200.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 |
@@ -164,7 +164,7 @@ Lifespan is the total uptime + the total downtime of a host.
| 17. | callisto | 2 years, 3 months, 13 days | Linux 4.0.4-303.fc22.x86_64 |
| 18. | tauceti-e | 2 years, 1 months, 29 days | Linux 3.2.0-4-amd64 |
| 19. | tauceti-f | 1 years, 9 months, 20 days | Linux 3.2.0-3-amd64 |
-| 20. | *mega-m3-pro | 1 years, 8 months, 31 days | Darwin 24.6.0 |
+| 20. | *mega-m3-pro | 1 years, 9 months, 4 days | Darwin 24.6.0 |
+-----+----------------+-----------------------------+-----------------------------------+
```
@@ -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. | OpenBSD 4... | 10 |
-| 20. | FreeBSD 7... | 10 |
+| 19. | FreeBSD 7... | 10 |
+| 20. | FreeBSD 6... | 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, 4 months, 5 days |
+| 5. | *Linux 6... | 3 years, 4 months, 8 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, 12 months, 11 days |
+| 12. | *Darwin 24... | 0 years, 12 months, 15 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... | 226 |
+| 5. | *Linux 6... | 227 |
| 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... | 64 |
+| 12. | *Darwin 24... | 65 |
| 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, 28 days |
+| 1. | *Linux | 28 years, 5 months, 1 days |
| 2. | *FreeBSD | 12 years, 10 months, 8 days |
| 3. | *OpenBSD | 8 years, 8 months, 18 days |
-| 4. | *Darwin | 5 years, 3 months, 25 days |
+| 4. | *Darwin | 5 years, 3 months, 29 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 | 1885 |
+| 1. | *Linux | 1886 |
| 2. | *FreeBSD | 912 |
| 3. | *OpenBSD | 557 |
-| 4. | *Darwin | 345 |
+| 4. | *Darwin | 346 |
| 5. | NetBSD | 0 |
+-----+------------+-------+
```