From ba7502bb616095586a9b68dddbc3195346b22e42 Mon Sep 17 00:00:00 2001
From: Jean-Paul Calderone <exarkun@twistedmatrix.com>
Date: Wed, 10 Jun 2020 15:03:44 -0400
Subject: [PATCH] Somewhat configurable accounts on issuer and storage servers

---
 nixos/modules/ssh.nix                     | 24 ++++++++++----
 nixos/modules/tests/private-storage.nix   | 19 ++++++++++++
 nixos/modules/tests/probeuser_ed25519     | 38 +++++++++++++++++++++++
 nixos/modules/tests/probeuser_ed25519.pub |  1 +
 4 files changed, 76 insertions(+), 6 deletions(-)
 create mode 100644 nixos/modules/tests/probeuser_ed25519
 create mode 100644 nixos/modules/tests/probeuser_ed25519.pub

diff --git a/nixos/modules/ssh.nix b/nixos/modules/ssh.nix
index fc028fd5..ca9b3154 100644
--- a/nixos/modules/ssh.nix
+++ b/nixos/modules/ssh.nix
@@ -5,10 +5,18 @@
   ...
 }: {
   options = {
+    services.private-storage.sshUsers = lib.mkOption {
+      type = lib.types.attrsOf lib.types.str;
+      example = lib.literalExample { root = "ssh-ed25519 AAA..."; };
+      description = ''
+        Users to configure on the issuer server and the storage servers and
+        the SSH public keys to use to authenticate them.
+      '';
+    };
   };
   config =
   let
-    cfg = config."private-storage".config;
+     cfg = config.services."private-storage";
   in {
     # An attempt at a properly secure SSH configuration.  This is informed by
     # personal experience as well as various web resources:
@@ -29,13 +37,17 @@
         # password-based authentication at all.
         PermitEmptyPasswords no
 
-        # Don't allow authentication as random system users.
-        AllowUsers root
+        # Only allow authentication as one of the configured users, not random
+        # other (often system-managed) users.
+        AllowUsers ${builtins.concatStringsSep " " (builtins.attrNames cfg.sshUsers)}
       '';
     };
 
-    users.users.root.openssh.authorizedKeys.keys = [
-      "ssh-ed25519 AAAAC3NzaC1lZDI1NTE5AAAAIN4GenAY/YLGuf1WoMXyyVa3S9i4JLQ0AG+pt7nvcLlQ exarkun@baryon"
-    ];
+    users.users =
+      let makeUserConfig = username: sshPublicKey: {
+        isNormalUser = true;
+        openssh.authorizedKeys.keys = [ sshPublicKey ];
+      };
+      in builtins.mapAttrs makeUserConfig cfg.sshUsers;
   };
 }
diff --git a/nixos/modules/tests/private-storage.nix b/nixos/modules/tests/private-storage.nix
index 08a3e0d5..2bdd25a8 100644
--- a/nixos/modules/tests/private-storage.nix
+++ b/nixos/modules/tests/private-storage.nix
@@ -2,6 +2,19 @@ let
   pkgs = import <nixpkgs> { };
   pspkgs = import ../pspkgs.nix { inherit pkgs; };
 
+  sshPrivateKey = ./probeuser_ed25519;
+  sshPublicKey = ./probeuser_ed25519.pub;
+  sshUsers = {
+    probeuser = (builtins.readFile sshPublicKey);
+  };
+  # Generate a command which can be used with runOnNode to ssh to the given
+  # host.
+  ssh = hostname: [
+    "cp" sshPrivateKey "/tmp/ssh_key" ";"
+    "chmod" "0400" "/tmp/ssh_key" ";"
+    "ssh" "-oStrictHostKeyChecking=no" "-i" "/tmp/ssh_key" "probeuser@${hostname}" ":"
+  ];
+
   # Separate helper programs so we can write as little perl inside a string
   # inside a nix expression as possible.
   run-introducer = ./run-introducer.py;
@@ -108,6 +121,8 @@ import <nixpkgs/nixos/tests/make-test.nix> {
           introducerFURL = introducerFURL;
           issuerRootURL = issuerURL;
           inherit ristrettoSigningKeyPath;
+          inherit sshUsers;
+
         };
       } // networkConfig;
 
@@ -117,6 +132,8 @@ import <nixpkgs/nixos/tests/make-test.nix> {
     { imports =
       [ ../issuer.nix
       ];
+      services.private-storage.sshUsers = sshUsers;
+
       services.private-storage-issuer = {
         enable = true;
         domain = "issuer";
@@ -169,7 +186,9 @@ import <nixpkgs/nixos/tests/make-test.nix> {
       # doesn't prove it is so but if it fails it's a pretty good indication
       # it isn't so.
       $storage->waitForOpenPort(22);
+      ${runOnNode "issuer" (ssh "storage")}
       $issuer->waitForOpenPort(22);
+      ${runOnNode "storage" (ssh "issuer")}
 
       # Set up a Tahoe-LAFS introducer.
       $introducer->copyFileFromHost(
diff --git a/nixos/modules/tests/probeuser_ed25519 b/nixos/modules/tests/probeuser_ed25519
new file mode 100644
index 00000000..09c734d0
--- /dev/null
+++ b/nixos/modules/tests/probeuser_ed25519
@@ -0,0 +1,38 @@
+-----BEGIN OPENSSH PRIVATE KEY-----
+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
+-----END OPENSSH PRIVATE KEY-----
diff --git a/nixos/modules/tests/probeuser_ed25519.pub b/nixos/modules/tests/probeuser_ed25519.pub
new file mode 100644
index 00000000..e9ba1bbd
--- /dev/null
+++ b/nixos/modules/tests/probeuser_ed25519.pub
@@ -0,0 +1 @@
+ssh-rsa AAAAB3NzaC1yc2EAAAADAQABAAABgQD1GpUUiM4j1bDCGaWu3cch6ibh+Apx13oNby8VHblrKdcYgvAgUUn0FbUiGsQB1JR3C3B0MMoHWdXcPG9itLi23L4F1sqXxlurJ+UfLzuw2e3Tbsum8Fr0BF5mnt41dnibIhF6DuVCdB47JVZd8XvLY4LMFRvTz0g77YB2gUEOsOu+cmkNdRGIGmPygD0U693gHOR9G5KpM44NOuNdKKWENJTQ3mSSjlufLTu1YOwj6hskVUYAvM7mu3zojxP5utZ68DAD3kM9ADCsgrtyX0714f/n1xUFjB1Ay2AZ+OqxIds/ZirFE6OQr0EVICA2JvYhfInQ6TNk3Swh/b3aVSSQN8qml8nwj7PVZzfv8TwuRbQHkpLFqXv1x+1TGokhPWx95UOjfWvlR0rxX2SQC2wkU2omsRPIwNl5ugkXnHxhZcKBAz75Ozbg/e8FzA4nBy9qb4Fya1mFrLb7SOsEVWoDwyTDzM0RWIZpX/OUpJ+3dl61jKPmWT8ms2odKXlP2Pk= probeuser
-- 
GitLab