summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorPaul Buetow <paul@buetow.org>2026-01-24 14:28:45 +0200
committerPaul Buetow <paul@buetow.org>2026-01-24 14:28:45 +0200
commit9a57015b6fc729f8da37c42957733f1afb657be8 (patch)
tree774ef9238a847929c7d68da8a18d0335e21ecd5e
parent4d27f91ea6e61020902fbb2ed916225b69866275 (diff)
Add f3s hosts to ACME certificate management
- Add all 18 f3s hosts to @acme_hosts for certificate issuance - Skip standby certificate variants for f3s hosts (not needed for k3s cluster) - Add port 80 ACME challenge blocks to httpd for all f3s hosts - Add port 8080 fallback page blocks to httpd for f3s hosts (when cluster is down) - Update relayd.conf.tpl to skip standby keypairs for f3s hosts - Update acme-client.conf.tpl to skip standby certificates for f3s hosts Fixes missing certificates on flux.f3s.buetow.org, anki.f3s.buetow.org, and other f3s services
-rw-r--r--frontends/Rexfile2
-rw-r--r--frontends/etc/acme-client.conf.tpl2
-rw-r--r--frontends/etc/httpd.conf.tpl16
-rw-r--r--frontends/etc/relayd.conf.tpl2
-rw-r--r--frontends/scripts/foostats.pl22
5 files changed, 26 insertions, 18 deletions
diff --git a/frontends/Rexfile b/frontends/Rexfile
index e41b55a..4e5fecf 100644
--- a/frontends/Rexfile
+++ b/frontends/Rexfile
@@ -82,7 +82,7 @@ our @f3s_hosts =
our @dns_zones = qw/buetow.org dtail.dev foo.zone irregular.ninja snonux.foo/;
our @dns_zones_remove = qw/paul.cyou/;
our @acme_hosts =
- qw/buetow.org git.buetow.org paul.buetow.org dory.buetow.org ecat.buetow.org fotos.buetow.org znc.buetow.org dtail.dev foo.zone irregular.ninja alt.irregular.ninja snonux.foo gogios.buetow.org blowfish.buetow.org fishfinger.buetow.org/;
+ qw/buetow.org git.buetow.org paul.buetow.org dory.buetow.org ecat.buetow.org fotos.buetow.org znc.buetow.org dtail.dev foo.zone irregular.ninja alt.irregular.ninja snonux.foo gogios.buetow.org blowfish.buetow.org fishfinger.buetow.org f3s.buetow.org git.f3s.buetow.org cgit.f3s.buetow.org immich.f3s.buetow.org argocd.f3s.buetow.org keybr.f3s.buetow.org anki.f3s.buetow.org bag.f3s.buetow.org flux.f3s.buetow.org audiobookshelf.f3s.buetow.org grafana.f3s.buetow.org radicale.f3s.buetow.org vault.f3s.buetow.org syncthing.f3s.buetow.org uprecords.f3s.buetow.org koreader.f3s.buetow.org filebrowser.f3s.buetow.org webdav.f3s.buetow.org/;
# WireGuard IP addresses for ping checks
our %wg0_ips = (
diff --git a/frontends/etc/acme-client.conf.tpl b/frontends/etc/acme-client.conf.tpl
index 685794c..b99b428 100644
--- a/frontends/etc/acme-client.conf.tpl
+++ b/frontends/etc/acme-client.conf.tpl
@@ -31,9 +31,11 @@ domain <%= $host %> {
domain full chain certificate "/etc/ssl/<%= $host %>.fullchain.pem"
sign with letsencrypt
}
+<% unless (grep { $_ eq $host } @$f3s_hosts) { -%>
domain standby.<%= $host %> {
domain key "/etc/ssl/private/standby.<%= $host %>.key"
domain full chain certificate "/etc/ssl/standby.<%= $host %>.fullchain.pem"
sign with letsencrypt
}
<% } -%>
+<% } -%>
diff --git a/frontends/etc/httpd.conf.tpl b/frontends/etc/httpd.conf.tpl
index 6a313ae..24889d5 100644
--- a/frontends/etc/httpd.conf.tpl
+++ b/frontends/etc/httpd.conf.tpl
@@ -175,9 +175,21 @@ server "<%= $prefix %>gogios.buetow.org" {
}
<% } -%>
-# Fallback for f3s hosts - serve fallback page for ALL paths
+# f3s hosts: ACME challenges on port 80, fallback page on port 8080 (served by master when k3s cluster is down)
<% for my $host (@$f3s_hosts) { for my $prefix (@prefixes) { -%>
-server "<%= $prefix.$host %>" {
+server "<%= $prefix.$host %>-port80" {
+ listen on * port 80
+ log style forwarded
+ location "/.well-known/acme-challenge/*" {
+ root "/acme"
+ request strip 2
+ }
+ location * {
+ block return 302 "https://$HTTP_HOST$REQUEST_URI"
+ }
+}
+
+server "<%= $prefix.$host %>-port8080" {
listen on * port 8080
log style forwarded
location * {
diff --git a/frontends/etc/relayd.conf.tpl b/frontends/etc/relayd.conf.tpl
index b04ecd3..0a7283f 100644
--- a/frontends/etc/relayd.conf.tpl
+++ b/frontends/etc/relayd.conf.tpl
@@ -26,8 +26,10 @@ http protocol "https" {
# Skip server hostnames - each server only has its own cert, handled by dedicated keypair below
next if $host eq 'blowfish.buetow.org' or $host eq 'fishfinger.buetow.org'; -%>
tls keypair <%= $host %>
+ <% unless (grep { $_ eq $host } @$f3s_hosts) { -%>
tls keypair standby.<%= $host %>
<% } -%>
+ <% } -%>
tls keypair <%= $hostname.'.'.$domain -%>
# Enable WebSocket support
diff --git a/frontends/scripts/foostats.pl b/frontends/scripts/foostats.pl
index a440d94..a327e67 100644
--- a/frontends/scripts/foostats.pl
+++ b/frontends/scripts/foostats.pl
@@ -15,7 +15,7 @@ no warnings qw(experimental::refaliasing);
# Debugging aids like diagnostics are noisy in production.
# Removed per review: enable locally when debugging only.
-use constant VERSION => 'v0.1.0';
+use constant VERSION => 'v0.2.0';
# Package: FileHelper — small file/JSON helpers
# - Purpose: Atomic writes, gzip JSON read/write, and line reading.
@@ -959,11 +959,7 @@ package Foostats::Reporter {
# Convert .gmi links to .html
$url =~ s/\.gmi$/\.html/;
- return
- "<p><a href=\""
- . encode_entities($url) . "\">"
- . encode_entities($text)
- . "</a></p>\n";
+ return "<p><a href=\"" . encode_entities($url) . "\">" . encode_entities($text) . "</a></p>\n";
}
return '';
}
@@ -1546,8 +1542,7 @@ $content
push @summary_rows, build_daily_summary_row($date, $stats);
}
- $content .= format_table([ 'Date', 'Filtered', 'Gemini', 'Web', 'IPv4', 'IPv6', 'Total' ],
- \@summary_rows);
+ $content .= format_table([ 'Date', 'Filtered', 'Gemini', 'Web', 'IPv4', 'IPv6', 'Total' ], \@summary_rows);
$content .= "\n```\n\n";
return $content;
@@ -1590,9 +1585,7 @@ $content
push @feed_rows, build_feed_statistics_row($date, $stats);
}
- $content .=
- format_table([ 'Date', 'Gem Feed', 'Gem Atom', 'Web Feed', 'Web Atom', 'Total' ],
- \@feed_rows);
+ $content .= format_table([ 'Date', 'Gem Feed', 'Gem Atom', 'Web Feed', 'Web Atom', 'Total' ], \@feed_rows);
$content .= "\n```\n\n";
return $content;
@@ -1865,8 +1858,8 @@ sub foostats_main {
my $stats_dir = '/var/www/htdocs/buetow.org/self/foostats';
my $odds_file = $stats_dir . '/fooodds.txt';
my $odds_log = '/var/log/fooodds';
- my $output_dir; # Will default to $stats_dir/gemtext if not specified
- my $html_output_dir; # Will default to /var/www/htdocs/gemtexter/stats.foo.zone if not specified
+ my $output_dir; # Will default to $stats_dir/gemtext if not specified
+ my $html_output_dir; # Will default to /var/www/htdocs/gemtexter/stats.foo.zone if not specified
my $partner_node =
hostname eq 'fishfinger.buetow.org'
? 'blowfish.buetow.org'
@@ -1900,8 +1893,7 @@ sub foostats_main {
$output_dir //= '/var/gemini/stats.foo.zone';
$html_output_dir //= '/var/www/htdocs/gemtexter/stats.foo.zone';
- Foostats::Reporter::report($stats_dir, $output_dir, $html_output_dir,
- Foostats::Merger::merge($stats_dir))
+ Foostats::Reporter::report($stats_dir, $output_dir, $html_output_dir, Foostats::Merger::merge($stats_dir))
if $report
or $all;
}