1{ pkgs, ... }:
2let
3 inherit (import ./ssh-keys.nix pkgs) snakeOilEd25519PrivateKey snakeOilEd25519PublicKey;
4 username = "nix-remote-builder";
5in
6{
7 name = "rush";
8 meta = { inherit (pkgs.rush.meta) maintainers platforms; };
9
10 nodes = {
11 client =
12 { ... }:
13 {
14 nix.settings.extra-experimental-features = [ "nix-command" ];
15 };
16
17 server =
18 { config, ... }:
19 {
20 nix.settings.trusted-users = [ "${username}" ];
21
22 programs.rush = {
23 enable = true;
24 global = "debug 1";
25
26 rules = {
27 daemon = ''
28 match $# == 2
29 match $0 == "nix-daemon"
30 match $1 == "--stdio"
31 match $user == "${username}"
32 chdir "${config.nix.package}/bin"
33 '';
34
35 whoami = ''
36 match $# == 1
37 match $0 == "whoami"
38 match $user == "${username}"
39 chdir "${dirOf config.environment.usrbinenv}"
40 '';
41 };
42 };
43
44 services.openssh = {
45 enable = true;
46
47 extraConfig = ''
48 Match User ${username}
49 AllowAgentForwarding no
50 AllowTcpForwarding no
51 PermitTTY no
52 PermitTunnel no
53 X11Forwarding no
54 Match All
55 '';
56 };
57
58 users = {
59 groups."${username}" = { };
60
61 users."${username}" = {
62 inherit (config.programs.rush) shell;
63 group = "${username}";
64 isSystemUser = true;
65 openssh.authorizedKeys.keys = [ snakeOilEd25519PublicKey ];
66 };
67 };
68 };
69 };
70
71 testScript = ''
72 start_all()
73
74 client.succeed("mkdir -m 700 /root/.ssh")
75 client.succeed("cat '${snakeOilEd25519PrivateKey}' | tee /root/.ssh/id_ed25519")
76 client.succeed("chmod 600 /root/.ssh/id_ed25519")
77
78 server.wait_for_unit("sshd")
79
80 client.succeed("ssh-keyscan -H server | tee -a /root/.ssh/known_hosts")
81
82 client.succeed("ssh ${username}@server -- whoami")
83 client.succeed("nix store info --store 'ssh-ng://${username}@server'")
84
85 client.fail("ssh ${username}@server -- date")
86 client.fail("nix store info --store 'ssh://${username}@server'")
87 '';
88}