{ config, hostRegistry, lib, pkgs, ... }: { microvm = { # Running on server10 which has 40 threads on 20 cores vcpu = 8; # drone-ssh-runner clones the git repo into tmpfs which requires some RAM mem = 2 * 1024; }; # drone-ssh-runner clones into /tmp which needs to be bigger than the default rootfs tmpfs boot.tmp = { useTmpfs = true; tmpfsSize = "80%"; }; c3d2.deployment = { # /tmp is to small for drone to clone the repo even with depth mounts = lib.mkOptionDefault [ "tmp" ]; server = "server10"; }; system.stateVersion = "22.05"; networking = { hostName = "c3d2-web"; firewall.allowedTCPPorts = [ # telme10 23 # gemini 1965 ]; }; security.acme.certs = { # agate cannot load modern crypto like "ec256" keys "www.c3d2.de".keyType = "rsa4096"; }; services.nginx = { enable = true; virtualHosts = { "www.c3d2.de" = { default = true; serverAliases = [ "c3d2.de" "c3dd.de" "www.c3dd.de" "openpgpkey.c3d2.de" "cccdd.de" "www.cccdd.de" "dresden.ccc.de" "www.dresden.ccc.de" "netzbiotop.org" "www.netzbiotop.org" ]; enableACME = true; forceSSL = true; root = "/var/www/c3d2"; extraConfig = '' index portal.html index.html; ''; locations = { # Mastodon "~ ^/\\.well-known/webfinger".return = "301 https://c3d2.social/.well-known/webfinger?resource=acct%3ac3d2%40c3d2.social"; # Matrix "~ ^/\\.well-known/matrix/server" = { return = "200 '{\"m.server\": \"matrix.c3d2.de:443\"}'"; extraConfig = '' default_type application/json; ''; }; "~ ^/\\.well-known/matrix/client" = { return = "200 '{\"m.homeserver\": {\"base_url\": \"https://matrix.c3d2.de\"}}'"; extraConfig = /* nginx */ '' default_type application/json; add_header "Access-Control-Allow-Origin" *; ''; }; "~ ^/schule$".return = "307 /schule/"; "/schule/" = { alias = "/var/www/cms-slides/"; extraConfig = '' index index.html; ''; }; # SpaceAPI "/status.png".proxyPass = "http://[${hostRegistry.spaceapi.ip6}]:3000/status.png"; "/spaceapi.json".proxyPass = "http://[${hostRegistry.spaceapi.ip6}]:3000/spaceapi.json"; # WKD: Web Key Directory for PGP Keys "~ ^/openpgp".extraConfig = '' autoindex off; default_type "application/octet-stream"; add_header Access-Control-Allow-Origin "* always"; ''; }; }; "datenspuren.de" = { serverAliases = [ "www.datenspuren.de" "ds.c3d2.de" "datenspuren.c3d2.de" ]; enableACME = true; forceSSL = true; root = "/var/www/c3d2/datenspuren"; extraConfig = /* nginx */ '' index index.html; rewrite ^/$ /2024/ redirect; ''; # Mastodon locations."~ ^/.well-known/webfinger".return = "301 https://c3d2.social/.well-known/webfinger?resource=acct%3adatenspuren%40c3d2.social"; }; "autotopia.c3d2.de" = { enableACME = true; forceSSL = true; root = "/var/www/c3d2/autotopia"; extraConfig = '' index index.html; rewrite ^/$ /2020/ redirect; ''; }; }; }; # Gemini server services.agate = { enable = true; addresses = [ # sysctl net.ipv6.bindv6only = 0 "[::]:1965" ]; certificatesDir = "/var/lib/agate/certificates"; contentDir = "/var/www/gemini"; language = "de"; }; systemd = { packages = with pkgs; [ telme10 ]; services = { # lets agate access the tls certs agate = { requires = [ "agate-keys.service" ]; after = [ "agate-keys.service" ]; serviceConfig = { Group = "keys"; }; }; agate-keys = { path = with pkgs; [ openssl ]; script = let stateDir = "/var/lib/agate/certificates"; in '' mkdir -p ${stateDir} openssl x509 \ -in /var/lib/acme/www.c3d2.de/cert.pem \ -out ${stateDir}/cert.der \ -outform DER openssl rsa \ -in /var/lib/acme/www.c3d2.de/key.pem \ -out ${stateDir}/key.der \ -outform DER chown root:keys ${stateDir}/* chmod 0640 ${stateDir}/* ''; serviceConfig = { Type = "oneshot"; }; }; telme10 = { serviceConfig.AmbientCapabilities = "CAP_NET_BIND_SERVICE"; }; }; sockets.telme10.wantedBy = [ "sockets.target" ]; }; users = { groups = { c3d2-web = { }; telme10 = { }; }; users = { c3d2-web = { group = "c3d2-web"; home = "/var/lib/c3d2-web"; isSystemUser = true; openssh.authorizedKeys.keys = [ "ssh-ed25519 AAAAC3NzaC1lZDI1NTE5AAAAIHIkIN1gi5cX2wV2WuNph/QzVK7vvYkvqnR/P69s36mZ drone@c3d2" ]; packages = with pkgs; [ (stdenv.mkDerivation { pname = "atomic-rsync"; inherit (rsync) version src meta; dontBuild = true; dontConfigure = true; buildInputs = [ python3 ]; installPhase = '' substituteInPlace support/atomic-rsync \ --replace /usr/bin/rsync rsync install -Dm755 support/atomic-rsync -t $out/bin ''; }) (libxslt.override { cryptoSupport = true; }) libxml2 rsync gnumake ]; # otherwise the the drone ssh runner cannot log in useDefaultShell = true; }; telme10 = { isSystemUser = true; group = "telme10"; }; }; }; systemd.tmpfiles.rules = with config.users.users.c3d2-web; [ "d /var/www/c3d2 0755 c3d2-web ${group} -" "d ${config.services.agate.contentDir} 0755 c3d2-web ${group} -" "d ${home} 0700 c3d2-web ${group} -" ]; sops = { defaultSopsFile = ./secrets.yaml; secrets."c3d2-web/gitea-token".owner = "c3d2-web"; }; }