diff --git a/flake.nix b/flake.nix index 15c783f..5dc3348 100644 --- a/flake.nix +++ b/flake.nix @@ -185,6 +185,7 @@ iosevkaLyteTermSubset = prev.callPackage ./packages/iosevkaLyteTermSubset.nix { inherit iosevkaLyteTerm; }; + conduwuit = prev.callPackage ./packages/conduwuit.nix {}; nix-base-container-image = final.dockerTools.buildImageWithNixDb { name = "git.lyte.dev/lytedev/nix"; tag = "latest"; @@ -331,6 +332,7 @@ inherit system; modules = with nixosModules; [ home-manager-defaults + conduwuit # TODO: disko? hardware.nixosModules.common-cpu-intel diff --git a/modules/home-manager/ghostty/config b/modules/home-manager/ghostty/config index 943a8ed..8379927 100644 --- a/modules/home-manager/ghostty/config +++ b/modules/home-manager/ghostty/config @@ -989,6 +989,7 @@ working-directory = # keybind = alt+six=goto_tab:6 # keybind = alt+seven=goto_tab:7 +keybind = ctrl+enter=unbind keybind = ctrl+shift+2=increase_font_size:4 keybind = ctrl+shift+minus=decrease_font_size:0.5 keybind = ctrl+shift+plus=increase_font_size:0.5 diff --git a/modules/nixos/conduwuit.nix b/modules/nixos/conduwuit.nix new file mode 100644 index 0000000..dbebd47 --- /dev/null +++ b/modules/nixos/conduwuit.nix @@ -0,0 +1,277 @@ +# https://github.com/NixOS/nixpkgs/blob/32aaedffae68f54312c4c7726f828be82f278a48/nixos/modules/services/matrix/conduwuit.nix{ +{ + config, + lib, + pkgs, + ... +}: let + cfg = config.services.conduwuit; + defaultUser = "conduwuit"; + defaultGroup = "conduwuit"; + format = pkgs.formats.toml {}; + configFile = format.generate "conduwuit.toml" cfg.settings; +in { + meta.maintainers = with lib.maintainers; [niklaskorz]; + options.services.conduwuit = { + enable = lib.mkEnableOption "conduwuit"; + + user = lib.mkOption { + type = lib.types.nonEmptyStr; + description = '' + The user {command}`conduwuit` is run as. + ''; + default = defaultUser; + }; + + group = lib.mkOption { + type = lib.types.nonEmptyStr; + description = '' + The group {command}`conduwuit` is run as. + ''; + default = defaultGroup; + }; + + extraEnvironment = lib.mkOption { + type = lib.types.attrsOf lib.types.str; + description = "Extra Environment variables to pass to the conduwuit server."; + default = {}; + example = { + RUST_BACKTRACE = "yes"; + }; + }; + + package = lib.mkPackageOption pkgs.unstable-packages "conduwuit" {}; + + settings = lib.mkOption { + type = lib.types.submodule { + freeformType = format.type; + options = { + global.server_name = lib.mkOption { + type = lib.types.nonEmptyStr; + example = "example.com"; + description = "The server_name is the name of this server. It is used as a suffix for user and room ids."; + }; + global.address = lib.mkOption { + type = lib.types.nullOr (lib.types.listOf lib.types.nonEmptyStr); + default = null; + example = [ + "127.0.0.1" + "::1" + ]; + description = '' + Addresses (IPv4 or IPv6) to listen on for connections by the reverse proxy/tls terminator. + If set to `null`, conduwuit will listen on IPv4 and IPv6 localhost. + Must be `null` if `unix_socket_path` is set. + ''; + }; + global.port = lib.mkOption { + type = lib.types.listOf lib.types.port; + default = [6167]; + description = '' + The port(s) conduwuit will be running on. + You need to set up a reverse proxy in your web server (e.g. apache or nginx), + so all requests to /_matrix on port 443 and 8448 will be forwarded to the conduwuit + instance running on this port. + ''; + }; + global.unix_socket_path = lib.mkOption { + type = lib.types.nullOr lib.types.path; + default = null; + description = '' + Listen on a UNIX socket at the specified path. If listening on a UNIX socket, + listening on an address will be disabled. The `address` option must be set to + `null` (the default value). The option {option}`services.conduwuit.group` must + be set to a group your reverse proxy is part of. + + This will automatically add a system user "conduwuit" to your system if + {option}`services.conduwuit.user` is left at the default, and a "conduwuit" + group if {option}`services.conduwuit.group` is left at the default. + ''; + }; + global.unix_socket_perms = lib.mkOption { + type = lib.types.ints.positive; + default = 660; + description = "The default permissions (in octal) to create the UNIX socket with."; + }; + global.max_request_size = lib.mkOption { + type = lib.types.ints.positive; + default = 20000000; + description = "Max request size in bytes. Don't forget to also change it in the proxy."; + }; + global.allow_registration = lib.mkOption { + type = lib.types.bool; + default = false; + description = '' + Whether new users can register on this server. + + Registration with token requires `registration_token` or `registration_token_file` to be set. + + If set to true without a token configured, and + `yes_i_am_very_very_sure_i_want_an_open_registration_server_prone_to_abuse` + is set to true, users can freely register. + ''; + }; + global.allow_encryption = lib.mkOption { + type = lib.types.bool; + default = true; + description = "Whether new encrypted rooms can be created. Note: existing rooms will continue to work."; + }; + global.allow_federation = lib.mkOption { + type = lib.types.bool; + default = true; + description = '' + Whether this server federates with other servers. + ''; + }; + global.trusted_servers = lib.mkOption { + type = lib.types.listOf lib.types.nonEmptyStr; + default = ["matrix.org"]; + description = '' + Servers listed here will be used to gather public keys of other servers + (notary trusted key servers). + + Currently, conduwuit doesn't support inbound batched key requests, so + this list should only contain other Synapse servers. + + Example: `[ "matrix.org" "constellatory.net" "tchncs.de" ]` + ''; + }; + global.database_path = lib.mkOption { + readOnly = true; + type = lib.types.path; + default = "/var/lib/conduwuit/"; + description = '' + Path to the conduwuit database, the directory where conduwuit will save its data. + Note that database_path cannot be edited because of the service's reliance on systemd StateDir. + ''; + }; + global.allow_check_for_updates = lib.mkOption { + type = lib.types.bool; + default = false; + description = '' + If enabled, conduwuit will send a simple GET request periodically to + for any new announcements made. + Despite the name, this is not an update check endpoint, it is simply an announcement check endpoint. + + Disabled by default. + ''; + }; + }; + }; + default = {}; + # TOML does not allow null values, so we use null to omit those fields + apply = lib.filterAttrsRecursive (_: v: v != null); + description = '' + Generates the conduwuit.toml configuration file. Refer to + + for details on supported values. + ''; + }; + }; + + config = lib.mkIf cfg.enable { + assertions = [ + { + assertion = !(cfg.settings ? global.unix_socket_path) || !(cfg.settings ? global.address); + message = '' + In `services.conduwuit.settings.global`, `unix_socket_path` and `address` cannot be set at the + same time. + Leave one of the two options unset or explicitly set them to `null`. + ''; + } + { + assertion = cfg.user != defaultUser -> config ? users.users.${cfg.user}; + message = "If `services.conduwuit.user` is changed, the configured user must already exist."; + } + { + assertion = cfg.group != defaultGroup -> config ? users.groups.${cfg.group}; + message = "If `services.conduwuit.group` is changed, the configured group must already exist."; + } + ]; + + users.users = lib.mkIf (cfg.user == defaultUser) { + ${defaultUser} = { + group = cfg.group; + home = cfg.settings.global.database_path; + isSystemUser = true; + }; + }; + + users.groups = lib.mkIf (cfg.group == defaultGroup) { + ${defaultGroup} = {}; + }; + + systemd.services.conduwuit = { + description = "Conduwuit Matrix Server"; + documentation = ["https://conduwuit.puppyirl.gay/"]; + wantedBy = ["multi-user.target"]; + wants = ["network-online.target"]; + after = ["network-online.target"]; + environment = lib.mkMerge [ + {CONDUWUIT_CONFIG = configFile;} + cfg.extraEnvironment + ]; + startLimitBurst = 5; + startLimitIntervalSec = 60; + serviceConfig = { + DynamicUser = true; + User = cfg.user; + Group = cfg.group; + + DevicePolicy = "closed"; + LockPersonality = true; + MemoryDenyWriteExecute = true; + NoNewPrivileges = true; + ProtectClock = true; + ProtectControlGroups = true; + ProtectHome = true; + ProtectHostname = true; + ProtectKernelLogs = true; + ProtectKernelModules = true; + ProtectKernelTunables = true; + PrivateDevices = true; + PrivateMounts = true; + PrivateTmp = true; + PrivateUsers = true; + PrivateIPC = true; + RemoveIPC = true; + RestrictAddressFamilies = [ + "AF_INET" + "AF_INET6" + "AF_UNIX" + ]; + RestrictNamespaces = true; + RestrictRealtime = true; + SystemCallArchitectures = "native"; + SystemCallFilter = [ + "@system-service" + "@resources" + "~@clock" + "@debug" + "@module" + "@mount" + "@reboot" + "@swap" + "@cpu-emulation" + "@obsolete" + "@timer" + "@chown" + "@setuid" + "@privileged" + "@keyring" + "@ipc" + ]; + SystemCallErrorNumber = "EPERM"; + + StateDirectory = "conduwuit"; + StateDirectoryMode = "0700"; + RuntimeDirectory = "conduwuit"; + RuntimeDirectoryMode = "0750"; + + ExecStart = lib.getExe cfg.package; + Restart = "on-failure"; + RestartSec = 10; + }; + }; + }; +} diff --git a/modules/nixos/default.nix b/modules/nixos/default.nix index c6e0f8a..b082664 100644 --- a/modules/nixos/default.nix +++ b/modules/nixos/default.nix @@ -179,6 +179,7 @@ }; deno-netlify-ddns-client = import ./deno-netlify-ddns-client.nix; + conduwuit = import ./conduwuit.nix; fallback-hostname = {lib, ...}: { networking.hostName = lib.mkDefault "set-a-hostname-dingus"; @@ -749,6 +750,8 @@ variables.GSK_RENDERER = "gl"; systemPackages = with pkgs; [ bitwarden + # adwaita-gtk-theme + papirus-icon-theme adwaita-icon-theme adwaita-icon-theme-legacy ]; diff --git a/nixos/beefcake.nix b/nixos/beefcake.nix index 2fa043b..069bfab 100644 --- a/nixos/beefcake.nix +++ b/nixos/beefcake.nix @@ -1786,6 +1786,36 @@ sudo nix run nixpkgs#ipmitool -- raw 0x30 0x30 0x02 0xff 0x00 factorio-server-settings = {mode = "0777";}; }; } + ({ + pkgs, + config, + ... + }: let + port = builtins.head config.services.conduwuit.settings.global.port; + sPort = toString port; + in { + sops.secrets.matrix-registration-token-file.mode = "0400"; + services.conduwuit = { + enable = true; + settings = { + global = { + allow_check_for_updates = true; + allow_federation = false; + registration_token_file = config.sops.secrets.matrix-registration-token-file.path; + server_name = "lyte.dev"; + }; + }; + }; + services.caddy.virtualHosts."matrix.lyte.dev".extraConfig = '' + reverse_proxy /_matrix/* :${sPort} + reverse_proxy /_synapse/client/* :${sPort} + ''; + services.caddy.virtualHosts."lyte.dev:8448".extraConfig = '' + reverse_proxy /_matrix/* :${sPort} + ''; + # TODO: backups + # TODO: reverse proxy + }) ]; /* diff --git a/nixos/router.nix b/nixos/router.nix index 612bbe3..df10d79 100644 --- a/nixos/router.nix +++ b/nixos/router.nix @@ -56,6 +56,7 @@ "git.lyte.dev" "grafana.h.lyte.dev" "idm.h.lyte.dev" + "matrix.lyte.dev" "nextcloud.h.lyte.dev" "nix.h.lyte.dev" "onlyoffice.h.lyte.dev" diff --git a/secrets/beefcake/secrets.yml b/secrets/beefcake/secrets.yml index f3b9f82..d190bf4 100644 --- a/secrets/beefcake/secrets.yml +++ b/secrets/beefcake/secrets.yml @@ -27,6 +27,7 @@ restic-rascal-passphrase: ENC[AES256_GCM,data:yonKbBh4riGwxc/qcj8F/qrgAtA1sWhYej restic-rascal-ssh-private-key: ENC[AES256_GCM,data:ddsOs0XsayyQI9qc6LzwQpdDnfwNpbj8PbBJ5fyuqtlVNYndeLxaYcbZI2ULSUhgR1tN0FS+ggGTHQhVvjwksNvpskUGHNKkSLKH3D/mn5N9tsoeAblN4gZsloZdqXBVzEehumcQMdhh6iy6NkNbuinKrVKDhLV25PrFKuSBEYw9VHU7HAMW5Tfop3RzBXjZWETCDAR2OQa7d1dXsJ0Kw6b9RFmRe5MGQ0J7YhjdTg26JGMMVSeHvr5UbiUJkGA5RvOLEDM2Dfai7Lf8yRPZVxUl+rdRsNvNYEoYGu5rGLUFcuqIbQ+s40dP2uXwWauwkIvHUjEahkbP0httj4Kg3qIJBRPg7OuS+MOwAnLEAs3hl5zeBV396yA9qjWW8nhnbml58/uFFbfXbJWTM3r8cMpFbHKD+Ojo/99fm5Vy3pAMzNzEsHOaT+iyDYyNkV5OH1GyKK9n7kIRLdqmWe7GmaKXlwVvNUPi3RvLX9VXq83a4BuupFyTmaNfPGMs/17830aleV674+QVgKh3VyFtuJy6KBpMXDv16wFo,iv:S2I3h6pmKLxEc29E0zn2b8lscqA//5/ZMTV9q+/tdvs=,tag:ALeCT+nrVPDfS21xC555sA==,type:str] restic-ssh-priv-key-benland: ENC[AES256_GCM,data:G+uiYZTvqXhpJb66j6Q6S+otlXeRX0CdYeMHzSMjIbvbI0AVm0yCU7COO5/O8i47NpvrKKS1kVxVEK8ixLRUowkl3hgRXhxsBIPFnpkMD0ENmJttm4HOpi0qIWMwzPYTjkz/slY4HcTFnCfYy1ZpURQdWwZsr1EdAA05bUMTtM22R3uOMzjO8uf72PCWX7yffo8MxsLmWvNVAOhVlrb2H5KQNR/IquFK3TFoZitq5nVDG9tcEFkX+lgA3zsmCHU/2DvvodgeRoltaAFvgjVznNGf4e5p8owHUtSzX52HwGZRiUlMuhpre2gm1r73n8AyZe41II+LX/85fMfZDdyayIGv3AAMBib8H0/AoChexRcdLQEmzOgRrXsgucDJrWSWP6WMBVyamUm79m5ep0fvL1lJftuJqN0uuq9dBrispdso4x+6jk/pDf5pEM/FE6s1rY832BEb7q0PnjyvVogOez+cIihmMpDdnS0A/8TFzg29i3C+93x5vrt3k7atNzR/jN+/GqX2FKLzxWrrIw2d,iv:IP+N8JQu+XRvwTtBnxu54ujzU5UliltXG3mk9HfJaN8=,tag:4oinE9QMaSh8IfUd/ttM3Q==,type:str] paperless-superuser-password: ENC[AES256_GCM,data:lypWK73mOYI2hyQAW/4T3cDiVtsts3kKb7LZb9ES3n97Kn5l,iv:jBHUBFbb4GqQ3gnK0h5VCaGj3/kd3/eGa1QFiE7+B9I=,tag:UoQar+x1xVnCV2k+9hYjWA==,type:str] +matrix-registration-token-file: ENC[AES256_GCM,data:SthCOqjdMhdWK6mDaVcG3LSBsLEhNNpgwPQmdKDcQJJygTnkYwUY6RdD6Joxgxqscz8evJfogtw/iNFdocm/YEwn/0pvbAiC0GLxT0Ar3Rg6aXeedrbhHQ==,iv:fq4mmP14w7Y0+zNqSI58KZ5+6e4YHm2XhmE7zs0/SgE=,tag:Yu0prJTc3b+fpjK75GBVvA==,type:str] factorio-server-settings: ENC[AES256_GCM,data:KlHkHGenkoLtqt0YCETwQdhH0tvvqsyake3lC9Wimso3Y8IXvDfkLpOTE53Jq4frf1QMJh0LYyle+AmIgGvB0gAp/4fM1E4Ah9JPtKkcjVPyQIypuaDsPaVQMxMlJt1+TLX2fbSWdxOo0lulNg==,iv:AHq37PY3ZxKF0+ClUrSvhJSBuXFtGZLBZW/ZADrVqLI=,tag:B0gFyy6rmd6CGJfzAhO02A==,type:str] flanilla.env: ENC[AES256_GCM,data:qp0cpjHgpFx2gICtH8vNusJt08MLOIS3,iv:lugXNEJpMJ8mSwvo2jDwTwsY0x3kcHQDc29Z2Wz+LB4=,tag:0/FWQKUXePemFWGXbH1Tjg==,type:str] sops: @@ -53,8 +54,8 @@ sops: bGpacHFRSkJYUUMwOEh4cVBXZ1NESmsKa5EhZ7148ojCqZldukLcPLr93HqnpNgq rMI0Nyz4Z4lkTVMRpA94zyNTkNwJ02/CYcKi8EJi6jGZnNPUTcnTwg== -----END AGE ENCRYPTED FILE----- - lastmodified: "2024-12-26T16:42:22Z" - mac: ENC[AES256_GCM,data:COh57637D7BnYa2ke+SsGnRuyWmS3X6xDJNV0ATWEHqKjckZ2tqyfL1ugGuokmqilIsRcXi2q5sqCd8uNrWZLicZ/6eQ5w7CqoFU8OEON6ERibQ36X0oLsz9teuT+bx9ZMfzYOKh0LZY0XP9es7W+4PC3XiBJcIB2GWTTrrGaI4=,iv:aeBvVjC7Qn/ohYmpC6lvcve0bMSBsvfRSa1kyiyj0Rg=,tag:hld5rkOq5mfcGFShKuKgng==,type:str] + lastmodified: "2025-02-11T06:57:42Z" + mac: ENC[AES256_GCM,data:EtQKfdiE0NLZaFCZ8BIsGY6zhBU5YTVOju9HFPSrJ1DAyLj/T0izWtQKUTxYtzFSY+9CTptH5RTB3+z0RrC4zs+nBp44CWfQC5GB4odgd5U797YTuC4O5jngDWWemRjf2jD/HEngznSqjHzCNuGzNCx16eYHuebSQOiQGwhTeoc=,iv:qi6UBV7u1JTyFB3Rm0DeJA6ZcbigEqW39FhrcGfspmw=,tag:ADA24OcFSUK8Q/Gp2PUTLA==,type:str] pgp: [] unencrypted_suffix: _unencrypted - version: 3.9.1 + version: 3.9.2