about summary refs log tree commit diff
path: root/nixos
diff options
context:
space:
mode:
authorgithub-actions[bot] <41898282+github-actions[bot]@users.noreply.github.com>2021-02-15 12:20:16 +0000
committerGitHub <noreply@github.com>2021-02-15 12:20:16 +0000
commita1d9d57051448515395a9173710cc30fa47dd89f (patch)
tree8e56af3512752d5740ee0b1406a32b9c05a1b13a /nixos
parente1580db42f851d696fb59e3a43bd2b70c13c9392 (diff)
parentcd518a718b8987d60d2870851bb12bdd3882c51a (diff)
Merge staging-next into staging
Diffstat (limited to 'nixos')
-rw-r--r--nixos/modules/config/users-groups.nix2
-rw-r--r--nixos/modules/services/web-apps/mastodon.nix106
2 files changed, 66 insertions, 42 deletions
diff --git a/nixos/modules/config/users-groups.nix b/nixos/modules/config/users-groups.nix
index 5b3e9a8ceb7f4..1a530b9f01359 100644
--- a/nixos/modules/config/users-groups.nix
+++ b/nixos/modules/config/users-groups.nix
@@ -568,7 +568,7 @@ in {
     # Install all the user shells
     environment.systemPackages = systemShells;
 
-    environment.etc = (mapAttrs' (name: { packages, ... }: {
+    environment.etc = (mapAttrs' (_: { packages, name, ... }: {
       name = "profiles/per-user/${name}";
       value.source = pkgs.buildEnv {
         name = "user-environment";
diff --git a/nixos/modules/services/web-apps/mastodon.nix b/nixos/modules/services/web-apps/mastodon.nix
index 92b1be963bf7f..37e5f7719b7b5 100644
--- a/nixos/modules/services/web-apps/mastodon.nix
+++ b/nixos/modules/services/web-apps/mastodon.nix
@@ -25,10 +25,28 @@ let
     ES_ENABLED = if (cfg.elasticsearch.host != null) then "true" else "false";
     ES_HOST = cfg.elasticsearch.host;
     ES_PORT = toString(cfg.elasticsearch.port);
+
+    TRUSTED_PROXY_IP = cfg.trustedProxy;
   }
   // (if cfg.smtp.authenticate then { SMTP_LOGIN  = cfg.smtp.user; } else {})
   // cfg.extraConfig;
 
+  cfgService = {
+    # User and group
+    User = cfg.user;
+    Group = cfg.group;
+    # State directory and mode
+    StateDirectory = "mastodon";
+    StateDirectoryMode = "0750";
+    # Logs directory and mode
+    LogsDirectory = "mastodon";
+    LogsDirectoryMode = "0750";
+    # Access write directories
+    UMask = "0027";
+    # Sandboxing
+    PrivateTmp = true;
+  };
+
   envFile = pkgs.writeText "mastodon.env" (lib.concatMapStrings (s: s + "\n") (
     (lib.concatLists (lib.mapAttrsToList (name: value:
       if value != null then [
@@ -179,6 +197,26 @@ in {
         type = lib.types.str;
       };
 
+      trustedProxy = lib.mkOption {
+        description = ''
+          You need to set it to the IP from which your reverse proxy sends requests to Mastodon's web process,
+          otherwise Mastodon will record the reverse proxy's own IP as the IP of all requests, which would be
+          bad because IP addresses are used for important rate limits and security functions.
+        '';
+        type = lib.types.str;
+        default = "127.0.0.1";
+      };
+
+      enableUnixSocket = lib.mkOption {
+        description = ''
+          Instead of binding to an IP address like 127.0.0.1, you may bind to a Unix socket. This variable
+          is process-specific, e.g. you need different values for every process, and it works for both web (Puma)
+          processes and streaming API (Node.js) processes.
+        '';
+        type = lib.types.bool;
+        default = true;
+      };
+
       redis = {
         createLocally = lib.mkOption {
           description = "Configure local Redis server for Mastodon.";
@@ -370,19 +408,16 @@ in {
       environment = env;
       serviceConfig = {
         Type = "oneshot";
-        User = cfg.user;
-        Group = cfg.group;
         WorkingDirectory = cfg.package;
-        LogsDirectory = "mastodon";
-        StateDirectory = "mastodon";
-      };
+      } // cfgService;
+
       after = [ "network.target" ];
       wantedBy = [ "multi-user.target" ];
     };
 
     systemd.services.mastodon-init-db = lib.mkIf cfg.automaticMigrations {
       script = ''
-        if [ `psql mastodon -c \
+        if [ `psql ${cfg.database.name} -c \
                 "select count(*) from pg_class c \
                 join pg_namespace s on s.oid = c.relnamespace \
                 where s.nspname not in ('pg_catalog', 'pg_toast', 'information_schema') \
@@ -397,14 +432,9 @@ in {
       environment = env;
       serviceConfig = {
         Type = "oneshot";
-        User = cfg.user;
-        Group = cfg.group;
         EnvironmentFile = "/var/lib/mastodon/.secrets_env";
-        PrivateTmp = true;
-        LogsDirectory = "mastodon";
-        StateDirectory = "mastodon";
         WorkingDirectory = cfg.package;
-      };
+      } // cfgService;
       after = [ "mastodon-init-dirs.service" "network.target" ] ++ (if databaseActuallyCreateLocally then [ "postgresql.service" ] else []);
       wantedBy = [ "multi-user.target" ];
     };
@@ -415,21 +445,20 @@ in {
         ++ (if cfg.automaticMigrations then [ "mastodon-init-db.service" ] else [ "mastodon-init-dirs.service" ]);
       description = "Mastodon streaming";
       wantedBy = [ "multi-user.target" ];
-      environment = env // {
-        PORT = toString(cfg.streamingPort);
-      };
+      environment = env // (if cfg.enableUnixSocket
+        then { SOCKET = "/run/mastodon-streaming/streaming.socket"; }
+        else { PORT = toString(cfg.streamingPort); }
+      );
       serviceConfig = {
         ExecStart = "${pkgs.nodejs-slim}/bin/node streaming";
         Restart = "always";
         RestartSec = 20;
-        User = cfg.user;
-        Group = cfg.group;
-        WorkingDirectory = cfg.package;
         EnvironmentFile = "/var/lib/mastodon/.secrets_env";
-        PrivateTmp = true;
-        LogsDirectory = "mastodon";
-        StateDirectory = "mastodon";
-      };
+        WorkingDirectory = cfg.package;
+        # Runtime directory and mode
+        RuntimeDirectory = "mastodon-streaming";
+        RuntimeDirectoryMode = "0750";
+      } // cfgService;
     };
 
     systemd.services.mastodon-web = {
@@ -438,21 +467,20 @@ in {
         ++ (if cfg.automaticMigrations then [ "mastodon-init-db.service" ] else [ "mastodon-init-dirs.service" ]);
       description = "Mastodon web";
       wantedBy = [ "multi-user.target" ];
-      environment = env // {
-        PORT = toString(cfg.webPort);
-      };
+      environment = env // (if cfg.enableUnixSocket
+        then { SOCKET = "/run/mastodon-web/web.socket"; }
+        else { PORT = toString(cfg.webPort); }
+      );
       serviceConfig = {
         ExecStart = "${cfg.package}/bin/puma -C config/puma.rb";
         Restart = "always";
         RestartSec = 20;
-        User = cfg.user;
-        Group = cfg.group;
-        WorkingDirectory = cfg.package;
         EnvironmentFile = "/var/lib/mastodon/.secrets_env";
-        PrivateTmp = true;
-        LogsDirectory = "mastodon";
-        StateDirectory = "mastodon";
-      };
+        WorkingDirectory = cfg.package;
+        # Runtime directory and mode
+        RuntimeDirectory = "mastodon-web";
+        RuntimeDirectoryMode = "0750";
+      } // cfgService;
       path = with pkgs; [ file imagemagick ffmpeg ];
     };
 
@@ -469,14 +497,9 @@ in {
         ExecStart = "${cfg.package}/bin/sidekiq -c 25 -r ${cfg.package}";
         Restart = "always";
         RestartSec = 20;
-        User = cfg.user;
-        Group = cfg.group;
-        WorkingDirectory = cfg.package;
         EnvironmentFile = "/var/lib/mastodon/.secrets_env";
-        PrivateTmp = true;
-        LogsDirectory = "mastodon";
-        StateDirectory = "mastodon";
-      };
+        WorkingDirectory = cfg.package;
+      } // cfgService;
       path = with pkgs; [ file imagemagick ffmpeg ];
     };
 
@@ -495,12 +518,12 @@ in {
         };
 
         locations."@proxy" = {
-          proxyPass = "http://127.0.0.1:${toString(cfg.webPort)}";
+          proxyPass = (if cfg.enableUnixSocket then "http://unix:/run/mastodon-web/web.socket" else "http://127.0.0.1:${toString(cfg.webPort)}");
           proxyWebsockets = true;
         };
 
         locations."/api/v1/streaming/" = {
-          proxyPass = "http://127.0.0.1:${toString(cfg.streamingPort)}/";
+          proxyPass = (if cfg.enableUnixSocket then "http://unix:/run/mastodon-streaming/streaming.socket" else "http://127.0.0.1:${toString(cfg.streamingPort)}/");
           proxyWebsockets = true;
         };
       };
@@ -532,6 +555,7 @@ in {
         };
       })
       (lib.attrsets.setAttrByPath [ cfg.user "packages" ] [ cfg.package mastodonEnv ])
+      (lib.mkIf cfg.configureNginx {${config.services.nginx.user}.extraGroups = [ cfg.user ];})
     ];
 
     users.groups.mastodon = lib.mkIf (cfg.group == "mastodon") { };