snoottube-ops/configs/frontend.nix

304 lines
9.3 KiB
Nix

{ config, pkgs, nixpkgs, globalServiceConfig, ... }:
let
fallback_www_content = pkgs.stdenv.mkDerivation {
name = "fallback-www-content";
version = "1.0.0";
phases = "installPhase";
installPhase = ''
mkdir -p $out
echo "sorry, we're temporarily offline at the moment. please check back later!" > $out/error.html;
'';
};
in {
networking.firewall.enable = true;
networking.firewall.allowedTCPPorts = [ 80 443 6922 ];
networking.firewall.allowedUDPPorts = [ 51869 ];
networking.firewall.checkReversePath = "loose";
fileSystems."/" = {
autoResize = true; # embiggen
};
swapDevices = [{
device = "/swapfile";
size = 512;
}];
# extra blocks sourced from https://git.pixie.town/f0x/nixos/src/branch/main/nodes/aura/configuration.nix#L100
networking.firewall.extraCommands = builtins.concatStringsSep "\n" (builtins.map (ip: "iptables -A INPUT -s ${ip} -j DROP") [
"158.101.19.243" # full-text search scraper https://macaw.social/@angilly/109597402157254670
"207.231.106.226" # fediverse.network / fedi.ninja
"45.81.20.80" # instances.social
"198.58.122.231" # fedimapper.tedivm.com
"142.93.3.121" # fedidb.org
"45.158.40.164" # fedi.buzz
"170.39.215.216" # fediverse.observer
"87.157.136.163" # fedi_stats
"94.31.103.67" # python/federation
"45.56.100.29" # scottherr? same as :5a13
"138.37.89.34"
"104.21.80.126" # gangstalking.services
"172.67.181.16" # gangstalking.services
"198.98.54.220" # ryona.agency
]) + "\n" + builtins.concatStringsSep "\n" (builtins.map (ip: "ip6tables -A INPUT -s ${ip} -j DROP") [
"2003:cb:ff2c:2700:d0f2:6433:729c:158e" # fedi_stats
"2600:3c02::f03c:92ff:feca:9fa6" # scottherr stats
"2600:3c03::f03c:93ff:fe42:5a14" # unknown, tries public tl access
"2606:4700:3034::ac43:b510" # gangstalking.services
"2606:4700:3031::6815:507e" # gangstalking.services
"2605:6400:10:1fe:dead:babe:b00b:cafe" # ryona.agency
]);
networking.hostName = "inhale";
services.openssh.enable = true;
services.openssh.passwordAuthentication = false;
services.openssh.gatewayPorts = "yes";
services.openssh.listenAddresses = [
{ addr = "0.0.0.0"; port = 6922; }
];
services.prometheus_exporters = {
enable = true;
nodePort = 19982;
systemdPort = 19983;
combinedPort = 19980;
};
security.acme.acceptTerms = true;
security.acme.defaults.email = "vivlim@pm.me";
#security.acme.defaults.server = "https://acme-staging-v02.api.letsencrypt.org/directory"; # staging letsencrypt
services.fail2ban = {
enable = true;
};
services.nginx = {
enable = true;
recommendedProxySettings = true;
recommendedTlsSettings = true;
virtualHosts."snoot.tube" = {
forceSSL = true;
enableACME = true;
locations."/" = {
proxyPass = "https://backend_ssh"; # ssh forwarded
proxyWebsockets = true;
extraConfig = ''
proxy_set_header Connection "";
'';
};
locations."/robots.txt" = {
extraConfig = ''
return 200 'User-agent: *\nDisallow: /';
add_header Content-Type text/plain;
'';
};
locations."/sleeping/" = let
sleeping = builtins.fetchGit {
#url = "https://git.sleeping.town/unascribed/Sleeping4.git";
#rev = "999cee9611bf0ff9cff826d94151855561250489";
url = "https://git.vvn.space/vivlim/Sleeping4.git";
ref = "refs/heads/snoot";
rev = "85ecd0c5d9355492c46169bee9c9f97b4cdd7d44";
};
in {
alias = "${sleeping}/";
};
};
virtualHosts."dev.snoot.tube" = {
forceSSL = true;
enableACME = true;
locations."/" = {
proxyPass = "https://backend_ssh"; # ssh forwarded
proxyWebsockets = true;
extraConfig = ''
proxy_set_header Connection "";
'';
};
locations."/robots.txt" = {
extraConfig = ''
return 200 'User-agent: *\nDisallow: /';
add_header Content-Type text/plain;
'';
};
locations."/sleeping/" = {
proxyPass = "https://vvn.space/vivlim/sleeping/";
};
};
virtualHosts."awake.snoot.tube" = {
forceSSL = true;
enableACME = true;
locations."/" = {
proxyPass = "https://backend_ssh"; # ssh forwarded
proxyWebsockets = true;
extraConfig = ''
proxy_set_header Connection "";
'';
};
locations."/robots.txt" = {
extraConfig = ''
return 200 'User-agent: *\nDisallow: /';
add_header Content-Type text/plain;
'';
};
locations."/sleeping/sleeping.js" = {
extraConfig = ''
return 200 'console.log("woke mode engaged");';
add_header Content-Type text/javascript;
'';
};
locations."/sleeping/sleeping.css" = {
extraConfig = ''
return 200 '/* nothing here */';
add_header Content-Type text/css;
'';
};
};
upstreams.backend_ssh = {
servers = {
"localhost:4433" = { };
};
extraConfig = ''
keepalive 32;
keepalive_timeout 30s;
'';
};
appendHttpConfig = ''
log_format mylogformat '$remote_addr - $remote_user [$time_local] "$request" '
'$status $body_bytes_sent "$http_referer" '
'"$http_user_agent" $geoip_country_name $upstream_response_time $request_time';
access_log /var/log/nginx/access.log mylogformat buffer=4096 flush=15s;
'';
};
services._3proxy = {
enable = true;
denyPrivate = true;
resolution = {
nserver = [
"127.0.0.1:53"
];
};
services = [
{
type = "proxy";
bindAddress = "127.0.0.1";
bindPort = 3128;
auth = [ "none" ];
}
];
extraConfig = ''
'';
};
services.dnscrypt-proxy2 = {
enable = true;
settings = {
sources.quad9-resolvers = {
urls = [ "https://quad9.net/dnscrypt/quad9-resolvers.md" "https://raw.githubusercontent.com/Quad9DNS/dnscrypt-settings/main/dnscrypt/quad9-resolvers.md" ];
minisign_key = "RWQBphd2+f6eiAqBsvDZEBXBGHQBJfeG6G+wJPPKxCZMoEQYpmoysKUN";
cache_file = "/var/lib/private/dnscrypt-proxy/quad9-resolvers.md";
refresh_delay = 72;
prefix = "quad9-";
};
bootstrap_resolvers = ["9.9.9.9:53" "8.8.8.8:53"];
ignore_system_dns = true;
netprobe_timeout = 60;
netprobe_address = "9.9.9.9:53";
# filters for which resolvers to use
require_dnssec = false;
require_nolog = true;
require_nofilter = true;
block_ipv6 = true;
keepalive = 30; # seconds
timeout = 5000; # ms
listen_addresses = [ "127.0.0.1:53" ];
log_level = 0; # *so* verbose.
cache = false; # no dns cache needed, 3proxy will cache resolved names.
query_log.file = "/dev/stdout"; # log queries to stdout.
nx_log.file = "/dev/stdout"; # log *suspicious* queries to stdout.
};
upstreamDefaults = false; # just use the config defined here
};
systemd.services.prometheus-nginxlog-exporter = {
description = "nginx prometheus exporter";
wantedBy = [ "multi-user.target" ];
after = [ "container@mastodon.service" ];
serviceConfig = let
configFile = pkgs.writeText "config.hcl" ''
listen {
port = 4040
address = "127.0.0.1"
metrics_endpoint = "/metrics"
}
namespace "nginx" {
# 192.168.42.11 - - [11/Jan/2023:10:59:57 -0800] "GET /api/v1/announcements HTTP/1.1" 200 752 "https://snoot.tube/" "Mozilla/5.0 (X11; Linux x86_64; rv:104.0) Gecko/20100101 Firefox/104.0"
format = "$remote_addr - $remote_user [$time_local] \"$request\" $status $body_bytes_sent \"$http_referer\" \"$http_user_agent\" $geoip_country_name $upstream_response_time $request_time"
#relabel "remote_addr" { from = "remote_addr" }
relabel "status" { from = "status" }
#relabel "http_referer" { from = "http_referer" }
#relabel "http_user_agent" { from = "http_user_agent" }
relabel "user_agent_uri" {
from = "http_user_agent"
only_counter = true
match "^.*(https://[a-zA-Z0-9./]+).*$" {
replacement = "$1"
}
}
source {
files = [
"/var/log/nginx/access.log"
]
}
labels {
app = "snoot"
}
histogram_buckets = [.05, .1, .5, 1, 5, 10]
}
'';
# validate config at build time
configFileValidated = pkgs.stdenv.mkDerivation {
name = "prometheus-nginxlog-exporter-validated-config.hcl";
phases = "installPhase";
installPhase = ''
${pkgs.prometheus-nginxlog-exporter}/bin/prometheus-nginxlog-exporter -config-file ${configFile} -verify-config && cp ${configFile} $out
'';
};
in {
ExecStart = "${pkgs.prometheus-nginxlog-exporter}/bin/prometheus-nginxlog-exporter -config-file ${configFileValidated}";
};
};
environment.systemPackages = [
pkgs.dig.dnsutils
];
users.users.root = {
openssh.authorizedKeys.keys = [
"ssh-ed25519 AAAAC3NzaC1lZDI1NTE5AAAAIP2gCRemxVT9fLxHn0kqYlE0BkPX3mOstVJlEzTCGLbl root@nixos" # backend uses this key
];
};
}