diff --git a/README.md b/README.md new file mode 100644 index 0000000..629c2e3 --- /dev/null +++ b/README.md @@ -0,0 +1,35 @@ +# HTTP + +Configure `berlin.ccc.de` web server to send federation traffic to the matrix server: + +```nginx +server { + hostname berlin.ccc.de; + location "/.well-known/matrix/server" { + default_type application/json; + return 200 '{"m.server":"matrix.berlin.ccc.de:443"}'; + } +} +``` + +# DNS + +``` +_matrix-fed._tcp.matrix.berlin.ccc.de. IN SRV 10 0 443 matrix.berlin.ccc.de. +#_matrix._tcp.matrix.berlin.ccc.de. IN SRV 10 0 443 matrix.berlin.ccc.de. +#_matrix._tcp.berlin.ccc.de. IN SRV 10 0 443 matrix.berlin.ccc.de. +_matrix-fed._tcp.berlin.ccc.de. IN SRV 10 0 443 matrix.berlin.ccc.de. +matrix.berlin.ccc.de. IN A +matrix.berlin.ccc.de. IN AAAA +``` + +# Bots + +```bash +register_new_matrix_user \ + -c homeserver.yaml https://matrix.berlin.ccc.de \ + --user_domain berlin.ccc.de \ + --user \ + --password +``` + diff --git a/configuration.nix b/configuration.nix new file mode 100644 index 0000000..f99d39a --- /dev/null +++ b/configuration.nix @@ -0,0 +1,145 @@ +{ + config, + modulesPath, + pkgs, + lib, + ... +}: + +{ + imports = [ (modulesPath + "/virtualisation/proxmox-lxc.nix") ]; + + nix = { + optimise = { + automatic = true; + dates = [ "11:00" ]; + }; + settings = { + auto-optimise-store = true; + sandbox = false; + trusted-users = [ + "root" + "@wheel" + ]; # Allow remote updates + experimental-features = [ + "nix-command" + "flakes" + ]; # Enable flakes + }; + gc = { + automatic = true; + options = "--delete-older-then 14d"; + }; + }; + + nixpkgs.hostPlatform = "x86_64-linux"; + + environment.systemPackages = with pkgs; [ + vim + git + ]; + + proxmoxLXC = { + manageNetwork = false; + manageHostName = false; + privileged = true; + }; + + users.users.root = { + packages = with pkgs; [ + kitty # for terminfo + neofetch # for shits and giggles + ]; + openssh.authorizedKeys.keys = [ + "ssh-ed25519 AAAAC3NzaC1lZDI1NTE5AAAAICW1+Ml8R9x1LCJaZ8bIZ1qIV4HCuZ6x7DziFW+0Nn5T xengi@kanae_2022-12-09" + "ssh-ed25519 AAAAC3NzaC1lZDI1NTE5AAAAICmb+mJfo84IagUaRoDEqY9ROjjQUOQ7tMclpN6NDPrX xengi@kota_2022-01-16" + "ssh-ed25519 AAAAC3NzaC1lZDI1NTE5AAAAICyklb7dvEHH0VBEMmTUQFKHN6ekBQqkDKj09+EilUIQ xengi@lucy_2018-09-08" + "ssh-ed25519 AAAAC3NzaC1lZDI1NTE5AAAAICjv9W8WXq9QGkgmANNPQR24/I1Pm1ghxNIHftEI+jlZ xengi@mayu_2021-06-11" + "ssh-ed25519 AAAAC3NzaC1lZDI1NTE5AAAAIGhyfD+8jMl6FDSADb11sfAsJk0KNoVzjjiDRZjUOtmf xengi@nana_2019-08-16" + "ssh-ed25519 AAAAC3NzaC1lZDI1NTE5AAAAIMPtGqhV7io3mhIoZho4Yf7eCo0sUZvjT2NziM2PkXSo xengi@nyu_2017-10-11" + "ssh-ed25519 AAAAC3NzaC1lZDI1NTE5AAAAILwYcSxbP6Hon//kZFIZJSHdqvsJ6AyCwH4JP9/t4q46 xengi@yuka_2020-12-16" + ]; + }; + + networking = { + useNetworkd = true; + nftables.enable = true; + dhcpcd.enable = false; + firewall = { + enable = true; + allowedTCPPorts = [ + 22 # SSH + 80 # HTTP/1 + 443 # HTTP/2 + 8448 # Matrix federation + ]; + allowedUDPPorts = [ + 443 # HTTP/3 + ]; + }; + }; + + time.timeZone = "Europe/Berlin"; + i18n.defaultLocale = "en_US.UTF-8"; + console.font = "Lat2-Terminus16"; + + services = { + fstrim.enable = false; # Let Proxmox host handle fstrim + openssh = { + enable = true; + openFirewall = true; + settings = { + PermitEmptyPasswords = "no"; + PermitRootLogin = "prohibit-password"; + PasswordAuthentication = false; + KbdInteractiveAuthentication = false; + }; + banner = '' + __ __ + /\ \__ __ /\ \ + ___ ___ __ \ \ ,_\ _ __ /\_\ __ _ ___ ___ ___\ \ \____ + /' __` __`\ /'__`\ \ \ \/ /\`'__\/\ \ /\ \/'\ /'___\ /'___\ /'___\ \ '__`\ + /\ \/\ \/\ \/\ \L\.\_\ \ \_\ \ \/ \ \ \\/> ssh-ed25519 uH+n1w EMOmmGlZ2rnqAaqcHHQ9conaa8YH/3TBFRpUlssNuGw +jyXUxitYHc/vNpab9winTCqCWBQYtmDGdZortYYlMAI +-> ssh-ed25519 EvLbWw K+NOnJui0ASn3lPsP1xZ2X4fdfSBQ1woOnD3c4Zk/xE +FDYbrduCSWvo5NSzyAgwNa7tU4c3r7Fcoizfph3fqF4 +-> ssh-ed25519 dM+fLQ Ji3jw0haPByWaQ68rHxFmj1xjSG9EVfyYTtZZpAFYFg +cHPTEfHWjwIVUBaDB85vGCfatd4Wtuq7QT3mIcdaF7M +-> ssh-ed25519 jxWM2Q ZTbjGk18JyognAJwUQIfwy3YlHALXsfyUICiGrG/ij0 +/eyD/UoQZ33s2geZ6212ZMOLhyzKCbryR1HDYW02dfg +-> ssh-ed25519 /yCUCg cM7meOfoTt4UlsODZeSrLFkMtIAInASm0uDrMHDDnXY +LCdZCjhp+/i7bGkXhHJ4Jv6C2ikcPsL3i7W/tap7AMs +-> ssh-ed25519 FGp51g zZFF/qLQDbKpkBQiEJJQrtoJVxrdrWeqziwNq/rP2jY +jJ/ivlZIfn6/oh7yZSCNmQGikvwdSVAzxkLj/tc2Eys +-> ssh-ed25519 alMFaA y5NuhEOK3lijncBscuSCfOTpepiIkAYW/W5kG+wscRE +a/z+2jHk1ERmNXFv+h1B7BpavjbemqOON5ruHP5U6dY +--- 6e7V59HtYHOi9koxczT0hwL6wk1/QkmDOkUGGlZCmo8 +[5°Ì“¬rl*X*…_€'-˜ú¿`‹“ó|3A3£N>¨Ñ• \ No newline at end of file diff --git a/secrets/pushover_user_key.age b/secrets/pushover_user_key.age new file mode 100644 index 0000000..1fe3ef2 --- /dev/null +++ b/secrets/pushover_user_key.age @@ -0,0 +1,17 @@ +age-encryption.org/v1 +-> ssh-ed25519 uH+n1w EMOmmGlZ2rnqAaqcHHQ9conaa8YH/3TBFRpUlssNuGw +jyXUxitYHc/vNpab9winTCqCWBQYtmDGdZortYYlMAI +-> ssh-ed25519 EvLbWw K+NOnJui0ASn3lPsP1xZ2X4fdfSBQ1woOnD3c4Zk/xE +FDYbrduCSWvo5NSzyAgwNa7tU4c3r7Fcoizfph3fqF4 +-> ssh-ed25519 dM+fLQ Ji3jw0haPByWaQ68rHxFmj1xjSG9EVfyYTtZZpAFYFg +cHPTEfHWjwIVUBaDB85vGCfatd4Wtuq7QT3mIcdaF7M +-> ssh-ed25519 jxWM2Q ZTbjGk18JyognAJwUQIfwy3YlHALXsfyUICiGrG/ij0 +/eyD/UoQZ33s2geZ6212ZMOLhyzKCbryR1HDYW02dfg +-> ssh-ed25519 /yCUCg cM7meOfoTt4UlsODZeSrLFkMtIAInASm0uDrMHDDnXY +LCdZCjhp+/i7bGkXhHJ4Jv6C2ikcPsL3i7W/tap7AMs +-> ssh-ed25519 FGp51g zZFF/qLQDbKpkBQiEJJQrtoJVxrdrWeqziwNq/rP2jY +jJ/ivlZIfn6/oh7yZSCNmQGikvwdSVAzxkLj/tc2Eys +-> ssh-ed25519 alMFaA y5NuhEOK3lijncBscuSCfOTpepiIkAYW/W5kG+wscRE +a/z+2jHk1ERmNXFv+h1B7BpavjbemqOON5ruHP5U6dY +--- 6e7V59HtYHOi9koxczT0hwL6wk1/QkmDOkUGGlZCmo8 +[5°Ì“¬rl*X*…_€'-˜ú¿`‹“ó|3A3£N>¨Ñ• \ No newline at end of file diff --git a/secrets/secrets.nix b/secrets/secrets.nix new file mode 100644 index 0000000..b2cef40 --- /dev/null +++ b/secrets/secrets.nix @@ -0,0 +1,23 @@ +let + kanae = "ssh-ed25519 AAAAC3NzaC1lZDI1NTE5AAAAICW1+Ml8R9x1LCJaZ8bIZ1qIV4HCuZ6x7DziFW+0Nn5T xengi@kanae_2022-12-09"; + kota = "ssh-ed25519 AAAAC3NzaC1lZDI1NTE5AAAAICmb+mJfo84IagUaRoDEqY9ROjjQUOQ7tMclpN6NDPrX xengi@kota_2022-01-16"; + lucy = "ssh-ed25519 AAAAC3NzaC1lZDI1NTE5AAAAICyklb7dvEHH0VBEMmTUQFKHN6ekBQqkDKj09+EilUIQ xengi@lucy_2018-09-08"; + mayu = "ssh-ed25519 AAAAC3NzaC1lZDI1NTE5AAAAICjv9W8WXq9QGkgmANNPQR24/I1Pm1ghxNIHftEI+jlZ xengi@mayu_2021-06-11"; + nana = "ssh-ed25519 AAAAC3NzaC1lZDI1NTE5AAAAIGhyfD+8jMl6FDSADb11sfAsJk0KNoVzjjiDRZjUOtmf xengi@nana_2019-08-16"; + nyu = "ssh-ed25519 AAAAC3NzaC1lZDI1NTE5AAAAIMPtGqhV7io3mhIoZho4Yf7eCo0sUZvjT2NziM2PkXSo xengi@nyu_2017-10-11"; + users = [ + kanae + kota + lucy + mayu + nana + nyu + ]; + + _matrix = "ssh-ed25519 AAAAC3NzaC1lZDI1NTE5AAAAIM7AZkepRXoY+DJeSLOU+GR60S62p6+0X/PDeEUZ0yHx root@matrix"; +in +{ + "matrix-registration-shared-secret.age".publicKeys = users ++ [ _matrix ]; + "pushover_app_token.age".publicKeys = users ++ [ _matrix ]; + "pushover_user_key.age".publicKeys = users ++ [ _matrix ]; +} diff --git a/services/nginx.nix b/services/nginx.nix new file mode 100644 index 0000000..b334e5c --- /dev/null +++ b/services/nginx.nix @@ -0,0 +1,44 @@ +{ config, pkgs, ... }: + +let + fqdn = "matrix.berlin.ccc.de"; +in +{ + services.nginx = { + enable = true; + package = pkgs.nginxQuic; + resolver.addresses = ["[2606:4700:4700::1111]" "[2620:fe::fe]" "1.1.1.1" "9.9.9.9"]; + statusPage = true; # http://127.0.0.1/nginx_status + sslProtocols = "TLSv1.3"; + recommendedTlsSettings = true; + recommendedOptimisation = true; + recommendedZstdSettings = true; + recommendedGzipSettings = true; + recommendedBrotliSettings = true; + virtualHosts."${fqdn}" = { + quic = true; + kTLS = true; + forceSSL = true; + useACMEHost = fqdn; + locations = { + "/.well-known/matrix/client" = { + return = "200 '{\"m.homeserver\": {\"base_url\": \"https://matrix.berlin.ccc.de\"}}'"; + extraConfig = '' + default_type application/json; + add_header Access-Control-Allow-Origin "*"; + ''; + }; + "/" = { + recommendedProxySettings = true; + proxyPass = "unix:/run/matrix-synapse.sock"; + }; + }; + extraConfig = '' + ''; + }; + }; + + security.acme.certs."${fqdn}" = { + reloadServices = ["nginx"]; + }; +} diff --git a/services/postgres.nix b/services/postgres.nix new file mode 100644 index 0000000..2c78756 --- /dev/null +++ b/services/postgres.nix @@ -0,0 +1,15 @@ +{ config, ... }: + +{ + services.postgresql = { + enable = true; + enableJIT = true; + ensureUsers = [ + { + name = config.services.matrix-synapse.settings.database.args.user; + ensureDBOwnership = true; + } + ]; + ensureDatabases = [ config.services.matrix-synapse.settings.database.args.database ]; + }; +} diff --git a/services/synapse.nix b/services/synapse.nix new file mode 100644 index 0000000..3e7e9b8 --- /dev/null +++ b/services/synapse.nix @@ -0,0 +1,48 @@ +{ config, ... }: + +let + domain = "berlin.ccc.de"; +in +{ + services.matrix-synapse = { + enable = false; + settings = { + server_name = domain; + public_baseurl = "https://matrix.${domain}:443/"; + #signing_key_path = config.age.secrets.signing_key.path; # "/var/lib/matrix-synapse/homeserver.signing.key" + database.name = "psycopg2"; + listeners = [ + { + path = "/run/matrix-synapse.sock"; + x_forwarded = true; + resources = [ + { + compress = false; + names = [ + "client" + "federation" + ]; + } + ]; + } + ]; + dynamic_thumbnails = true; + max_upload_size = "128M"; + max_image_pixels = "64M"; + + retention = { + enabled = true; + default_policy = { + min_lifetime = "1d"; + max_lifetime = "1y"; + }; + allowed_lifetime_min = "1d"; + allowed_lifetime_max = "1y"; + }; + }; + extraConfigFiles = [ + config.age.secrets.matrix-registration-shared-secret.path + ]; + enableRegistrationScript = true; + }; +}