diff options
Diffstat (limited to '')
24 files changed, 982 insertions, 549 deletions
diff --git a/flake.lock b/flake.lock index a23f22a..75b1bc4 100644 --- a/flake.lock +++ b/flake.lock @@ -43,11 +43,11 @@ }, "crane": { "locked": { - "lastModified": 1742394900, - "narHash": "sha256-vVOAp9ahvnU+fQoKd4SEXB2JG2wbENkpqcwlkIXgUC0=", + "lastModified": 1745022865, + "narHash": "sha256-tXL4qUlyYZEGOHUKUWjmmcvJjjLQ+4U38lPWSc8Cgdo=", "owner": "ipetkov", "repo": "crane", - "rev": "70947c1908108c0c551ddfd73d4f750ff2ea67cd", + "rev": "25ca4c50039d91ad88cc0b8feacb9ad7f748dedf", "type": "github" }, "original": { @@ -111,11 +111,11 @@ ] }, "locked": { - "lastModified": 1741786315, - "narHash": "sha256-VT65AE2syHVj6v/DGB496bqBnu1PXrrzwlw07/Zpllc=", + "lastModified": 1745224732, + "narHash": "sha256-0OWgbEKhpMLpk3WQi3ugOwxWW4Y6JVpKiQ+o0nuNzus=", "owner": "nix-community", "repo": "disko", - "rev": "0d8c6ad4a43906d14abd5c60e0ffe7b587b213de", + "rev": "1770bf1ae5da05564f86b969ef21c7228cc1a70b", "type": "github" }, "original": { @@ -214,11 +214,11 @@ }, "nixpkgs": { "locked": { - "lastModified": 1743036386, - "narHash": "sha256-W1Qap/jwnpvWPXC+cUp0PlaZsJO05sfQfzffRrYW7YY=", + "lastModified": 1745186762, + "narHash": "sha256-vn1ixtFWtellgcZpdIoxCVu9agdK3647hi7lcc/58eQ=", "owner": "NixOS", "repo": "nixpkgs", - "rev": "1751c9cb80247edc5fed79b90211a92c56bf91e6", + "rev": "c16961fda203155a314b0c75c13961c29e9ea7b0", "type": "github" }, "original": { @@ -245,11 +245,11 @@ }, "nixpkgs-unstable": { "locked": { - "lastModified": 1743039536, - "narHash": "sha256-O3GFPU0Uyv80LKVMMukVqrfxSzWKkBwQIHN2UnRSCZk=", + "lastModified": 1745215074, + "narHash": "sha256-JjkdlVI9BImDV5RrCiJk17cMSIqbefUXBM9trHRif+c=", "owner": "NixOS", "repo": "nixpkgs", - "rev": "0ab4a506520ea9247e673e9849ecf84c72f88be2", + "rev": "78e2cd1a1590f8c70b329cbc7d13bb2ab5b5a16c", "type": "github" }, "original": { @@ -278,11 +278,11 @@ ] }, "locked": { - "lastModified": 1741508717, - "narHash": "sha256-iQf1WdNxaApOFHIx4RLMRZ4f8g+8Xp0Z1/E/Mz2rLxY=", + "lastModified": 1744897914, + "narHash": "sha256-GIVU92o2TZBnKQXTb76zpQbWR4zjU2rFqWKNIIpXnqA=", "owner": "yaxitech", "repo": "ragenix", - "rev": "2a2bea99d74927e54adf53cbf113219def67d5c9", + "rev": "40f2e17ecaeab4d78ec323e96a04548c0aaa5223", "type": "github" }, "original": { @@ -317,11 +317,11 @@ ] }, "locked": { - "lastModified": 1743042789, - "narHash": "sha256-yPlxN0r3pQjUIwyX/qeWSTdpHjWy/AfmM0PK1bYkO18=", + "lastModified": 1745289264, + "narHash": "sha256-7nt+UJ7qaIUe2J7BdnEEph9n2eKEwxUwKS/QIr091uA=", "owner": "oxalica", "repo": "rust-overlay", - "rev": "b4d2dee9d16e7725b71969f28862ded3a94a7934", + "rev": "3b7171858c20d5293360042936058fb0c4cb93a9", "type": "github" }, "original": { @@ -342,11 +342,11 @@ "nixpkgs-24_11": "nixpkgs-24_11" }, "locked": { - "lastModified": 1742413977, - "narHash": "sha256-NkhM9GVu3HL+MiXtGD0TjuPCQ4GFVJPBZ8KyI2cFDGU=", + "lastModified": 1745164839, + "narHash": "sha256-+0T3pBcl5BD3qHB2nGfwwnRhb4EeNlJEI0BUm5fXPmE=", "owner": "simple-nixos-mailserver", "repo": "nixos-mailserver", - "rev": "b4fbffe79c00f19be94b86b4144ff67541613659", + "rev": "42651ce2d337921c99ae0c293ed9af49f7a89c6a", "type": "gitlab" }, "original": { @@ -378,11 +378,11 @@ ] }, "locked": { - "lastModified": 1742982148, - "narHash": "sha256-aRA6LSxjlbMI6MmMzi/M5WH/ynd8pK+vACD9za3MKLQ=", + "lastModified": 1744961264, + "narHash": "sha256-aRmUh0AMwcbdjJHnytg1e5h5ECcaWtIFQa6d9gI85AI=", "owner": "numtide", "repo": "treefmt-nix", - "rev": "61c88349bf6dff49fa52d7dfc39b21026c2a8881", + "rev": "8d404a69efe76146368885110f29a2ca3700bee6", "type": "github" }, "original": { diff --git a/hosts/by-name/server2/configuration.nix b/hosts/by-name/server2/configuration.nix index ba0de14..24513f4 100644 --- a/hosts/by-name/server2/configuration.nix +++ b/hosts/by-name/server2/configuration.nix @@ -83,6 +83,26 @@ }; redlib.enable = true; rust-motd.enable = true; + sharkey = { + enable = true; + fqdn = "sharkey.vhack.eu"; + settings = { + id = "aidx"; + + maxNoteLength = 8192; + maxFileSize = 1024 * 1024 * 1024; + proxyRemoteFiles = true; + + # > At the suggestion of Sharkey maintainers, + # > this allows the server to run multiple workers + # > and without this (and postgres tuning), the instance runs slowly. + # Copied from: https://github.com/sodiboo/system/blob/b63c7b27f49043e8701b3ff5e1441cd27d5a2fff/sharkey.mod.nix#L21-L23 + clusterLimit = 3; + + signToActivityPubGet = true; + CheckActivityPubGetSigned = false; + }; + }; taskchampion-sync.enable = true; users.enable = true; }; diff --git a/hosts/by-name/server3/configuration.nix b/hosts/by-name/server3/configuration.nix index 7f5bce5..17085e8 100644 --- a/hosts/by-name/server3/configuration.nix +++ b/hosts/by-name/server3/configuration.nix @@ -71,6 +71,7 @@ enable = true; fqdn = "mail.vhack.eu"; admin = "admin@vhack.eu"; + initialAdminPassword = "$6$k/JGlODSgRyb6dG2$KV78QYipkS423WQQoQIcEWNFZdq4uuS5uIpJUNL1WLmXsD3b6KuLtt18TNU24Hnpup5TbMM5vtui/I.vGAybS/"; security = { dkimKeys = let loadKey = name: { @@ -84,19 +85,7 @@ verificationMode = "strict"; }; openFirewall = true; - principals = [ - { - class = "individual"; - name = "soispha"; - secret = "$2b$05$XX36sJuHNbTFvi8DFldscOeQBHahluSkiUqD9QGzQaET7NJusSuQW"; - email = [ - "soispha@vhack.eu" - "abuse@vhack.eu" - "postmaster@vhack.eu" - "admin@vhack.eu" - ]; - } - ]; + principals = null; }; postgresql.enable = true; rust-motd.enable = true; diff --git a/modules/by-name/co/constants/module.nix b/modules/by-name/co/constants/module.nix index 9db6445..2115a37 100644 --- a/modules/by-name/co/constants/module.nix +++ b/modules/by-name/co/constants/module.nix @@ -25,6 +25,7 @@ config.vhack.constants = { ids.uids = { # Keep this sorted with `!sort --numeric-sort --key=2 --field-separator="="` + systemd-coredump = 151; # GROUP opendkim = 221; mautrix-whatsapp = 222; etebase-server = 223; @@ -43,16 +44,22 @@ nscd = 330; sshd = 331; systemd-oom = 332; + resolvconf = 333; # GROUP nix-sync = 334; nextcloud = 335; redis-nextcloud = 336; taskchampion = 337; + stalwart-mail-certificates = 338; # GROUP + sharkey = 339; + redis-sharkey = 340; # As per the NixOS file, the uids should not be greater or equal to 400; }; ids.gids = let inherit (config.vhack.constants.ids) uids; in { + # Please add your groups to the users and inherit them here. + # This avoids having an user/group id mismatch. inherit (uids) acme @@ -76,13 +83,13 @@ sshd stalwart-mail systemd-oom + sharkey + redis-sharkey + systemd-coredump # matches systemd-coredump user + resolvconf # This group is not matched to an user? + stalwart-mail-certificates # This group is used to connect nginx and stalwart-mail ; - # Keep this sorted with `!sort --numeric-sort --key=2 --field-separator="="` - systemd-coredump = 151; # matches systemd-coredump user - resolvconf = 333; # This group is not matched to an user? - stalwart-mail-certificates = 338; # This group is used to connect nginx and stalwart-mail - # The gid should match the uid. Thus should not be >= 400; }; }; diff --git a/modules/by-name/sh/sharkey/module.nix b/modules/by-name/sh/sharkey/module.nix new file mode 100644 index 0000000..a2f5445 --- /dev/null +++ b/modules/by-name/sh/sharkey/module.nix @@ -0,0 +1,297 @@ +# Source: https://github.com/sodiboo/system/blob/b63c7b27f49043e8701b3ff5e1441cd27d5a2fff/sharkey/module.nix +{ + config, + lib, + pkgs, + vhackPackages, + ... +}: let + cfg = config.vhack.sharkey; + + createDB = cfg.database.host == "127.0.0.1" && cfg.database.createLocally; + + settingsFormat = pkgs.formats.yaml {}; + configFile = settingsFormat.generate "sharkey-config.yml" cfg.settings; +in { + options.vhack.sharkey = { + enable = lib.mkEnableOption "sharkey"; + + fqdn = lib.mkOption { + description = "The fully qualified domain name of this instance."; + type = lib.types.str; + example = "sharkey.shonk.social"; + }; + + package = lib.mkOption { + type = lib.types.package; + default = vhackPackages.sharkey; + defaultText = lib.literalExpression "vhackPackages.sharkey"; + description = "Sharkey package to use."; + }; + + dataDirectory = lib.mkOption { + type = lib.types.path; + default = "/var/lib/sharkey"; + description = "The directory where sharkey stores it's data."; + + # This is already set in the package. + readOnly = true; + }; + + database = { + createLocally = lib.mkOption { + description = "Whether to enable local db creation."; + type = lib.types.bool; + default = true; + }; + + host = lib.mkOption { + type = lib.types.str; + default = "127.0.0.1"; + description = "The database host."; + }; + + port = lib.mkOption { + type = lib.types.port; + default = 5432; + description = "The database port."; + }; + + name = lib.mkOption { + type = lib.types.str; + default = "sharkey"; + description = "The database name in postgresql."; + }; + }; + + settings = lib.mkOption { + inherit (settingsFormat) type; + default = {}; + description = '' + Configuration for Sharkey, see + <link xlink:href="https://activitypub.software/TransFem-org/Sharkey/-/blob/develop/.config/example.yml"/> + for supported settings. + ''; + }; + }; + + config = lib.mkIf cfg.enable { + environment.systemPackages = [cfg.package]; + + vhack = { + nginx.enable = true; + + sharkey.settings = { + id = "aidx"; + + url = "https://${cfg.fqdn}/"; + port = 5312; + + db = { + inherit (cfg.database) host port; + db = cfg.database.name; + user = cfg.database.name; + pass = "sharkey-password"; + }; + redis = { + path = config.services.redis.servers."sharkey".unixSocket; + }; + }; + + persist.directories = [ + { + directory = "${config.services.redis.servers."sharkey".settings.dir}"; + user = "sharkey"; + group = "redis-sharey"; + mode = "0770"; + } + { + directory = "${cfg.dataDirectory}"; + user = "sharkey"; + group = "sharkey"; + mode = "0770"; + } + ]; + }; + + services = { + nginx.virtualHosts."${cfg.fqdn}" = { + locations."/" = { + proxyPass = "http://127.0.0.1:${toString cfg.settings.port}"; + proxyWebsockets = true; + }; + + # proxy_set_header Host $host; + # proxy_http_version 1.1; + # proxy_redirect off; + # + # # If it's behind another reverse proxy or CDN, remove the following. + # proxy_set_header X-Real-IP $remote_addr; + # proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for; + # proxy_set_header X-Forwarded-Proto https; + # + # # For WebSocket + # proxy_set_header Upgrade $http_upgrade; + # proxy_set_header Connection $connection_upgrade; + # + # # Cache settings + # proxy_cache cache1; + # proxy_cache_lock on; + # proxy_cache_use_stale updating; + # proxy_force_ranges on; + # add_header X-Cache $upstream_cache_status; + + enableACME = true; + forceSSL = true; + }; + + postgresql = lib.mkIf createDB { + enable = true; + settings.port = cfg.database.port; + ensureUsers = [ + { + inherit (cfg.database) name; + ensureDBOwnership = true; + } + ]; + ensureDatabases = [cfg.database.name]; + }; + + redis = { + servers."sharkey" = { + enable = true; + + user = "sharkey"; + + # Disable TCP listening. (We have a UNIX socket) + port = 0; + bind = null; + + settings = { + protected-mode = true; + enable-protected-configs = false; + enable-debug-command = false; + enable-module-command = false; + + supervised = "systemd"; + stop-writes-on-bgsave-error = true; + sanitize-dump-payload = "clients"; + }; + }; + }; + }; + + systemd.services.postgresql.postStart = '' + $PSQL -tAc "ALTER ROLE ${cfg.database.name} WITH ENCRYPTED PASSWORD 'sharkey-password';" + ''; + + systemd.services.sharkey = { + requires = + [ + "redis-sharkey.service" + "network-online.target" + ] + ++ lib.optionals createDB ["postgresql.service"]; + + after = + [ + "redis-sharkey.service" + "network-online.target" + ] + ++ lib.optionals createDB ["postgresql.service"]; + + wantedBy = ["multi-user.target"]; + + environment = { + MISSKEY_CONFIG_YML = "${configFile}"; + NODE_ENV = "production"; + }; + + serviceConfig = { + Type = "simple"; + + StateDirectory = "sharkey"; + StateDirectoryMode = "0700"; + CacheDirectory = "sharkey"; + RuntimeDirectory = "sharkey"; + RuntimeDirectoryMode = "0700"; + ExecStart = "${lib.getExe cfg.package} migrateandstart"; + + TimeoutSec = 60; + Restart = "no"; + + StandardOutput = "journal"; + StandardError = "journal"; + SyslogIdentifier = "sharkey"; + + User = "sharkey"; + Group = "sharkey"; + + # Bind standard privileged ports + AmbientCapabilities = []; + CapabilityBoundingSet = []; + + ReadWritePaths = [ + "${cfg.dataDirectory}" + ]; + + # Hardening + DeviceAllow = [""]; + LockPersonality = true; + # Probably needed for v8's JIT (crashes with it on). + MemoryDenyWriteExecute = false; + PrivateDevices = true; + PrivateUsers = true; + ProcSubset = "pid"; + PrivateTmp = true; + ProtectClock = true; + ProtectControlGroups = true; + ProtectHome = true; + ProtectHostname = true; + ProtectKernelLogs = true; + ProtectKernelModules = true; + ProtectKernelTunables = true; + ProtectProc = "invisible"; + ProtectSystem = "strict"; + RestrictAddressFamilies = [ + "AF_UNIX" # Local communication unix(7) + "AF_INET" # IPv4 Internet protocols ip(7) + "AF_INET6" # IPv6 Internet protocols ipv6(7) + # Needed for nodes `os.networkInterfaces()` function. + "AF_NETLINK" # Kernel user interface device netlink(7) + ]; + RestrictNamespaces = true; + RestrictRealtime = true; + RestrictSUIDSGID = true; + SystemCallArchitectures = "native"; + SystemCallFilter = [ + "@system-service" + "~@privileged" + "~@mount" + ]; + UMask = "0077"; + }; + }; + + users = { + groups.sharkey = { + gid = config.vhack.constants.ids.gids.sharkey; + }; + users.sharkey = { + isSystemUser = true; + group = "sharkey"; + uid = config.vhack.constants.ids.uids.sharkey; + home = cfg.package; + packages = [cfg.package]; + }; + + groups.redis-sharkey = { + gid = config.vhack.constants.ids.gids.redis-sharkey; + }; + users.redis-sharkey = { + group = "redis-sharkey"; + uid = config.vhack.constants.ids.uids.redis-sharkey; + }; + }; + }; +} diff --git a/modules/by-name/st/stalwart-mail/module.nix b/modules/by-name/st/stalwart-mail/module.nix index cc4acc9..396116d 100644 --- a/modules/by-name/st/stalwart-mail/module.nix +++ b/modules/by-name/st/stalwart-mail/module.nix @@ -10,6 +10,33 @@ configFormat = pkgs.formats.toml {}; configFile = configFormat.generate "stalwart-mail.toml" topCfg.settings; + + hashedPassword = let + prefix = pre: lib.types.strMatching "^${lib.strings.escapeRegex pre}.*"; + in + lib.types.oneOf [ + (prefix "$argon2") + (prefix "$pbkdf2") + (prefix "$scrypt") + (prefix "$2") # bcrypt + (prefix "$6$") # sha-512 + (prefix "$5$") # sha-256 + (prefix "$sha1") + (prefix "$1") # md5 + (prefix "_") # BSDi crypt + (prefix "{SHA}") # base64 sha + (prefix "{SSHA}") # base64 salted sha + + # unix crypt + (prefix "{CRYPT}") + (prefix "{crypt}") + + # Plain text + (prefix "{PLAIN}") + (prefix "{plain}") + (prefix "{CLEAR}") + (prefix "{clear}") + ]; in { imports = [ ./settings.nix @@ -24,14 +51,20 @@ in { description = '' Email address to advertise as administrator. This is the address, where dkim, spv etc. refusal reports are sent to. - - The format should be: `mailto:<name>@<domain>` ''; type = lib.types.str; - example = "mailto:dmarc+rua@example.com"; + example = "dmarc+rua@example.com"; default = ""; }; + initialAdminPassword = lib.mkOption { + type = hashedPassword; + description = '' + The hash of the password for the admin account, used to bootstrap account + creation. + ''; + }; + fqdn = lib.mkOption { type = lib.types.str; example = "mail.foss-syndicate.org"; @@ -61,32 +94,7 @@ in { }; secret = lib.mkOption { - type = let - prefix = pre: lib.types.strMatching "^${lib.strings.escapeRegex pre}.*"; - in - lib.types.oneOf [ - (prefix "$argon2") - (prefix "$pbkdf2") - (prefix "$scrypt") - (prefix "$2") # bcrypt - (prefix "$6$") # sha-512 - (prefix "$5$") # sha-256 - (prefix "$sha1") - (prefix "$1") # md5 - (prefix "_") # BSDi crypt - (prefix "{SHA}") # base64 sha - (prefix "{SSHA}") # base64 salted sha - - # unix crypt - (prefix "{CRYPT}") - (prefix "{crypt}") - - # Plain text - (prefix "{PLAIN}") - (prefix "{plain}") - (prefix "{CLEAR}") - (prefix "{clear}") - ]; + type = hashedPassword; description = '' Sets the password for the user account. Passwords can be stored hashed or in plain text (not recommended). @@ -188,7 +196,11 @@ in { }; nginx.virtualHosts."${cfg.fqdn}" = { - locations."/".proxyPass = "http://${builtins.elemAt config.services.stalwart-mail.settings.server.listener.http.bind 0}"; + locations."/" = { + proxyPass = "http://${builtins.elemAt config.services.stalwart-mail.settings.server.listener.http.bind 0}"; + recommendedProxySettings = true; + }; + useACMEHost = "${cfg.fqdn}"; forceSSL = true; }; diff --git a/modules/by-name/st/stalwart-mail/settings.nix b/modules/by-name/st/stalwart-mail/settings.nix index 907cea9..765d8db 100644 --- a/modules/by-name/st/stalwart-mail/settings.nix +++ b/modules/by-name/st/stalwart-mail/settings.nix @@ -100,7 +100,7 @@ in { from-name = "'TLS Report'"; from-address = "'noreply-tls@${cfg.fqdn}'"; org-name = "'Foss Syndicate Mail Handling'"; - contact-info = "'${cfg.admin}'"; + contact-info = "'mailto:${cfg.admin}'"; send = "daily"; max-size = 26214400; # 25 MiB sign = lib.mkIf (cfg.security != null) "'${cfg.fqdn}'"; @@ -110,7 +110,7 @@ in { from-name = "'DMARC Report'"; from-address = "'noreply-dmarc@${cfg.fqdn}'"; org-name = "'Foss Syndicate Mail Handling'"; - contact-info = "'${cfg.admin}'"; + contact-info = "'mailto:${cfg.admin}'"; send = "weekly"; max-size = 26214400; # 25MiB sign = lib.mkIf (cfg.security != null) "'${cfg.fqdn}'"; @@ -541,6 +541,11 @@ in { }; }; + authentication.fallback-admin = { + user = cfg.admin; + secret = cfg.initialAdminPassword; + }; + certificate = { "default" = { cert = "%{file:${config.security.acme.certs.${cfg.fqdn}.directory}/fullchain.pem}%"; diff --git a/modules/by-name/ta/taskchampion-sync/module.nix b/modules/by-name/ta/taskchampion-sync/module.nix index 2fa0a3f..1870186 100644 --- a/modules/by-name/ta/taskchampion-sync/module.nix +++ b/modules/by-name/ta/taskchampion-sync/module.nix @@ -4,6 +4,7 @@ ... }: let cfg = config.vhack.taskchampion-sync; + dataDirectory = "/var/lib/taskchampion-sync-server"; in { options.vhack.taskchampion-sync = { enable = lib.mkEnableOption "taskchampion-sync"; @@ -16,13 +17,18 @@ in { }; vhack.persist.directories = [ - "/var/lib/taskchampion-sync-server" + { + directory = dataDirectory; + user = "taskchampion"; + group = "taskchampion"; + mode = "0700"; + } ]; services.taskchampion-sync-server = { enable = true; openFirewall = true; - dataDir = "/var/lib/taskchampion-sync-server"; + dataDir = dataDirectory; }; }; } diff --git a/pkgs/by-name/sh/sharkey/package.nix b/pkgs/by-name/sh/sharkey/package.nix new file mode 100644 index 0000000..22261fa --- /dev/null +++ b/pkgs/by-name/sh/sharkey/package.nix @@ -0,0 +1,4 @@ +{pkgsUnstable}: +# NOTE(@bpeetz): The package was written for unstable, and I don't see a reason to migrate +# it back, considering that 25.05 is right around the corner. <2025-04-22> +pkgsUnstable.callPackage ./unstable_package.nix {} diff --git a/pkgs/by-name/sh/sharkey/unstable_package.nix b/pkgs/by-name/sh/sharkey/unstable_package.nix new file mode 100644 index 0000000..3922ca0 --- /dev/null +++ b/pkgs/by-name/sh/sharkey/unstable_package.nix @@ -0,0 +1,176 @@ +# Source: https://github.com/sodiboo/system/blob/b63c7b27f49043e8701b3ff5e1441cd27d5a2fff/sharkey/package.nix +{ + lib, + stdenv, + fetchFromGitLab, + # Build time + makeWrapper, + copyDesktopItems, + jq, + moreutils, + cacert, + python3, + pkg-config, + # Run time + bash, + jemalloc, + ffmpeg-headless, + nodejs, + pnpm_9, + glib, + vips, + pixman, + pango, + cairo, +}: +stdenv.mkDerivation (finalAttrs: { + pname = "sharkey"; + version = "2025.2.2"; + + src = fetchFromGitLab { + owner = "TransFem-org"; + repo = "Sharkey"; + domain = "activitypub.software"; + rev = finalAttrs.version; + hash = "sha256-KVr4KLtJ22LEk94GuxeTk8/GcFs7oU/gkoVTvrgbYBg="; + fetchSubmodules = true; + }; + + pnpmDeps = stdenv.mkDerivation { + pname = "${finalAttrs.pname}-pnpm-deps"; + inherit (finalAttrs) src version; + + nativeBuildInputs = [ + jq + moreutils + pnpm_9 + cacert + ]; + + # https://github.com/NixOS/nixpkgs/blob/763e59ffedb5c25774387bf99bc725df5df82d10/pkgs/applications/misc/pot/default.nix#L56 + installPhase = '' + export HOME=$(mktemp --directory) + + pnpm config set store-dir $out + pnpm config set side-effects-cache false + pnpm install --force --frozen-lockfile --ignore-scripts + ''; + + fixupPhase = '' + rm --recursive --force $out/v3/tmp + for f in $(find $out -name "*.json"); do + sed --in-place --regexp-extended --expression='s/"checkedAt":[0-9]+,//g' "$f" + jq --sort-keys . "$f" | sponge "$f" + done + ''; + + dontBuild = true; + outputHashMode = "recursive"; + outputHash = "sha256-XWcDchvrYSJr0s/DMb8FIEK7MdE6aC2bAbrW88Ig4ug="; + }; + + nativeBuildInputs = [ + copyDesktopItems + pnpm_9 + nodejs + makeWrapper + python3 + pkg-config + ]; + + buildInputs = [ + glib + vips + + pixman + pango + cairo + ]; + + configurePhase = '' + runHook preConfigure + + export HOME=$(mktemp --directory) + export STORE_PATH=$(mktemp --directory) + + export npm_config_nodedir=${nodejs} + + cp --no-target-directory --recursive "$pnpmDeps" "$STORE_PATH" + chmod --recursive +w "$STORE_PATH" + + pnpm config set store-dir "$STORE_PATH" + pnpm install --offline --frozen-lockfile --ignore-scripts + + ( + cd node_modules/.pnpm/node_modules/v-code-diff + pnpm run postinstall + ) + ( + cd node_modules/.pnpm/node_modules/re2 + pnpm run rebuild + ) + ( + cd node_modules/.pnpm/node_modules/sharp + pnpm run install + ) + ( + cd node_modules/.pnpm/node_modules/canvas + pnpm run install + ) + + runHook postConfigure + ''; + + buildPhase = '' + runHook preBuild + + pnpm build + + runHook postBuild + ''; + + installPhase = let + libPath = lib.makeLibraryPath [ + jemalloc + ffmpeg-headless + stdenv.cc.cc.lib + ]; + + binPath = lib.makeBinPath [ + bash + pnpm_9 + nodejs + ]; + in + # bash + '' + runHook preInstall + + mkdir --parents $out/Sharkey + + ln --symbolic /var/lib/sharkey $out/Sharkey/files + ln --symbolic /run/sharkey $out/Sharkey/.config + cp --recursive * $out/Sharkey + + # We cannot `--set` the PATH, because sharkey runs shellscripts at start (and maybe + # at other times), which need these things. + makeWrapper ${lib.getExe pnpm_9} $out/bin/sharkey \ + --chdir $out/Sharkey \ + --prefix PATH : ${binPath} \ + --prefix LD_LIBRARY_PATH : ${libPath} + + runHook postInstall + ''; + + passthru = { + inherit (finalAttrs) pnpmDeps; + }; + + meta = { + description = "🌎 A Sharkish microblogging platform 🚀"; + homepage = "https://joinsharkey.org"; + license = lib.licenses.gpl3Only; + platforms = ["x86_64-linux" "aarch64-linux"]; + mainProgram = "sharkey"; + }; +}) diff --git a/pkgs/by-name/st/stalwart-mail-free/package.nix b/pkgs/by-name/st/stalwart-mail-free/package.nix index bb2c1db..19405c7 100644 --- a/pkgs/by-name/st/stalwart-mail-free/package.nix +++ b/pkgs/by-name/st/stalwart-mail-free/package.nix @@ -24,7 +24,7 @@ in } "stalwart-mail passthru"; useFetchCargoVendor = true; - cargoHash = "sha256-Qg01QXP/ImRCUw3aXcZbnM1hysHUwozCdQ7LecjUa0o="; + cargoHash = "sha256-FCRsmH9ZGYaf9ss3ECjZQkknIxAaDj9cedW32dWmBGY="; # The tests should check if this works. # And this shaves of around 50% of the build time. @@ -40,7 +40,7 @@ in (prev.postUnpack or "") + '' cp --recursive "${mail-send}" ./source/crates/mail-send - chmod -R +w "./source/crates/mail-send" + chmod --recursive +w "./source/crates/mail-send" ''; cargoPatches = diff --git a/tests/by-name/em/email-dns/nodes/mail_server.nix b/tests/by-name/em/email-dns/nodes/mail_server.nix index 89dbc4a..279d289 100644 --- a/tests/by-name/em/email-dns/nodes/mail_server.nix +++ b/tests/by-name/em/email-dns/nodes/mail_server.nix @@ -14,6 +14,7 @@ ++ [ ../../../../../modules ../../../../common/acme/client.nix + ../../../../common/dns/client.nix ]; environment.systemPackages = [ @@ -21,11 +22,6 @@ pkgs.openssl ]; - networking.nameservers = lib.mkForce [ - nodes.name_server.networking.primaryIPAddress - nodes.name_server.networking.primaryIPv6Address - ]; - age.identityPaths = ["${../../../../common/email/hostKey}"]; vhack = { diff --git a/tests/by-name/em/email-dns/nodes/name_server.nix b/tests/by-name/em/email-dns/nodes/name_server.nix index 48ce496..d9d3617 100644 --- a/tests/by-name/em/email-dns/nodes/name_server.nix +++ b/tests/by-name/em/email-dns/nodes/name_server.nix @@ -140,13 +140,9 @@ in { ++ [ ../../../../../modules ../../../../common/acme/client.nix + ../../../../common/dns/server.nix ]; - networking.nameservers = lib.mkForce [ - nodes.name_server.networking.primaryIPAddress - nodes.name_server.networking.primaryIPv6Address - ]; - services.nginx = { logError = "stderr debug"; virtualHosts = let @@ -175,145 +171,121 @@ in { nginx = { enable = true; }; - dns = { - enable = true; - openFirewall = true; - interfaces = [ - nodes.name_server.networking.primaryIPAddress - nodes.name_server.networking.primaryIPv6Address - ]; - - zones = let - stsZone = { - SOA = { - nameServer = "ns"; - adminEmail = "admin@server.com"; - serial = 2025012301; - }; + dns.zones = let + stsZone = { + SOA = { + nameServer = "ns"; + adminEmail = "admin@server.com"; + serial = 2025012301; + }; - useOrigin = false; + useOrigin = false; - A = [ - nodes.name_server.networking.primaryIPAddress - ]; - AAAA = [ - nodes.name_server.networking.primaryIPv6Address - ]; + A = [ + nodes.name_server.networking.primaryIPAddress + ]; + AAAA = [ + nodes.name_server.networking.primaryIPv6Address + ]; + }; + in { + "arpa" = { + SOA = { + nameServer = "ns"; + adminEmail = "admin@server.com"; + serial = 2025012301; }; - in { - "arpa" = { - SOA = { - nameServer = "ns"; - adminEmail = "admin@server.com"; - serial = 2025012301; - }; - useOrigin = false; + useOrigin = false; - PTR = [ - { - name = "acme.test"; - ip.v4 = nodes.acme.networking.primaryIPAddress; - } - { - name = "acme.test"; - ip.v6 = nodes.acme.networking.primaryIPv6Address; - } + PTR = [ + { + name = "acme.test"; + ip.v4 = nodes.acme.networking.primaryIPAddress; + } + { + name = "acme.test"; + ip.v6 = nodes.acme.networking.primaryIPv6Address; + } - { - name = "alice.com"; - ip.v4 = nodes.alice.networking.primaryIPAddress; - } - { - name = "alice.com"; - ip.v6 = nodes.alice.networking.primaryIPv6Address; - } + { + name = "alice.com"; + ip.v4 = nodes.alice.networking.primaryIPAddress; + } + { + name = "alice.com"; + ip.v6 = nodes.alice.networking.primaryIPv6Address; + } - { - name = "bob"; - ip.v4 = nodes.bob.networking.primaryIPAddress; - } - { - name = "bob"; - ip.v6 = nodes.bob.networking.primaryIPv6Address; - } + { + name = "bob"; + ip.v4 = nodes.bob.networking.primaryIPAddress; + } + { + name = "bob"; + ip.v6 = nodes.bob.networking.primaryIPv6Address; + } - { - name = "mail1.server.com"; - ip.v4 = nodes.mail1_server.networking.primaryIPAddress; - } - { - name = "mail1.server.com"; - ip.v6 = nodes.mail1_server.networking.primaryIPv6Address; - } + { + name = "mail1.server.com"; + ip.v4 = nodes.mail1_server.networking.primaryIPAddress; + } + { + name = "mail1.server.com"; + ip.v6 = nodes.mail1_server.networking.primaryIPv6Address; + } - { - name = "mail2.server.com"; - ip.v4 = nodes.mail2_server.networking.primaryIPAddress; - } - { - name = "mail2.server.com"; - ip.v6 = nodes.mail2_server.networking.primaryIPv6Address; - } + { + name = "mail2.server.com"; + ip.v4 = nodes.mail2_server.networking.primaryIPAddress; + } + { + name = "mail2.server.com"; + ip.v6 = nodes.mail2_server.networking.primaryIPv6Address; + } - { - name = "ns.server.com"; - ip.v4 = nodes.name_server.networking.primaryIPAddress; - } - { - name = "ns.server.com"; - ip.v6 = nodes.name_server.networking.primaryIPv6Address; - } - ]; - }; - - "alice.com" = mkZone "alice" nodes lib nodes.mail2_server.vhack.stalwart-mail; - "mta-sts.alice.com" = stsZone; - "bob.com" = mkZone "bob" nodes lib nodes.mail1_server.vhack.stalwart-mail; - "mta-sts.bob.com" = stsZone; - "mail1.server.com" = mkServerZone "mail1" nodes lib; - "mail2.server.com" = mkServerZone "mail2" nodes lib; - "ns.server.com" = { - SOA = { - nameServer = "ns"; - adminEmail = "admin@server.com"; - serial = 2025012301; - }; - useOrigin = false; + { + name = "ns.server.com"; + ip.v4 = nodes.name_server.networking.primaryIPAddress; + } + { + name = "ns.server.com"; + ip.v6 = nodes.name_server.networking.primaryIPv6Address; + } + ]; + }; - A = [ - nodes.name_server.networking.primaryIPAddress - ]; - AAAA = [ - nodes.name_server.networking.primaryIPv6Address - ]; + "alice.com" = mkZone "alice" nodes lib nodes.mail2_server.vhack.stalwart-mail; + "mta-sts.alice.com" = stsZone; + "bob.com" = mkZone "bob" nodes lib nodes.mail1_server.vhack.stalwart-mail; + "mta-sts.bob.com" = stsZone; + "mail1.server.com" = mkServerZone "mail1" nodes lib; + "mail2.server.com" = mkServerZone "mail2" nodes lib; + "ns.server.com" = { + SOA = { + nameServer = "ns"; + adminEmail = "admin@server.com"; + serial = 2025012301; }; - "acme.test" = { - SOA = { - nameServer = "ns"; - adminEmail = "admin@server.com"; - serial = 2025012301; - }; - useOrigin = false; + useOrigin = false; - A = [ - nodes.acme.networking.primaryIPAddress - ]; - AAAA = [ - nodes.acme.networking.primaryIPv6Address - ]; + A = [ + nodes.name_server.networking.primaryIPAddress + ]; + AAAA = [ + nodes.name_server.networking.primaryIPv6Address + ]; + }; + "server.com" = { + SOA = { + nameServer = "ns"; + adminEmail = "admin@server.com"; + serial = 2025012301; }; - "server.com" = { - SOA = { - nameServer = "ns"; - adminEmail = "admin@server.com"; - serial = 2025012301; - }; - useOrigin = false; - NS = [ - "ns.server.com." - ]; - }; + useOrigin = false; + NS = [ + "ns.server.com." + ]; }; }; }; diff --git a/tests/by-name/em/email-dns/nodes/user.nix b/tests/by-name/em/email-dns/nodes/user.nix index 55a4609..fba02ce 100644 --- a/tests/by-name/em/email-dns/nodes/user.nix +++ b/tests/by-name/em/email-dns/nodes/user.nix @@ -9,6 +9,7 @@ }: { imports = [ ../../../../common/acme/client.nix + ../../../../common/dns/client.nix ]; environment.systemPackages = [ @@ -20,11 +21,6 @@ pkgs.openssl ]; - networking.nameservers = lib.mkForce [ - nodes.name_server.networking.primaryIPAddress - nodes.name_server.networking.primaryIPv6Address - ]; - users.users."${user}" = {isNormalUser = true;}; systemd.tmpfiles.rules = [ diff --git a/tests/by-name/em/email-dns/test.nix b/tests/by-name/em/email-dns/test.nix index 0e4d9a0..f0399a5 100644 --- a/tests/by-name/em/email-dns/test.nix +++ b/tests/by-name/em/email-dns/test.nix @@ -31,9 +31,9 @@ in lib, ... }: { - imports = [../../../common/acme]; - networking.nameservers = lib.mkForce [ - nodes.name_server.networking.primaryIPAddress + imports = [ + ../../../common/acme/server.nix + ../../../common/dns/client.nix ]; }; @@ -89,7 +89,8 @@ in exit 1 } ''; - inherit (pkgs) lib; + + acme_scripts = import ../../../common/acme/scripts.nix {inherit pkgs;}; in /* python @@ -121,30 +122,7 @@ in with subtest("Add pebble ca key to all services"): for node in [name_server, mail1_server, mail2_server, alice, bob]: - node.succeed("${pkgs.writeShellScript "fetch-and-set-ca" '' - set -xe - - # Fetch the randomly generated ca certificate - curl https://acme.test:15000/roots/0 > /tmp/ca.crt - curl https://acme.test:15000/intermediates/0 >> /tmp/ca.crt - - # Append it to the various system stores - # The file paths are from <nixpgks>/modules/security/ca.nix - for cert_path in "ssl/certs/ca-certificates.crt" "ssl/certs/ca-bundle.crt" "pki/tls/certs/ca-bundle.crt"; do - cert_path="/etc/$cert_path" - - mv "$cert_path" "$cert_path.old" - cat "$cert_path.old" > "$cert_path" - cat /tmp/ca.crt >> "$cert_path" - done - - export NIX_SSL_CERT_FILE=/tmp/ca.crt - export SSL_CERT_FILE=/tmp/ca.crt - - # TODO - # # P11-Kit trust source. - # environment.etc."ssl/trust-source".source = "$${cacertPackage.p11kit}/etc/ssl/trust-source"; - ''}") + node.succeed("${acme_scripts.add_pebble_acme_ca}") with subtest("Both mailserver successfully started all services"): import json diff --git a/tests/by-name/em/email-http/nodes/name_server.nix b/tests/by-name/em/email-http/nodes/name_server.nix deleted file mode 100644 index a7e3ce9..0000000 --- a/tests/by-name/em/email-http/nodes/name_server.nix +++ /dev/null @@ -1,210 +0,0 @@ -{extraModules}: { - config, - lib, - nodes, - pkgs, - ... -}: let - keyAlgoToKeyType = keyAlgo: - if keyAlgo == "ed25519-sha256" - then "ed25519" - else if keyAlgo == "rsa-sha-256" || keyAlgo == "rsa-sha-1" - then "rsa" - else builtins.throw "Impossible"; - - mkZone = user: nodes: lib: cfg: { - SOA = { - nameServer = "ns.server.com"; - adminEmail = "${user}@${user}.com"; - serial = 2024012301; - }; - - MX = [ - { - preference = 10; - exchange = "${cfg.fqdn}."; - } - ]; - - # https://www.rfc-editor.org/rfc/rfc8461.html#section-3.1 - # Also see the policy in the hmtl part. - MTA-STS = [ - { - id = "20250228Z"; - } - ]; - - # https://www.rfc-editor.org/rfc/rfc7208.html - # https://en.wikipedia.org/wiki/Sender_Policy_Framework - TXT = [ - (builtins.concatStringsSep " " - [ - "v=spf1" # The version. - "+mx" # Allow mail from this domain MX record. - "-all" # Reject all other emails if the previous mechanism did not match. - ]) - ]; - - # https://www.rfc-editor.org/rfc/rfc6376.html#section-3.6.1 - # https://www.rfc-editor.org/rfc/rfc6376.html#section-7.5 - DKIM = [ - { - selector = "mail"; - k = keyAlgoToKeyType cfg.security.dkimKeys."${user}.com".keyAlgorithm; - p = cfg.security.dkimKeys."${user}.com".dkimPublicKey; - s = ["email"]; - t = ["s"]; - } - ]; - - # https://www.rfc-editor.org/rfc/rfc7489.html#section-6.3 - DMARC = [ - { - adkim = "strict"; - aspf = "strict"; - fo = ["0" "1" "d" "s"]; - p = "quarantine"; - rua = cfg.admin; - ruf = [cfg.admin]; - } - ]; - - A = [ - nodes.${user}.networking.primaryIPAddress - ]; - AAAA = [ - nodes.${user}.networking.primaryIPv6Address - ]; - }; - mkServerZone = serverName: nodes: lib: let - cfg = nodes."${serverName}_server".vhack.stalwart-mail; - in { - SOA = { - nameServer = "ns.server.com"; - adminEmail = "admin@server.com"; - serial = 2024012301; - }; - MX = [ - { - preference = 10; - exchange = "${serverName}.server.com."; - } - ]; - - # https://www.rfc-editor.org/rfc/rfc6376.html#section-3.6.1 - # https://www.rfc-editor.org/rfc/rfc6376.html#section-7.5 - DKIM = [ - { - selector = "mail"; - k = keyAlgoToKeyType cfg.security.dkimKeys."${serverName}.server.com".keyAlgorithm; - p = cfg.security.dkimKeys."${serverName}.server.com".dkimPublicKey; - s = ["email"]; - t = ["s"]; - } - ]; - - # https://www.rfc-editor.org/rfc/rfc7489.html#section-6.3 - DMARC = [ - { - adkim = "strict"; - aspf = "strict"; - fo = ["0" "1" "d" "s"]; - p = "reject"; - rua = cfg.admin; - ruf = [cfg.admin]; - } - ]; - - # https://www.rfc-editor.org/rfc/rfc7208.html - # NOTE(@bpeetz): This server might not be directly sending mail, but it is still required for - # the SMTP EHLO check. <2025-02-25> - TXT = [ - (builtins.concatStringsSep " " - [ - "v=spf1" # The version. - "+mx" # Allow mail from this domain MX record. - "-all" # Reject all other emails if the previous mechanism did not match. - ]) - ]; - - A = [ - nodes."${serverName}_server".networking.primaryIPAddress - ]; - AAAA = [ - nodes."${serverName}_server".networking.primaryIPv6Address - ]; - }; -in { - imports = - extraModules - ++ [ - ../../../../../modules - ../../../../common/acme/client.nix - ]; - - networking.nameservers = lib.mkForce [ - nodes.name_server.networking.primaryIPAddress - nodes.name_server.networking.primaryIPv6Address - ]; - - vhack = { - nginx = { - enable = true; - }; - dns = { - enable = true; - openFirewall = true; - interfaces = [ - nodes.name_server.networking.primaryIPAddress - nodes.name_server.networking.primaryIPv6Address - ]; - - zones = { - "bob.com" = mkZone "bob" nodes lib nodes.mail_server.vhack.stalwart-mail; - "mail.server.com" = mkServerZone "mail" nodes lib; - "ns.server.com" = { - SOA = { - nameServer = "ns"; - adminEmail = "admin@server.com"; - serial = 2025012301; - }; - useOrigin = false; - - A = [ - nodes.name_server.networking.primaryIPAddress - ]; - AAAA = [ - nodes.name_server.networking.primaryIPv6Address - ]; - }; - "acme.test" = { - SOA = { - nameServer = "ns"; - adminEmail = "admin@server.com"; - serial = 2025012301; - }; - useOrigin = false; - - A = [ - nodes.acme.networking.primaryIPAddress - ]; - AAAA = [ - nodes.acme.networking.primaryIPv6Address - ]; - }; - "server.com" = { - SOA = { - nameServer = "ns"; - adminEmail = "admin@server.com"; - serial = 2025012301; - }; - - useOrigin = false; - NS = [ - "ns.server.com." - ]; - }; - }; - }; - }; -} diff --git a/tests/by-name/em/email-http/test.nix b/tests/by-name/em/email-http/test.nix index 2c7921d..f508b9f 100644 --- a/tests/by-name/em/email-http/test.nix +++ b/tests/by-name/em/email-http/test.nix @@ -31,13 +31,38 @@ in lib, ... }: { - imports = [../../../common/acme]; - networking.nameservers = lib.mkForce [ - nodes.name_server.networking.primaryIPAddress + imports = [ + ../../../common/acme/server.nix + ../../../common/dns/client.nix ]; }; - name_server = import ./nodes/name_server.nix {inherit extraModules;}; + name_server = {nodes, ...}: { + imports = + extraModules + ++ [ + ../../../common/acme/client.nix + ../../../common/dns/server.nix + ]; + + vhack.dns.zones = { + "mail.server.com" = { + SOA = { + nameServer = "ns"; + adminEmail = "admin@server.com"; + serial = 2025012301; + }; + useOrigin = false; + + A = [ + nodes.mail_server.networking.primaryIPAddress + ]; + AAAA = [ + nodes.mail_server.networking.primaryIPv6Address + ]; + }; + }; + }; mail_server = mkMailServer "mail" null; @@ -45,66 +70,46 @@ in }; # TODO(@bpeetz): This test should also test the http JMAP features of stalwart-mail. <2025-04-12> - testScript = _: - /* - python - */ - '' - # Start dependencies for the other services - acme.start() - acme.wait_for_unit("pebble.service") - name_server.start() - name_server.wait_for_unit("nsd.service") - - # Start the actual testing machines - start_all() - - mail_server.wait_for_unit("stalwart-mail.service") - mail_server.wait_for_open_port(993) # imap - mail_server.wait_for_open_port(465) # smtp - - bob.wait_for_unit("multi-user.target") - - with subtest("Add pebble ca key to all services"): - for node in [name_server, mail_server, bob]: - node.succeed("${pkgs.writeShellScript "fetch-and-set-ca" '' - set -xe - - # Fetch the randomly generated ca certificate - curl https://acme.test:15000/roots/0 > /tmp/ca.crt - curl https://acme.test:15000/intermediates/0 >> /tmp/ca.crt - - # Append it to the various system stores - # The file paths are from <nixpgks>/modules/security/ca.nix - for cert_path in "ssl/certs/ca-certificates.crt" "ssl/certs/ca-bundle.crt" "pki/tls/certs/ca-bundle.crt"; do - cert_path="/etc/$cert_path" - - mv "$cert_path" "$cert_path.old" - cat "$cert_path.old" > "$cert_path" - cat /tmp/ca.crt >> "$cert_path" - done - - export NIX_SSL_CERT_FILE=/tmp/ca.crt - export SSL_CERT_FILE=/tmp/ca.crt - - # TODO - # # P11-Kit trust source. - # environment.etc."ssl/trust-source".source = "$${cacertPackage.p11kit}/etc/ssl/trust-source"; - ''}") - - with subtest("The mailserver successfully started all services"): - import json - def all_services_running(host): - (status, output) = host.systemctl("list-units --state=failed --plain --no-pager --output=json") - host_failed = json.loads(output) - assert len(host_failed) == 0, f"Expected zero failing services, but found: {json.dumps(host_failed, indent=4)}" - all_services_running(mail_server) - - with subtest("Bob can use the self-service interface"): - bob.succeed("${pkgs.writeShellScript "check-self-service" '' - curl mail.server.com --location --output /home/bob/output.html; - ''}") - - bob.copy_from_vm("/home/bob", "") - ''; + testScript = _: let + acme_scripts = import ../../../common/acme/scripts.nix {inherit pkgs;}; + in + /* + python + */ + '' + # Start dependencies for the other services + acme.start() + acme.wait_for_unit("pebble.service") + name_server.start() + name_server.wait_for_unit("nsd.service") + + # Start the actual testing machines + start_all() + + mail_server.wait_for_unit("stalwart-mail.service") + mail_server.wait_for_open_port(993) # imap + mail_server.wait_for_open_port(465) # smtp + + bob.wait_for_unit("multi-user.target") + + with subtest("Add pebble ca key to all services"): + for node in [name_server, mail_server, bob]: + node.wait_for_unit("network-online.target") + node.succeed("${acme_scripts.add_pebble_acme_ca}") + + with subtest("The mailserver successfully started all services"): + import json + def all_services_running(host): + (status, output) = host.systemctl("list-units --state=failed --plain --no-pager --output=json") + host_failed = json.loads(output) + assert len(host_failed) == 0, f"Expected zero failing services, but found: {json.dumps(host_failed, indent=4)}" + all_services_running(mail_server) + + with subtest("Bob can use the self-service interface"): + bob.succeed("${pkgs.writeShellScript "check-self-service" '' + curl mail.server.com --location --output /home/bob/output.html; + ''}") + + bob.copy_from_vm("/home/bob", "") + ''; } diff --git a/tests/by-name/sh/sharkey/test.nix b/tests/by-name/sh/sharkey/test.nix new file mode 100644 index 0000000..40efe17 --- /dev/null +++ b/tests/by-name/sh/sharkey/test.nix @@ -0,0 +1,118 @@ +{ + nixos-lib, + pkgsUnstable, + nixpkgs-unstable, + vhackPackages, + pkgs, + extraModules, + nixLib, + ... +}: +nixos-lib.runTest { + hostPkgs = pkgs; # the Nixpkgs package set used outside the VMs + + name = "sharkey"; + + node = { + specialArgs = {inherit pkgsUnstable extraModules vhackPackages nixpkgs-unstable nixLib;}; + + # Use the nixpkgs as constructed by the `nixpkgs.*` options + pkgs = null; + }; + + nodes = { + acme = {...}: { + imports = [ + ../../../common/acme/server.nix + ../../../common/dns/client.nix + ]; + }; + name_server = {nodes, ...}: { + imports = + extraModules + ++ [ + ../../../common/acme/client.nix + ../../../common/dns/server.nix + ]; + + vhack.dns.zones = { + "sharkey.server" = { + SOA = { + nameServer = "ns"; + adminEmail = "admin@server.com"; + serial = 2025012301; + }; + useOrigin = false; + + A = [ + nodes.server.networking.primaryIPAddress + ]; + AAAA = [ + nodes.server.networking.primaryIPv6Address + ]; + }; + }; + }; + + server = {config, ...}: { + imports = + extraModules + ++ [ + ../../../../modules + ../../../common/acme/client.nix + ../../../common/dns/client.nix + ]; + + vhack = { + persist.enable = true; + nginx.enable = true; + sharkey = { + enable = true; + fqdn = "sharkey.server"; + }; + }; + }; + + client = {...}: { + imports = [ + ../../../common/acme/client.nix + ../../../common/dns/client.nix + ]; + }; + }; + + testScript = {nodes, ...}: let + acme_scripts = import ../../../common/acme/scripts.nix {inherit pkgs;}; + in + /* + python + */ + '' + # Start dependencies for the other services + acme.start() + acme.wait_for_unit("pebble.service") + name_server.start() + name_server.wait_for_unit("nsd.service") + + # Start the actual testing machines + start_all() + + + with subtest("Add pebble ca key to all services"): + for node in [name_server, server, client]: + node.wait_for_unit("network-online.target") + node.succeed("${acme_scripts.add_pebble_acme_ca}") + + server.wait_for_unit("sharkey.service") + + with subtest("All services running"): + import json + def all_services_running(host): + (status, output) = host.systemctl("list-units --state=failed --plain --no-pager --output=json") + host_failed = json.loads(output) + assert len(host_failed) == 0, f"Expected zero failing services, but found: {json.dumps(host_failed, indent=4)}" + all_services_running(server) + + client.wait_until_succeeds("curl --silent https://sharkey.server | grep 'Thank you for using Sharkey!'") + ''; +} diff --git a/tests/common/acme/scripts.nix b/tests/common/acme/scripts.nix new file mode 100644 index 0000000..2228823 --- /dev/null +++ b/tests/common/acme/scripts.nix @@ -0,0 +1,30 @@ +{pkgs}: +/* +* Extra functions useful for the test script. +*/ +{ + add_pebble_acme_ca = pkgs.writeShellScript "fetch-and-set-ca" '' + set -xe + + # Fetch the randomly generated ca certificate + curl https://acme.test:15000/roots/0 > /tmp/ca.crt + curl https://acme.test:15000/intermediates/0 >> /tmp/ca.crt + + # Append it to the various system stores + # The file paths are from <nixpgks>/modules/security/ca.nix + for cert_path in "ssl/certs/ca-certificates.crt" "ssl/certs/ca-bundle.crt" "pki/tls/certs/ca-bundle.crt"; do + cert_path="/etc/$cert_path" + + mv "$cert_path" "$cert_path.old" + cat "$cert_path.old" > "$cert_path" + cat /tmp/ca.crt >> "$cert_path" + done + + export NIX_SSL_CERT_FILE=/tmp/ca.crt + export SSL_CERT_FILE=/tmp/ca.crt + + # TODO + # # P11-Kit trust source. + # environment.etc."ssl/trust-source".source = "$${cacertPackage.p11kit}/etc/ssl/trust-source"; + ''; +} diff --git a/tests/common/acme/default.nix b/tests/common/acme/server.nix index 236ba6a..997c944 100644 --- a/tests/common/acme/default.nix +++ b/tests/common/acme/server.nix @@ -1,28 +1,5 @@ -# The certificate for the ACME service is exported as: -# -# config.test-support.acme.caCert -# -# This value can be used inside the configuration of other test nodes to inject -# the test certificate into security.pki.certificateFiles or into package -# overlays. -# -# { -# acme = { nodes, lib, ... }: { -# imports = [ ./common/acme/server ]; -# networking.nameservers = lib.mkForce [ -# nodes.mydnsresolver.networking.primaryIPAddress -# ]; -# }; -# -# dnsmyresolver = ...; -# } -# -# Keep in mind, that currently only _one_ resolver is supported, if you have -# more than one resolver in networking.nameservers only the first one will be -# used. -# -# Also make sure that whenever you use a resolver from a different test node -# that it has to be started _before_ the ACME service. +# Add this node as acme server. +# This also needs a DNS server. { config, pkgs, diff --git a/tests/common/dns/client.nix b/tests/common/dns/client.nix new file mode 100644 index 0000000..52f3267 --- /dev/null +++ b/tests/common/dns/client.nix @@ -0,0 +1,10 @@ +{ + lib, + nodes, + ... +}: { + networking.nameservers = lib.mkForce [ + nodes.name_server.networking.primaryIPAddress + nodes.name_server.networking.primaryIPv6Address + ]; +} diff --git a/tests/common/dns/server.nix b/tests/common/dns/server.nix new file mode 100644 index 0000000..0c8d72c --- /dev/null +++ b/tests/common/dns/server.nix @@ -0,0 +1,43 @@ +{ + lib, + nodes, + ... +}: { + imports = [ + ../../../modules + ]; + + networking.nameservers = lib.mkForce [ + nodes.name_server.networking.primaryIPAddress + nodes.name_server.networking.primaryIPv6Address + ]; + + vhack = { + dns = { + enable = true; + openFirewall = true; + interfaces = [ + nodes.name_server.networking.primaryIPAddress + nodes.name_server.networking.primaryIPv6Address + ]; + + zones = { + "acme.test" = { + SOA = { + nameServer = "ns"; + adminEmail = "admin@server.com"; + serial = 2025012301; + }; + useOrigin = false; + + A = [ + nodes.acme.networking.primaryIPAddress + ]; + AAAA = [ + nodes.acme.networking.primaryIPv6Address + ]; + }; + }; + }; + }; +} diff --git a/update.sh b/update.sh index c43b80b..e22f4ea 100755 --- a/update.sh +++ b/update.sh @@ -3,12 +3,13 @@ __update_sh_run() { __update_sh_command="$1" shift 1 - printf "\033[35;1m> \033[0m\033[35;1m%s\033[0m\n" "Running '$(basename "$__update_sh_command")' .." + printf "\033[35;1m> \033[0m\033[35;1m%s\033[0m\n" "Running '$(basename "$__update_sh_command") $*' .." "$__update_sh_command" "$@" unset __update_sh_command } +__update_sh_run nix flake update __update_sh_run ./pkgs/update_pkgs.sh "$@" # vim: ft=sh diff --git a/zones/vhack.eu/zone.nix b/zones/vhack.eu/zone.nix index d647174..696d1df 100644 --- a/zones/vhack.eu/zone.nix +++ b/zones/vhack.eu/zone.nix @@ -38,7 +38,7 @@ in { adminEmail = "dns-admin@foss-syndicate.org"; # NOTE(@bpeetz): ALWAYS change the serial number, when you change something in the # zone file! <2025-04-01> - serial = mkSerial 2025 04 11 01; + serial = mkSerial 2025 04 23 01; }; useOrigin = false; @@ -157,6 +157,7 @@ in { redlib.CNAME = ["server2.vhack.eu."]; nextcloud.CNAME = ["server2.vhack.eu."]; + sharkey.CNAME = ["server2.vhack.eu."]; mastodon.CNAME = ["server3.vhack.eu."]; matrix.CNAME = ["server3.vhack.eu."]; |
