diff --git a/flake.lock b/flake.lock index 0a07e67..7d1707d 100644 --- a/flake.lock +++ b/flake.lock @@ -20,7 +20,93 @@ "type": "github" } }, + "conduit": { + "inputs": { + "crane": "crane", + "fenix": "fenix", + "flake-utils": "flake-utils", + "nixpkgs": "nixpkgs_2" + }, + "locked": { + "lastModified": 1680688749, + "narHash": "sha256-j+jnjBbWMCbjxwIA0oh7Qwwg5e009kGWBqrCj9hQ9nY=", + "owner": "famedly", + "repo": "conduit", + "rev": "1b9e63f4269988a957a2e376355b2dacd2295c08", + "type": "gitlab" + }, + "original": { + "owner": "famedly", + "repo": "conduit", + "type": "gitlab" + } + }, + "crane": { + "inputs": { + "flake-compat": "flake-compat", + "flake-utils": [ + "conduit", + "flake-utils" + ], + "nixpkgs": [ + "conduit", + "nixpkgs" + ], + "rust-overlay": "rust-overlay" + }, + "locked": { + "lastModified": 1680584903, + "narHash": "sha256-uraq+D3jcLzw/UVk0xMHcnfILfIMa0DLrtAEq2nNlxU=", + "owner": "ipetkov", + "repo": "crane", + "rev": "65d3f6a3970cd46bef5eedfd458300f72c56b3c5", + "type": "github" + }, + "original": { + "owner": "ipetkov", + "repo": "crane", + "type": "github" + } + }, + "fenix": { + "inputs": { + "nixpkgs": [ + "conduit", + "nixpkgs" + ], + "rust-analyzer-src": "rust-analyzer-src" + }, + "locked": { + "lastModified": 1680607374, + "narHash": "sha256-U5iiPqbAanr+sQCCZ7zxYhwCXdcDpish8Uy4ELZeXM0=", + "owner": "nix-community", + "repo": "fenix", + "rev": "e70d498e97017daa59363eafa054619d4fa160c3", + "type": "github" + }, + "original": { + "owner": "nix-community", + "repo": "fenix", + "type": "github" + } + }, "flake-compat": { + "flake": false, + "locked": { + "lastModified": 1673956053, + "narHash": "sha256-4gtG9iQuiKITOjNQQeQIpoIB6b16fm+504Ch3sNKLd8=", + "owner": "edolstra", + "repo": "flake-compat", + "rev": "35bb57c0c8d8b62bbfd284272c928ceb64ddbde9", + "type": "github" + }, + "original": { + "owner": "edolstra", + "repo": "flake-compat", + "type": "github" + } + }, + "flake-compat_2": { "flake": false, "locked": { "lastModified": 1668681692, @@ -58,6 +144,21 @@ } }, "flake-utils": { + "locked": { + "lastModified": 1678901627, + "narHash": "sha256-U02riOqrKKzwjsxc/400XnElV+UtPUQWpANPlyazjH0=", + "owner": "numtide", + "repo": "flake-utils", + "rev": "93a2b84fc4b70d9e089d029deacc3583435c2ed6", + "type": "github" + }, + "original": { + "owner": "numtide", + "repo": "flake-utils", + "type": "github" + } + }, + "flake-utils_2": { "locked": { "lastModified": 1667395993, "narHash": "sha256-nuEHfE/LcWyuSWnS8t12N1wc105Qtau+/OdUAjtQ0rA=", @@ -106,10 +207,10 @@ }, "mms": { "inputs": { - "flake-compat": "flake-compat", - "flake-utils": "flake-utils", + "flake-compat": "flake-compat_2", + "flake-utils": "flake-utils_2", "nix": "nix", - "nixpkgs": "nixpkgs_3" + "nixpkgs": "nixpkgs_4" }, "locked": { "lastModified": 1669478601, @@ -128,7 +229,7 @@ "nix": { "inputs": { "lowdown-src": "lowdown-src", - "nixpkgs": "nixpkgs_2", + "nixpkgs": "nixpkgs_3", "nixpkgs-regression": "nixpkgs-regression" }, "locked": { @@ -194,6 +295,21 @@ } }, "nixpkgs_2": { + "locked": { + "lastModified": 1684015099, + "narHash": "sha256-KBR99DfioBrzcV9kwkYZn8oHwIPQ8/LWhhOERZgfDFg=", + "owner": "NixOS", + "repo": "nixpkgs", + "rev": "a3fe093364f627e621deb52e71071e59b14763a4", + "type": "github" + }, + "original": { + "owner": "NixOS", + "repo": "nixpkgs", + "type": "github" + } + }, + "nixpkgs_3": { "locked": { "lastModified": 1657693803, "narHash": "sha256-G++2CJ9u0E7NNTAi9n5G8TdDmGJXcIjkJ3NF8cetQB8=", @@ -209,7 +325,7 @@ "type": "github" } }, - "nixpkgs_3": { + "nixpkgs_4": { "locked": { "lastModified": 1669378442, "narHash": "sha256-nm+4PN0A4SnV0SzEchxrMyKPvI3Ld/aoom4PnHeHucs=", @@ -225,7 +341,7 @@ "type": "github" } }, - "nixpkgs_4": { + "nixpkgs_5": { "locked": { "lastModified": 1683478192, "narHash": "sha256-7f7RR71w0jRABDgBwjq3vE1yY3nrVJyXk8hDzu5kl1E=", @@ -244,10 +360,55 @@ "root": { "inputs": { "arion": "arion", + "conduit": "conduit", "mms": "mms", - "nixpkgs": "nixpkgs_4", + "nixpkgs": "nixpkgs_5", "nixpkgsUnstable": "nixpkgsUnstable" } + }, + "rust-analyzer-src": { + "flake": false, + "locked": { + "lastModified": 1680435407, + "narHash": "sha256-IPBtZCOh3BdrR+V77cL7r6WQnclWcZ/85BDYnmq/GnQ=", + "owner": "rust-lang", + "repo": "rust-analyzer", + "rev": "236576227a299fd19ba836b1834ab50c948af994", + "type": "github" + }, + "original": { + "owner": "rust-lang", + "ref": "nightly", + "repo": "rust-analyzer", + "type": "github" + } + }, + "rust-overlay": { + "inputs": { + "flake-utils": [ + "conduit", + "crane", + "flake-utils" + ], + "nixpkgs": [ + "conduit", + "crane", + "nixpkgs" + ] + }, + "locked": { + "lastModified": 1680488274, + "narHash": "sha256-0vYMrZDdokVmPQQXtFpnqA2wEgCCUXf5a3dDuDVshn0=", + "owner": "oxalica", + "repo": "rust-overlay", + "rev": "7ec2ff598a172c6e8584457167575b3a1a5d80d8", + "type": "github" + }, + "original": { + "owner": "oxalica", + "repo": "rust-overlay", + "type": "github" + } } }, "root": "root", diff --git a/flake.nix b/flake.nix index c9cd7d5..4aecbcb 100644 --- a/flake.nix +++ b/flake.nix @@ -5,6 +5,9 @@ #nixpkgs.url = "github:NixOS/nixpkgs/nixos-unstable"; arion.url = "github:hercules-ci/arion"; mms.url = "github:mkaito/nixos-modded-minecraft-servers"; + conduit = { + url = "gitlab:famedly/conduit"; + }; }; outputs = { self, nixpkgs, nixpkgsUnstable, ... }@inputs: @@ -32,7 +35,7 @@ katzencafe = { name, nodes, pkgs, pkgsUnstable, inputs, ... }: { deployment = { targetHost = "katzen.cafe"; - buildOnTarget = true; + # buildOnTarget = true; }; imports = [ ./modules/base-stuff.nix @@ -40,6 +43,7 @@ ./modules/postgres.nix #./modules/jitsi.nix ./modules/containers + ./modules/conduit.nix ./modules/keycloak.nix ./modules/forgejo.nix ./modules/mumble.nix diff --git a/modules/conduit.nix b/modules/conduit.nix index eb67509..501267e 100644 --- a/modules/conduit.nix +++ b/modules/conduit.nix @@ -1,4 +1,148 @@ -{ pkgs, inputs, ... }: +{ config +, pkgs +, inputs +, ... +}: + +let + # You'll need to edit these values + + # The hostname that will appear in your user and room IDs + server_name = "matrix.katzen.cafe"; + + # The hostname that Conduit actually runs on + # + # This can be the same as `server_name` if you want. This is only necessary + # when Conduit is running on a different machine than the one hosting your + # root domain. This configuration also assumes this is all running on a single + # machine, some tweaks will need to be made if this is not the case. + matrix_hostname = "matrix.${server_name}"; + + # An admin email for TLS certificate notifications + admin_email = "jade@schrottkatze.de"; + + # These ones you can leave alone + + # Build a dervation that stores the content of `${server_name}/.well-known/matrix/server` + well_known_server = pkgs.writeText "well-known-matrix-server" '' + { + "m.server": "${matrix_hostname}" + } + ''; + + # Build a dervation that stores the content of `${server_name}/.well-known/matrix/client` + well_known_client = pkgs.writeText "well-known-matrix-client" '' + { + "m.homeserver": { + "base_url": "https://${matrix_hostname}" + } + } + ''; +in + { - # TODO: matrix-conduit + # Configure Conduit itself + services.matrix-conduit = { + enable = true; + + # This causes NixOS to use the flake defined in this repository instead of + # the build of Conduit built into nixpkgs. + package = inputs.conduit.packages.${pkgs.system}.default; + + settings.global = { + inherit server_name; + }; + }; + + # Configure automated TLS acquisition/renewal + security.acme = { + acceptTerms = true; + defaults = { + email = admin_email; + }; + }; + + # ACME data must be readable by the NGINX user + users.users.nginx.extraGroups = [ + "acme" + ]; + + # Configure NGINX as a reverse proxy + services.nginx = { + enable = true; + recommendedProxySettings = true; + + virtualHosts = { + "${matrix_hostname}" = { + forceSSL = true; + enableACME = true; + + listen = [ + { + addr = "0.0.0.0"; + port = 443; + ssl = true; + } + { + addr = "0.0.0.0"; + port = 8448; + ssl = true; + } + ]; + + locations."/_matrix/" = { + proxyPass = "http://backend_conduit$request_uri"; + proxyWebsockets = true; + extraConfig = '' + proxy_set_header Host $host; + proxy_buffering off; + ''; + }; + + extraConfig = '' + merge_slashes off; + ''; + }; + + "${server_name}" = { + forceSSL = true; + enableACME = true; + + locations."=/.well-known/matrix/server" = { + # Use the contents of the derivation built previously + alias = "${well_known_server}"; + + extraConfig = '' + # Set the header since by default NGINX thinks it's just bytes + default_type application/json; + ''; + }; + + locations."=/.well-known/matrix/client" = { + # Use the contents of the derivation built previously + alias = "${well_known_client}"; + + extraConfig = '' + # Set the header since by default NGINX thinks it's just bytes + default_type application/json; + + # https://matrix.org/docs/spec/client_server/r0.4.0#web-browser-clients + add_header Access-Control-Allow-Origin "*"; + ''; + }; + }; + }; + + upstreams = { + "backend_conduit" = { + servers = { + "localhost:${toString config.services.matrix-conduit.settings.global.port}" = { }; + }; + }; + }; + }; + + # Open firewall ports for HTTP, HTTPS, and Matrix federation + networking.firewall.allowedTCPPorts = [ 80 443 8448 ]; + networking.firewall.allowedUDPPorts = [ 80 443 8448 ]; }