1 { config, lib, pkgs, ... }:
6 cfg = config.services.rmfakecloud;
7 serviceDataDir = "/var/lib/rmfakecloud";
11 services.rmfakecloud = {
12 enable = mkEnableOption (lib.mdDoc "rmfakecloud remarkable self-hosted cloud");
16 default = pkgs.rmfakecloud;
17 defaultText = literalExpression "pkgs.rmfakecloud";
18 description = lib.mdDoc ''
19 rmfakecloud package to use.
21 The default does not include the web user interface.
25 storageUrl = mkOption {
27 example = "https://local.appspot.com";
28 description = lib.mdDoc ''
29 URL used by the tablet to access the rmfakecloud service.
36 description = lib.mdDoc ''
37 Listening port number.
42 type = types.enum [ "info" "debug" "warn" "error" ];
44 description = lib.mdDoc ''
49 extraSettings = mkOption {
50 type = with types; attrsOf str;
52 example = { DATADIR = "/custom/path/for/rmfakecloud/data"; };
53 description = lib.mdDoc ''
54 Extra settings in the form of a set of key-value pairs.
55 For tokens and secrets, use `environmentFile` instead.
57 Available settings are listed on
58 https://ddvk.github.io/rmfakecloud/install/configuration/.
62 environmentFile = mkOption {
63 type = with types; nullOr path;
65 example = "/etc/secrets/rmfakecloud.env";
66 description = lib.mdDoc ''
67 Path to an environment file loaded for the rmfakecloud service.
69 This can be used to securely store tokens and secrets outside of the
70 world-readable Nix store. Since this file is read by systemd, it may
71 have permission 0400 and be owned by root.
77 config = mkIf cfg.enable {
78 systemd.services.rmfakecloud = {
79 description = "rmfakecloud remarkable self-hosted cloud";
82 STORAGE_URL = cfg.storageUrl;
83 PORT = toString cfg.port;
84 LOGLEVEL = cfg.logLevel;
85 } // cfg.extraSettings;
88 # Generate the secret key used to sign client session tokens.
89 # Replacing it invalidates the previously established sessions.
90 if [ -z "$JWT_SECRET_KEY" ] && [ ! -f jwt_secret_key ]; then
91 (umask 077; touch jwt_secret_key)
92 cat /dev/urandom | tr -cd '[:alnum:]' | head -c 48 >> jwt_secret_key
97 if [ -z "$JWT_SECRET_KEY" ]; then
98 export JWT_SECRET_KEY="$(cat jwt_secret_key)"
101 ${cfg.package}/bin/rmfakecloud
104 wantedBy = [ "multi-user.target" ];
105 wants = [ "network-online.target" ];
106 after = [ "network-online.target" ];
113 mkIf (cfg.environmentFile != null) cfg.environmentFile;
115 AmbientCapabilities =
116 mkIf (cfg.port < 1024) [ "CAP_NET_BIND_SERVICE" ];
119 PrivateDevices = true;
121 ProtectKernelTunables = true;
122 ProtectKernelModules = true;
123 ProtectControlGroups = true;
124 CapabilityBoundingSet = [ "" ];
125 DevicePolicy = "closed";
126 LockPersonality = true;
127 MemoryDenyWriteExecute = true;
129 ProtectHostname = true;
130 ProtectKernelLogs = true;
131 ProtectProc = "invisible";
134 RestrictAddressFamilies = [ "AF_INET" "AF_INET6" ];
135 RestrictNamespaces = true;
136 RestrictRealtime = true;
137 RestrictSUIDSGID = true;
138 SystemCallArchitectures = "native";
139 WorkingDirectory = serviceDataDir;
140 StateDirectory = baseNameOf serviceDataDir;
146 meta.maintainers = with maintainers; [ pacien ];