diff --git a/modules/hosts/loptland/default.nix b/modules/hosts/loptland/default.nix index 428f0fc..44a3104 100644 --- a/modules/hosts/loptland/default.nix +++ b/modules/hosts/loptland/default.nix @@ -30,13 +30,6 @@ topLevel: { forgejo forgejo-runner - # services - matrix-synapse - mautrix-discord - mautrix-signal - element-call - element-web - # game server minecraft-server factorio-server diff --git a/modules/hosts/loptland/nginx.nix b/modules/hosts/loptland/nginx.nix index 5de5314..0ceda04 100644 --- a/modules/hosts/loptland/nginx.nix +++ b/modules/hosts/loptland/nginx.nix @@ -8,9 +8,6 @@ }: let domainName = "christophhollizeck.dev"; - matrixDomain = "alwayssleepy.online"; - livekitPort = 7880; - lkJwtPort = 8089; in { services.nginx = { @@ -53,99 +50,6 @@ }; }; - "matrix.${matrixDomain}" = lib.mkIf config.services.matrix-synapse.enable { - forceSSL = true; - useACMEHost = matrixDomain; - - # MSC4143: advertise LiveKit as the RTC transport since Synapse doesn't implement this yet - locations."= /_matrix/client/unstable/org.matrix.msc4143/rtc/transports" = { - extraConfig = '' - default_type application/json; - add_header 'Access-Control-Allow-Origin' '*' always; - add_header 'Access-Control-Allow-Methods' 'GET, POST, OPTIONS' always; - add_header 'Access-Control-Allow-Headers' 'Authorization, Content-Type' always; - if ($request_method = OPTIONS) { - return 204; - } - return 200 '{"rtc_transports":[{"type":"livekit","livekit_service_url":"https://call.${matrixDomain}/livekit/jwt"}]}'; - ''; - }; - - locations."/" = { - proxyPass = "http://localhost:${toString 8008}"; - extraConfig = '' - client_max_body_size 50M; - ''; - }; - }; - - "call.${matrixDomain}" = lib.mkIf config.services.lk-jwt-service.enable { - forceSSL = true; - useACMEHost = matrixDomain; - - locations."= /config.json" = { - extraConfig = '' - default_type application/json; - return 200 '${builtins.toJSON { - default_server_config = { - "m.homeserver" = { - base_url = "https://matrix.${matrixDomain}"; - server_name = matrixDomain; - }; - }; - livekit = { - livekit_service_url = "https://call.${matrixDomain}/livekit/jwt"; - }; - }}'; - ''; - }; - - locations."/" = { - root = "${pkgs.element-call}"; - tryFiles = "$uri /index.html"; - extraConfig = '' - add_header Cache-Control "no-cache" always; - add_header Content-Security-Policy "frame-ancestors 'self' https://chat.${matrixDomain}" always; - ''; - }; - - # Proxy lk-jwt-service for token generation - locations."/livekit/jwt" = { - proxyPass = "http://localhost:${toString lkJwtPort}"; - }; - - # Proxy LiveKit SFU websocket - locations."/livekit/sfu" = { - proxyPass = "http://localhost:${toString livekitPort}"; - extraConfig = '' - proxy_http_version 1.1; - proxy_set_header Upgrade $http_upgrade; - proxy_set_header Connection "upgrade"; - ''; - }; - }; - - # .well-known Matrix delegation so Matrix IDs are @user:alwayssleepy.online - "alwayssleepy.online" = { - forceSSL = true; - useACMEHost = matrixDomain; - - locations."/.well-known/matrix/server" = { - extraConfig = '' - default_type application/json; - return 200 '{"m.server":"matrix.${matrixDomain}:443"}'; - ''; - }; - - locations."/.well-known/matrix/client" = { - extraConfig = '' - default_type application/json; - add_header 'Access-Control-Allow-Origin' '*'; - return 200 '{"m.homeserver":{"base_url":"https://matrix.${matrixDomain}"},"org.matrix.msc4143.rtc_foci":[{"type":"livekit","livekit_service_url":"https://call.${matrixDomain}/livekit/jwt"}]}'; - ''; - }; - }; - "nixcache.${domainName}" = lib.mkIf config.services.nix-serve.enable { forceSSL = true; useACMEHost = domainName; diff --git a/modules/server/acme.nix b/modules/server/acme.nix index 631f967..81d509f 100644 --- a/modules/server/acme.nix +++ b/modules/server/acme.nix @@ -44,7 +44,7 @@ topLevel: { inherit (topLevel.config.flake.meta.users.cholli) email; group = lib.mkIf config.services.nginx.enable "nginx"; - reloadServices = lib.mkIf config.services.nginx.enable [ "nginx.service" ]; + reloadServices = lib.mkIf config.services.nginx.enable "nginx.service"; dnsProvider = "netcup"; environmentFile = config.sops.templates."netcup.env".path; @@ -54,11 +54,6 @@ topLevel: { dnsResolver = "1.1.1.1:53"; extraDomainNames = [ "*.${domainname}" ]; }; - - certs."alwayssleepy.online" = { - dnsResolver = "1.1.1.1:53"; - extraDomainNames = [ "*.alwayssleepy.online" ]; - }; }; }; diff --git a/modules/server/element-call.nix b/modules/server/element-call.nix deleted file mode 100644 index 2e10ba8..0000000 --- a/modules/server/element-call.nix +++ /dev/null @@ -1,48 +0,0 @@ -topLevel: { - flake.modules.nixos.element-call = - { config, lib, pkgs, ... }: - let - matrixDomain = "alwayssleepy.online"; - livekitPort = 7880; - livekitRtcPortStart = 50000; - livekitRtcPortEnd = 50200; - lkJwtPort = 8089; - sopsFile = ../../secrets/secrets-loptland.yaml; - in - { - sops.secrets."matrix/livekit/keyFile" = { - inherit sopsFile; - # livekit and lk-jwt-service both read this file - mode = "0440"; - group = "livekit-secrets"; - }; - - users.groups.livekit-secrets = { }; - - # LiveKit SFU media server - services.livekit = { - enable = true; - openFirewall = true; - keyFile = config.sops.secrets."matrix/livekit/keyFile".path; - - settings = { - port = livekitPort; - rtc = { - port_range_start = livekitRtcPortStart; - port_range_end = livekitRtcPortEnd; - }; - }; - }; - - # lk-jwt-service: bridges Matrix OpenID tokens to LiveKit JWTs - services.lk-jwt-service = { - enable = true; - livekitUrl = "wss://call.${matrixDomain}/livekit/sfu"; - keyFile = config.sops.secrets."matrix/livekit/keyFile".path; - port = lkJwtPort; - }; - - # Allow lk-jwt-service (DynamicUser) to read the secrets file - systemd.services.lk-jwt-service.serviceConfig.SupplementaryGroups = [ "livekit-secrets" ]; - }; -} diff --git a/modules/server/element-web.nix b/modules/server/element-web.nix deleted file mode 100644 index b395d4b..0000000 --- a/modules/server/element-web.nix +++ /dev/null @@ -1,47 +0,0 @@ -{ - flake.modules.nixos.element-web = - { pkgs, ... }: - let - matrixDomain = "alwayssleepy.online"; - in - { - services.nginx.virtualHosts."chat.${matrixDomain}" = { - forceSSL = true; - useACMEHost = matrixDomain; - - locations."= /config.json" = { - extraConfig = '' - default_type application/json; - return 200 '${builtins.toJSON { - default_server_config = { - "m.homeserver" = { - base_url = "https://matrix.${matrixDomain}"; - server_name = matrixDomain; - }; - }; - disable_custom_urls = true; - disable_guests = true; - features = { - feature_group_calls = true; - }; - element_call = { - url = "https://call.${matrixDomain}"; - use_exclusively = true; - brand = "Element Call"; - }; - brand = "Element"; - default_theme = "dark"; - }}'; - ''; - }; - - locations."/" = { - root = "${pkgs.element-web}"; - tryFiles = "$uri /index.html"; - extraConfig = '' - add_header Cache-Control "no-cache" always; - ''; - }; - }; - }; -} diff --git a/modules/server/matrix-synapse.nix b/modules/server/matrix-synapse.nix deleted file mode 100644 index 9dc150f..0000000 --- a/modules/server/matrix-synapse.nix +++ /dev/null @@ -1,100 +0,0 @@ -{ - flake.modules.nixos.matrix-synapse = - { config, pkgs, lib, ... }: - let - domainName = "alwayssleepy.online"; - matrixPort = 8008; - sopsFile = ../../secrets/secrets-loptland.yaml; - in - { - sops.secrets."matrix/registrationSharedSecret" = { - inherit sopsFile; - owner = "matrix-synapse"; - }; - - services.postgresql = { - enable = true; - ensureDatabases = [ "matrix-synapse" ]; - ensureUsers = [ - { - name = "matrix-synapse"; - ensureDBOwnership = true; - } - ]; - }; - - # ensureDatabases creates with default collation, but Synapse requires C collation. - # This service runs after postgresql-setup (which runs ensureDatabases) and corrects - # the collation by recreating the DB if needed. - systemd.services."matrix-synapse-db-setup" = { - description = "Set up Matrix Synapse PostgreSQL database with C collation"; - wantedBy = [ "matrix-synapse.service" ]; - before = [ "matrix-synapse.service" ]; - after = [ - "postgresql.service" - "postgresql-setup.service" - ]; - requires = [ "postgresql.service" ]; - serviceConfig = { - Type = "oneshot"; - User = "postgres"; - RemainAfterExit = true; - }; - script = - let psql = lib.getExe' pkgs.postgresql "psql"; in - '' - COLLATION=$(${psql} -tAc "SELECT datcollate FROM pg_database WHERE datname = 'matrix-synapse'") - if [ "$COLLATION" != "C" ]; then - ${psql} -c "DROP DATABASE \"matrix-synapse\"" - ${psql} -c "CREATE DATABASE \"matrix-synapse\" ENCODING 'UTF8' LC_COLLATE='C' LC_CTYPE='C' TEMPLATE=template0 OWNER \"matrix-synapse\"" - fi - ''; - }; - - services.matrix-synapse = { - enable = true; - - settings = { - server_name = domainName; - - database = { - name = "psycopg2"; - args.database = "matrix-synapse"; - }; - - public_baseurl = "https://matrix.${domainName}"; - - listeners = [ - { - port = matrixPort; - bind_addresses = [ "127.0.0.1" ]; - type = "http"; - tls = false; - x_forwarded = true; - resources = [ - { - names = [ - "client" - "federation" - ]; - compress = false; - } - ]; - } - ]; - - enable_registration = true; - registration_requires_token = true; - }; - - extraConfigFiles = [ config.sops.templates."matrix-synapse-extra.yaml".path ]; - }; - - sops.templates."matrix-synapse-extra.yaml" = { - owner = "matrix-synapse"; - content = '' - registration_shared_secret: "${config.sops.placeholder."matrix/registrationSharedSecret"}" - ''; - }; - }; -} diff --git a/modules/server/mautrix-discord.nix b/modules/server/mautrix-discord.nix deleted file mode 100644 index 6ac6c60..0000000 --- a/modules/server/mautrix-discord.nix +++ /dev/null @@ -1,105 +0,0 @@ -{ - flake.modules.nixos.mautrix-discord = - { - config, - pkgs, - lib, - ... - }: - let - matrixDomain = "alwayssleepy.online"; - bridgePort = 29334; - sopsFile = ../../secrets/secrets-loptland.yaml; - in - { - sops.secrets."matrix/mautrix-discord/botToken" = { - inherit sopsFile; - owner = "mautrix-discord"; - }; - - sops.templates."mautrix-discord.env" = { - owner = "mautrix-discord"; - content = '' - MAUTRIX_DISCORD_DISCORD_BOT_TOKEN=${config.sops.placeholder."matrix/mautrix-discord/botToken"} - ''; - }; - - services.postgresql = { - ensureDatabases = [ "mautrix-discord" ]; - ensureUsers = [ - { - name = "mautrix-discord"; - ensureDBOwnership = true; - } - ]; - }; - - # mautrix-discord (like matrix-synapse) requires C collation - systemd.services."mautrix-discord-db-setup" = { - description = "Set up mautrix-discord PostgreSQL database with C collation"; - wantedBy = [ "mautrix-discord.service" ]; - before = [ "mautrix-discord.service" ]; - after = [ - "postgresql.service" - "postgresql-setup.service" - ]; - requires = [ "postgresql.service" ]; - serviceConfig = { - Type = "oneshot"; - User = "postgres"; - RemainAfterExit = true; - }; - script = - let - psql = lib.getExe' pkgs.postgresql "psql"; - in - '' - COLLATION=$(${psql} -tAc "SELECT datcollate FROM pg_database WHERE datname = 'mautrix-discord'") - if [ "$COLLATION" != "C" ]; then - ${psql} -c "DROP DATABASE \"mautrix-discord\"" - ${psql} -c "CREATE DATABASE \"mautrix-discord\" ENCODING 'UTF8' LC_COLLATE='C' LC_CTYPE='C' TEMPLATE=template0 OWNER \"mautrix-discord\"" - fi - ''; - }; - - # mautrix-discord depends on libolm which is deprecated/insecure upstream. - nixpkgs.config.permittedInsecurePackages = [ "olm-3.2.16" ]; - - services.mautrix-discord = { - enable = true; - environmentFile = config.sops.templates."mautrix-discord.env".path; - - settings = { - homeserver = { - address = "http://localhost:${toString 8008}"; - domain = matrixDomain; - }; - - appservice = { - address = "http://localhost:${toString bridgePort}"; - hostname = "127.0.0.1"; - port = bridgePort; - database = { - type = "postgres"; - uri = "postgres:///mautrix-discord?host=/var/run/postgresql"; - }; - }; - - bridge = { - relay = { - enabled = true; - admin_only = false; - }; - - permissions = { - "@cholli:${matrixDomain}" = "admin"; - "${matrixDomain}" = "user"; - }; - }; - }; - }; - - # Give matrix-synapse access to the registration file via group membership - users.users.matrix-synapse.extraGroups = [ "mautrix-discord" ]; - }; -} diff --git a/modules/server/mautrix-signal.nix b/modules/server/mautrix-signal.nix deleted file mode 100644 index d39a2d9..0000000 --- a/modules/server/mautrix-signal.nix +++ /dev/null @@ -1,82 +0,0 @@ -{ - flake.modules.nixos.mautrix-signal = - { - config, - pkgs, - lib, - ... - }: - let - matrixDomain = "alwayssleepy.online"; - bridgePort = 29335; - sopsFile = ../../secrets/secrets-loptland.yaml; - in - { - services.postgresql = { - ensureDatabases = [ "mautrix-signal" ]; - ensureUsers = [ - { - name = "mautrix-signal"; - ensureDBOwnership = true; - } - ]; - }; - - # mautrix-signal (like matrix-synapse) requires C collation - systemd.services."mautrix-signal-db-setup" = { - description = "Set up mautrix-signal PostgreSQL database with C collation"; - wantedBy = [ "mautrix-signal.service" ]; - before = [ "mautrix-signal.service" ]; - after = [ - "postgresql.service" - "postgresql-setup.service" - ]; - requires = [ "postgresql.service" ]; - serviceConfig = { - Type = "oneshot"; - User = "postgres"; - RemainAfterExit = true; - }; - script = - let - psql = lib.getExe' pkgs.postgresql "psql"; - in - '' - COLLATION=$(${psql} -tAc "SELECT datcollate FROM pg_database WHERE datname = 'mautrix-signal'") - if [ "$COLLATION" != "C" ]; then - ${psql} -c "DROP DATABASE \"mautrix-signal\"" - ${psql} -c "CREATE DATABASE \"mautrix-signal\" ENCODING 'UTF8' LC_COLLATE='C' LC_CTYPE='C' TEMPLATE=template0 OWNER \"mautrix-signal\"" - fi - ''; - }; - - services.mautrix-signal = { - enable = true; - - settings = { - homeserver = { - address = "http://localhost:${toString 8008}"; - domain = matrixDomain; - }; - - appservice = { - address = "http://localhost:${toString bridgePort}"; - hostname = "127.0.0.1"; - port = bridgePort; - }; - - database = { - type = "postgres"; - uri = "postgres:///mautrix-signal?host=/var/run/postgresql"; - }; - - bridge = { - permissions = { - "@cholli:${matrixDomain}" = "admin"; - "${matrixDomain}" = "user"; - }; - }; - }; - }; - }; -} diff --git a/secrets/secrets-loptland.yaml b/secrets/secrets-loptland.yaml index b9e4d11..3201cb1 100644 --- a/secrets/secrets-loptland.yaml +++ b/secrets/secrets-loptland.yaml @@ -20,12 +20,6 @@ hydra: token: ENC[AES256_GCM,data:FqlJMfw7d1VfWhC+vI4SEMWzzADXK/np33fCsihq3wgC6nWNeTurNn1vDRLIRH+s6iT1C8Ni8iAAlndfUS5SPH6Ymswix9KuJCvYc8Jy+c8pPchYePtMQfv3dVe5a1i06b8I5c+MX8V7j2kaCijYDirnhiD0qlc8SW/mIyB5RNpAgKPTzLjLKJNSUkTGOWUnww==,iv:H2yQ5ioBVnezmhGHbJ7sAlXvUb2MUmHpQpS7f+nIph4=,tag:qvqsbgf2Y/PAd3s9ZFuxWA==,type:str] remotebuild: private-key: ENC[AES256_GCM,data:FqdXFj4/leKNtNJ1H1sBnb/Gnso9soaLtdUToMsx3O6LAn2smdkFrguY9EESm+o1nIBWwc1S2cE/sfH8FR89NWbyfCDTsQLHRIIEYMS2kKLv7hqqdsmyQojW38TnUYtSo5W1V9pdmeYuotUrM7bPmW/Io/7/G/vW6LxtI7Mx1qT7OXnyEJVYsvY6TtJitWO0/jGUAGOyvu/+YhV4yRmArM2kjT+iYb8/dN0HpqCwo6aLvY7ctAA6ggESciuovEtUMv19y+RpMUaHxloziM3SFz/GjXekrqtPGDkCUusSChXuhzfmZDoz4dzNnkKn8HsmxzByzaTyNH9kCxzNV7vULTKi6/O4ny64FOk6pjymz2Yv6pK+pm3tP2wrPwynn3C1giwFCGn+2Nazixj4g4wd5iSFwNeAsDbLU0b3YN/NgQv0TeKGXR01Xgqvt06vtAnkpu8byPBUX5cz15kJckeztVHYCQyz6Uthk6NN+ScLok1z3I7Vn37KsF0Ka7k22aPMwXLLKkfEneavT41x1VNBq7Nedf9EFjjUG8S7,iv:mTlEphmcoFMv7dxIeSpsi77e3CJULcXxcOF1Nq66mUM=,tag:K2aGpaw2xeEj8537kB/cGA==,type:str] -matrix: - registrationSharedSecret: ENC[AES256_GCM,data:6IBlAfQhWlywWo/l8u5gAfW7bTgXwrAyk8WBBWkJQK+FL9LvUU5hDscozHrPIiRRzZdyeoAZ7phirDk3kN9E6Q==,iv:arZaxnIEUU3psaV8PqKAb46nlq73r2SAVlmCY+y+HB0=,tag:X/zsAtryEfl2PHKQ6GQfbg==,type:str] - mautrix-discord: - botToken: ENC[AES256_GCM,data:IrYMnUNorLK8853LXubpaXX2LwKbtlsdQzDHoeUq1VLyeH6Kz2CdnOV7UfuR4I0oEXBvw16PS+aBqjQCLcWGgXdTInEmq7lJ,iv:FmPlP1ZTdTTVcJeO0sKwiyaJ9KrZ8jbbyEiCK+O2XuI=,tag:Z+gVRNC34XV2OAUJcburIQ==,type:str] - livekit: - keyFile: ENC[AES256_GCM,data:h7pIrLswWJhS5vkcvVquMCFC/prCVavCJWUck7W6x7emH+qalXxmMxPnkCskFr163re+Y04PuOsrtFe4,iv:8BDrFPDhC5UHAzGUZ77hzNQh2RuMzdWphLXt9WI54gk=,tag:66MGl67bpOF/3n/vzYUOuw==,type:str] sops: age: - recipient: age1pc92kl38mfr0j68dxww7tpzvqp3lpw6lwfylj6hn2k3rf4rddgtsjxdx47 @@ -46,7 +40,7 @@ sops: czdSTjNGSEpURlZEUTlIaUtGQUk5cW8KvylMTgtmHNvGnN7DonAsYQZB31mVli75 3OTN+mOetq2YNxh/Se7vqzwbZnshfTDk9nJi9bKZQhBt2nYR8eLRkg== -----END AGE ENCRYPTED FILE----- - lastmodified: "2026-03-26T15:57:42Z" - mac: ENC[AES256_GCM,data:gyiA6KTHS6I/geGuAldEHibD9TXKSW25k5hF+Ay1vFHdvjBqwvZ2ExOh/mgTz9qvE3FC24R2le8BTQbRvymWaE6wulzNEuzh3KoQHdsJpVWUIfizESj3Nt83WmJPr4jW7suTslhXdFHU3a1RTOHkiqARZtg9HdWg/Wo8gsLkXLU=,iv:L0aEQkQ5pyPKzVxbWrOYtIszV/AapdsdSI0yH7+xqrI=,tag:xvKEcWMfy1GnU4p1OfH1lA==,type:str] + lastmodified: "2025-12-01T21:50:41Z" + mac: ENC[AES256_GCM,data:rtICn+ljt414EWhSmVqM3IttqBx07a+m0MHEADNQ7s3USSfq3oEXqfoA1Nt6nIF/ZjNYeebNW9hiiJcZw/Hh749p3Fdu64w63MUTwsBciT651DwNNHJHVGwELaU72nI8amtVln+Ka0VD58/cM0V4mcw+eNvfUS+ykUVZAqmOiHo=,iv:IlgqHdb1gtajBfWogN6EgZ1V6h7ToTR1cArP8jEYocg=,tag:bagJOpWoMSvsgmKT/LsAJg==,type:str] unencrypted_suffix: _unencrypted - version: 3.12.2 + version: 3.11.0