feat: init
This commit is contained in:
commit
8cfede9f57
28 changed files with 2129 additions and 0 deletions
162
modules/wiki-primary/caddy.nix
Normal file
162
modules/wiki-primary/caddy.nix
Normal file
|
|
@ -0,0 +1,162 @@
|
|||
{ config, pkgs, lib, ... }:
|
||||
{
|
||||
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 = {
|
||||
"www.noisebridge.net" = {
|
||||
extraConfig = ''
|
||||
# Health check endpoint
|
||||
handle /health {
|
||||
respond "ok" 200
|
||||
}
|
||||
|
||||
# Bot blocking
|
||||
@bots header_regexp User-Agent "(?i)(ClaudeBot|GPTBot|CCBot|Bytespider|AhrefsBot|SemrushBot|MJ12bot|DotBot|PetalBot|Amazonbot|anthropic-ai|ChatGPT-User|cohere-ai|FacebookBot|Google-Extended|PerplexityBot)"
|
||||
respond @bots 403
|
||||
|
||||
# robots.txt
|
||||
handle /robots.txt {
|
||||
respond "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
|
||||
"
|
||||
}
|
||||
|
||||
# Rate limiting for anonymous users (no session cookie)
|
||||
# {client_ip} works with or without a reverse proxy in front
|
||||
@anon {
|
||||
not header_regexp Cookie "nb_wiki_session="
|
||||
}
|
||||
rate_limit @anon {
|
||||
zone anon_zone {
|
||||
key {client_ip}
|
||||
events 60
|
||||
window 1m
|
||||
}
|
||||
}
|
||||
|
||||
# Cache headers: anon gets public caching, logged-in gets private
|
||||
@logged_in {
|
||||
header_regexp Cookie "nb_wiki_session="
|
||||
}
|
||||
header @anon Cache-Control "public, max-age=7200"
|
||||
header @logged_in Cache-Control "private, no-cache"
|
||||
|
||||
# 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"
|
||||
}
|
||||
|
||||
# Proxy to PHP-FPM
|
||||
php_fastcgi unix//run/phpfpm/mediawiki.sock {
|
||||
root ${config.services.mediawiki.finalPackage}/share/mediawiki
|
||||
}
|
||||
|
||||
file_server {
|
||||
root ${config.services.mediawiki.finalPackage}/share/mediawiki
|
||||
}
|
||||
'';
|
||||
};
|
||||
|
||||
"grafana.noisebridge.net" = {
|
||||
extraConfig = ''
|
||||
reverse_proxy localhost:3000
|
||||
'';
|
||||
};
|
||||
|
||||
# Domain redirects
|
||||
"noisebridge.net" = {
|
||||
extraConfig = ''
|
||||
redir https://www.noisebridge.net{uri} permanent
|
||||
'';
|
||||
};
|
||||
|
||||
"noisebridge.com" = {
|
||||
extraConfig = ''
|
||||
redir https://www.noisebridge.net{uri} permanent
|
||||
'';
|
||||
};
|
||||
|
||||
"noisebridge.org" = {
|
||||
extraConfig = ''
|
||||
redir https://www.noisebridge.net{uri} permanent
|
||||
'';
|
||||
};
|
||||
|
||||
"noisebridge.io" = {
|
||||
extraConfig = ''
|
||||
redir https://www.noisebridge.net{uri} permanent
|
||||
'';
|
||||
};
|
||||
|
||||
# ── Tor .onion vhost ──
|
||||
# Tor daemon forwards port 80 → localhost:8080. Caddy listens here
|
||||
# with HTTP only (no TLS — .onion v3 is already end-to-end encrypted).
|
||||
#
|
||||
# Differences from the clearnet vhost:
|
||||
# - No IP-based rate limiting (all Tor traffic arrives from 127.0.0.1)
|
||||
# - No HSTS (no TLS to enforce)
|
||||
# - No Cache-Control: public (no CDN to cache at)
|
||||
# - Bot blocking by User-Agent still works
|
||||
":8080" = {
|
||||
extraConfig = ''
|
||||
# Bot blocking (same list as clearnet)
|
||||
@bots header_regexp User-Agent "(?i)(ClaudeBot|GPTBot|CCBot|Bytespider|AhrefsBot|SemrushBot|MJ12bot|DotBot|PetalBot|Amazonbot|anthropic-ai|ChatGPT-User|cohere-ai|FacebookBot|Google-Extended|PerplexityBot)"
|
||||
respond @bots 403
|
||||
|
||||
# robots.txt — block everything on .onion (no reason for bots to index)
|
||||
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-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
|
||||
}
|
||||
'';
|
||||
};
|
||||
};
|
||||
};
|
||||
|
||||
# Port 8080 is only for local Tor daemon — not public
|
||||
# (firewall already blocks it since it's not in allowedTCPPorts)
|
||||
}
|
||||
Loading…
Add table
Add a link
Reference in a new issue