feat: init
Some checks failed
CI / check (push) Has been cancelled
CI / deploy (push) Has been cancelled

This commit is contained in:
Jet 2026-03-17 04:07:14 -07:00
commit 8cfede9f57
No known key found for this signature in database
28 changed files with 2129 additions and 0 deletions

View file

@ -0,0 +1,129 @@
{ config, pkgs, lib, ... }:
let
botPattern = ''(?i)(ClaudeBot|GPTBot|CCBot|Bytespider|AhrefsBot|SemrushBot|MJ12bot|DotBot|PetalBot|Amazonbot|anthropic-ai|ChatGPT-User|cohere-ai|FacebookBot|Google-Extended|PerplexityBot)'';
robotsTxt = ''
User-agent: ClaudeBot
Disallow: /
User-agent: GPTBot
Disallow: /
User-agent: CCBot
Disallow: /
User-agent: Bytespider
Disallow: /
User-agent: anthropic-ai
Disallow: /
User-agent: ChatGPT-User
Disallow: /
User-agent: *
Allow: /
Sitemap: https://www.noisebridge.net/sitemap.xml
'';
# Shared clearnet config for www and readonly vhosts
commonConfig = ''
# Health check endpoint
handle /health {
respond "ok" 200
}
# Bot blocking
@bots header_regexp User-Agent "${botPattern}"
respond @bots 403
# robots.txt
handle /robots.txt {
respond "${robotsTxt}"
}
# Rate limiting for anonymous users
# {client_ip} works with or without a reverse proxy in front
@anon {
not header_regexp Cookie "nb_wiki_session="
}
rate_limit @anon {
zone replica_zone {
key {client_ip}
events 60
window 1m
}
}
# Cache headers (read-only replica — everything is public-cacheable)
header Cache-Control "public, max-age=7200"
# Security headers
header {
Strict-Transport-Security "max-age=63072000; includeSubDomains; preload"
X-Content-Type-Options "nosniff"
X-Frame-Options "SAMEORIGIN"
Referrer-Policy "strict-origin-when-cross-origin"
X-Wiki-Mode "read-only"
}
php_fastcgi unix//run/phpfpm/mediawiki.sock {
root ${config.services.mediawiki.finalPackage}/share/mediawiki
}
file_server {
root ${config.services.mediawiki.finalPackage}/share/mediawiki
}
'';
in
{
services.caddy = {
enable = true;
package = pkgs.caddy-custom;
globalConfig = ''
order rate_limit before basicauth
servers {
# Trust Cloudflare's edge IPs so {client_ip} resolves to the real visitor
trusted_proxies static 173.245.48.0/20 103.21.244.0/22 103.22.200.0/22 103.31.4.0/22 141.101.64.0/18 108.162.192.0/18 190.93.240.0/20 188.114.96.0/20 197.234.240.0/22 198.41.128.0/17 162.158.0.0/15 104.16.0.0/13 104.24.0.0/14 172.64.0.0/13 131.0.72.0/22 2400:cb00::/32 2606:4700::/32 2803:f800::/32 2405:b500::/32 2405:8100::/32 2a06:98c0::/29 2c0f:f248::/32
metrics
}
'';
virtualHosts = {
"readonly.noisebridge.net" = {
extraConfig = commonConfig;
};
# ── Tor .onion vhost ──
# Tor daemon forwards port 80 → localhost:8080
# HTTP only, no TLS (.onion v3 is end-to-end encrypted)
# Read-only (same as clearnet replica)
":8080" = {
extraConfig = ''
# Bot blocking
@bots header_regexp User-Agent "${botPattern}"
respond @bots 403
# robots.txt — block everything on .onion
handle /robots.txt {
respond "User-agent: *
Disallow: /
"
}
# Security headers (no HSTS — no TLS over .onion)
header {
X-Content-Type-Options "nosniff"
X-Frame-Options "SAMEORIGIN"
Referrer-Policy "no-referrer"
X-Wiki-Mode "read-only"
X-Wiki-Access "tor"
}
php_fastcgi unix//run/phpfpm/mediawiki.sock {
root ${config.services.mediawiki.finalPackage}/share/mediawiki
}
file_server {
root ${config.services.mediawiki.finalPackage}/share/mediawiki
}
'';
};
};
};
}