1 { config, lib, pkgs, ... }:
6 cfg = config.services.rmfakecloud;
7 serviceDataDir = "/var/lib/rmfakecloud";
11 services.rmfakecloud = {
12 enable = mkEnableOption "rmfakecloud remarkable self-hosted cloud";
14 package = mkPackageOption pkgs "rmfakecloud" {
17 The default does not include the web user interface.
22 storageUrl = mkOption {
24 example = "https://local.appspot.com";
26 URL used by the tablet to access the rmfakecloud service.
34 Listening port number.
39 type = types.enum [ "info" "debug" "warn" "error" ];
46 extraSettings = mkOption {
47 type = with types; attrsOf str;
49 example = { DATADIR = "/custom/path/for/rmfakecloud/data"; };
51 Extra settings in the form of a set of key-value pairs.
52 For tokens and secrets, use `environmentFile` instead.
54 Available settings are listed on
55 https://ddvk.github.io/rmfakecloud/install/configuration/.
59 environmentFile = mkOption {
60 type = with types; nullOr path;
62 example = "/etc/secrets/rmfakecloud.env";
64 Path to an environment file loaded for the rmfakecloud service.
66 This can be used to securely store tokens and secrets outside of the
67 world-readable Nix store. Since this file is read by systemd, it may
68 have permission 0400 and be owned by root.
74 config = mkIf cfg.enable {
75 systemd.services.rmfakecloud = {
76 description = "rmfakecloud remarkable self-hosted cloud";
79 STORAGE_URL = cfg.storageUrl;
80 PORT = toString cfg.port;
81 LOGLEVEL = cfg.logLevel;
82 } // cfg.extraSettings;
85 # Generate the secret key used to sign client session tokens.
86 # Replacing it invalidates the previously established sessions.
87 if [ -z "$JWT_SECRET_KEY" ] && [ ! -f jwt_secret_key ]; then
88 (umask 077; touch jwt_secret_key)
89 cat /dev/urandom | tr -cd '[:alnum:]' | head -c 48 >> jwt_secret_key
94 if [ -z "$JWT_SECRET_KEY" ]; then
95 export JWT_SECRET_KEY="$(cat jwt_secret_key)"
98 ${cfg.package}/bin/rmfakecloud
101 wantedBy = [ "multi-user.target" ];
102 wants = [ "network-online.target" ];
103 after = [ "network-online.target" ];
110 mkIf (cfg.environmentFile != null) cfg.environmentFile;
112 AmbientCapabilities =
113 mkIf (cfg.port < 1024) [ "CAP_NET_BIND_SERVICE" ];
116 PrivateDevices = true;
118 ProtectKernelTunables = true;
119 ProtectKernelModules = true;
120 ProtectControlGroups = true;
121 CapabilityBoundingSet = [ "" ];
122 DevicePolicy = "closed";
123 LockPersonality = true;
124 MemoryDenyWriteExecute = true;
126 ProtectHostname = true;
127 ProtectKernelLogs = true;
128 ProtectProc = "invisible";
131 RestrictAddressFamilies = [ "AF_INET" "AF_INET6" ];
132 RestrictNamespaces = true;
133 RestrictRealtime = true;
134 RestrictSUIDSGID = true;
135 SystemCallArchitectures = "native";
136 WorkingDirectory = serviceDataDir;
137 StateDirectory = baseNameOf serviceDataDir;
143 meta.maintainers = with maintainers; [ pacien ];