diff options
Diffstat (limited to 'modules/by-name/sh')
-rw-r--r-- | modules/by-name/sh/sharkey/module.nix | 297 |
1 files changed, 297 insertions, 0 deletions
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; + }; + }; + }; +} |