Files
haschel/modules/proxy.nix
Atridad Lahiji cc6460c078
All checks were successful
Deploy NixOS / deploy (push) Successful in 35s
This is much funnier
2026-03-06 16:50:02 -07:00

197 lines
6.5 KiB
Nix

{
config,
lib,
pkgs,
...
}:
let
atriDotDad = "atri.dad";
atashDotDev = "atash.dev";
matrixDomain = "matrix.${atriDotDad}";
matrixRtcDomain = "matrixrtc.${atriDotDad}";
upstream = "lloyd.tadpole-pain.ts.net";
streamPorts = [
69
420
25565
25566
25567
];
wellKnownServer = builtins.toJSON {
"m.server" = "${matrixDomain}:443";
};
wellKnownClient = builtins.toJSON {
"m.homeserver" = {
base_url = "https://${matrixDomain}";
};
"org.matrix.msc4143.rtc_foci" = [
{
type = "livekit";
livekit_service_url = "https://${matrixDomain}/livekit/jwt";
}
];
};
mkProxy = port: ''
import common_config
reverse_proxy http://${upstream}:${toString port}
'';
aiBotsMatcher = ''
@fuckai {
header_regexp User-Agent "(?i)(GPTBot|ChatGPT-User|OAI-SearchBot|ChatGPT-Browser|ClaudeBot|Claude-Web|Claude-SearchBot|anthropic-ai|Anthropic-Claude|xAI-Bot|DeepseekBot|Google-Extended|Gemini-Ai|Gemini-Deep-Research|Google-CloudVertexBot|Google-NotebookLM|GoogleAgent-Mariner|Bard-Ai|FacebookBot|Meta-ExternalAgent|meta-webindexer|Applebot-Extended|bingbot|CCBot|PerplexityBot|Perplexity-User|Bytespider|Diffbot|Amazonbot|cohere-ai|Cohere-Command|YouBot|Omgilibot|ImagesiftBot|AI2Bot|Andibot|bigsur.ai|Brightbot|TerraCotta|Character-AI|Devin|Crawlspace|DuckAssistBot|FirecrawlAgent|Groq-Bot|HuggingFace-Bot|IbouBot|MistralAI-User|Replicate-Bot|RunPod-Bot|TimpiBot|Together-Bot|Kangaroo Bot|PanguBot|Cotoyogi|Webzio-Extended)"
}
# Intercept bots immediately.
# Because this 'handle' is at the top, it runs first and prevents other handles from executing.
handle @fuckai {
respond "Lorem ipsum dolor sit amet, consectetur adipiscing elit. Aliquam blandit ac neque in imperdiet. Suspendisse ullamcorper eu velit in volutpat. Lorem ipsum dolor sit amet, consectetur adipiscing elit. Suspendisse potenti. Cras non risus id lacus suscipit suscipit eget ac ex. Vestibulum vulputate diam a arcu imperdiet commodo. Etiam magna turpis, auctor ut tincidunt non, sodales eu diam. Suspendisse euismod lorem ultrices, euismod augue in, fermentum velit. Praesent nec enim vitae nibh mollis fringilla." 403
}
'';
mkSocatService =
port: proto:
lib.nameValuePair "socat-${proto}-${toString port}" {
description = "Socat ${proto} proxy for port ${toString port}";
after = [
"network-online.target"
"tailscaled.service"
];
wants = [ "network-online.target" ];
wantedBy = [ "multi-user.target" ];
serviceConfig = {
ExecStart = "${pkgs.socat}/bin/socat ${lib.toUpper proto}-LISTEN:${toString port},fork,reuseaddr ${lib.toUpper proto}:${upstream}:${toString port}";
Restart = "on-failure";
RestartSec = "5s";
DynamicUser = true;
AmbientCapabilities = [ "CAP_NET_BIND_SERVICE" ];
};
};
in
{
services.caddy = {
enable = true;
email = "me@${atriDotDad}";
extraConfig = ''
(common_config) {
# Enable Zstandard and Gzip compression
encode zstd gzip
header {
Strict-Transport-Security "max-age=31536000; includeSubDomains; preload"
X-Content-Type-Options "nosniff"
X-Frame-Options "DENY"
Referrer-Policy "strict-origin-when-cross-origin"
}
}
${atriDotDad} {
import common_config
${aiBotsMatcher}
handle /.well-known/matrix/server {
header Content-Type application/json
header X-Content-Type-Options nosniff
respond `${wellKnownServer}` 200
}
handle /.well-known/matrix/client {
header Content-Type application/json
header Access-Control-Allow-Origin "*"
header Vary Origin
header X-Content-Type-Options nosniff
respond `${wellKnownClient}` 200
}
handle {
reverse_proxy http://${upstream}:3000
}
}
analytics.${atriDotDad} { ${aiBotsMatcher} ${mkProxy 30060} }
archive.${atriDotDad} { ${aiBotsMatcher} ${mkProxy 30288} }
ascently.${atriDotDad} { ${aiBotsMatcher} ${mkProxy 8838} }
chef.${atriDotDad} { ${aiBotsMatcher} ${mkProxy 30111} }
democlimb.${atriDotDad} { ${aiBotsMatcher} ${mkProxy 8008} }
fedi.${atriDotDad} { ${aiBotsMatcher} ${mkProxy 8181} }
gist.${atriDotDad} { ${aiBotsMatcher} ${mkProxy 1227} }
git.${atriDotDad} { ${aiBotsMatcher} ${mkProxy 30010} }
links.${atriDotDad} { ${aiBotsMatcher} ${mkProxy 30243} }
memos.${atriDotDad} { ${aiBotsMatcher} ${mkProxy 30311} }
mermaid.${atriDotDad} { ${aiBotsMatcher} ${mkProxy 8280} }
msrc.${atriDotDad} { ${aiBotsMatcher} ${mkProxy 3311} }
openclimb.${atriDotDad} { ${aiBotsMatcher} ${mkProxy 1337} }
photos.${atriDotDad} { ${aiBotsMatcher} ${mkProxy 30041} }
pods.${atriDotDad} { ${aiBotsMatcher} ${mkProxy 30067} }
requests.${atriDotDad} { ${aiBotsMatcher} ${mkProxy 30042} }
s3.${atriDotDad} { ${aiBotsMatcher} ${mkProxy 30188} }
search.${atriDotDad} { ${aiBotsMatcher} ${mkProxy 30053} }
vault.${atriDotDad} { ${aiBotsMatcher} ${mkProxy 30032} }
vids.${atriDotDad} { ${aiBotsMatcher} ${mkProxy 31008} }
music.${atriDotDad} { ${aiBotsMatcher} ${mkProxy 30043} }
books.${atriDotDad} { ${aiBotsMatcher} ${mkProxy 31067} }
tv.${atriDotDad} {
${aiBotsMatcher}
request_body {
max_size 20GB
}
reverse_proxy http://${upstream}:30013 {
flush_interval -1
}
}
${matrixDomain} {
request_body {
max_size 100MB
}
handle_path /livekit/jwt/* {
@allowed path /sfu/get /get_token /healthz
handle @allowed {
reverse_proxy http://[::1]:${toString config.services.lk-jwt-service.port}
}
handle {
respond 404
}
}
handle {
reverse_proxy http://[::1]:6167
}
}
${matrixRtcDomain} {
reverse_proxy http://[::1]:${toString config.services.livekit.settings.port} {
flush_interval -1
}
}
ripkyle.org { ${aiBotsMatcher} ${mkProxy 4321} }
${atashDotDev} { ${aiBotsMatcher} ${mkProxy 6969} }
chronus.${atashDotDev} { ${aiBotsMatcher} ${mkProxy 7337} }
'';
};
systemd.services = lib.listToAttrs (
(map (port: mkSocatService port "tcp") streamPorts)
++ (map (port: mkSocatService port "udp") streamPorts)
);
networking.firewall = {
allowedTCPPorts = [
80
443
]
++ streamPorts;
allowedUDPPorts = streamPorts;
};
}