nixos: nix.sshServe: Support ssh-ng.

+74 -22
+17 -7
nixos/modules/services/misc/nix-ssh-serve.nix
··· 1 1 { config, lib, pkgs, ... }: 2 2 3 3 with lib; 4 - 5 - { 4 + let cfg = config.nix.sshServe; 5 + command = 6 + if cfg.protocol == "ssh" 7 + then "nix-store --serve" 8 + else "nix-daemon --stdio"; 9 + in { 6 10 options = { 7 11 8 12 nix.sshServe = { ··· 10 14 enable = mkOption { 11 15 type = types.bool; 12 16 default = false; 13 - description = "Whether to enable serving the Nix store as a binary cache via SSH."; 17 + description = "Whether to enable serving the Nix store as a remote store via SSH."; 14 18 }; 15 19 16 20 keys = mkOption { ··· 20 24 description = "A list of SSH public keys allowed to access the binary cache via SSH."; 21 25 }; 22 26 27 + protocol = mkOption { 28 + type = types.enum [ "ssh" "ssh-ng" ]; 29 + default = "ssh"; 30 + description = "The specific Nix-over-SSH protocol to use."; 31 + }; 32 + 23 33 }; 24 34 25 35 }; 26 36 27 - config = mkIf config.nix.sshServe.enable { 37 + config = mkIf cfg.enable { 28 38 29 39 users.extraUsers.nix-ssh = { 30 - description = "Nix SSH substituter user"; 40 + description = "Nix SSH store user"; 31 41 uid = config.ids.uids.nix-ssh; 32 42 useDefaultShell = true; 33 43 }; ··· 41 51 PermitTTY no 42 52 PermitTunnel no 43 53 X11Forwarding no 44 - ForceCommand ${config.nix.package.out}/bin/nix-store --serve 54 + ForceCommand ${config.nix.package.out}/bin/${command} 45 55 Match All 46 56 ''; 47 57 48 - users.extraUsers.nix-ssh.openssh.authorizedKeys.keys = config.nix.sshServe.keys; 58 + users.extraUsers.nix-ssh.openssh.authorizedKeys.keys = cfg.keys; 49 59 50 60 }; 51 61 }
+1
nixos/release.nix
··· 319 319 tests.nfs4 = callTest tests/nfs.nix { version = 4; }; 320 320 tests.nginx = callTest tests/nginx.nix { }; 321 321 tests.nghttpx = callTest tests/nghttpx.nix { }; 322 + tests.nix-ssh-serve = callTest tests/nix-ssh-serve.nix { }; 322 323 tests.novacomd = callTestOnTheseSystems ["x86_64-linux"] tests/novacomd.nix { }; 323 324 tests.leaps = callTest tests/leaps.nix { }; 324 325 tests.nsd = callTest tests/nsd.nix {};
+39
nixos/tests/nix-ssh-serve.nix
··· 1 + import ./make-test.nix ({ pkgs, lib, ... }: 2 + let inherit (import ./ssh-keys.nix pkgs) 3 + snakeOilPrivateKey snakeOilPublicKey; 4 + ssh-config = builtins.toFile "ssh.conf" '' 5 + UserKnownHostsFile=/dev/null 6 + StrictHostKeyChecking=no 7 + ''; 8 + in 9 + { name = "nix-ssh-serve"; 10 + meta.maintainers = [ lib.maintainers.shlevy ]; 11 + nodes = 12 + { server.nix.sshServe = 13 + { enable = true; 14 + keys = [ snakeOilPublicKey ]; 15 + protocol = "ssh-ng"; 16 + }; 17 + server.nix.package = pkgs.nixUnstable; 18 + client.nix.package = pkgs.nixUnstable; 19 + }; 20 + testScript = '' 21 + startAll; 22 + 23 + $client->succeed("mkdir -m 700 /root/.ssh"); 24 + $client->copyFileFromHost("${ssh-config}", "/root/.ssh/config"); 25 + $client->succeed("cat ${snakeOilPrivateKey} > /root/.ssh/id_ecdsa"); 26 + $client->succeed("chmod 600 /root/.ssh/id_ecdsa"); 27 + 28 + $client->succeed("nix-store --add /etc/machine-id > mach-id-path"); 29 + 30 + $server->waitForUnit("sshd"); 31 + 32 + $client->fail("diff /root/other-store\$(cat mach-id-path) /etc/machine-id"); 33 + # Currently due to shared store this is a noop :( 34 + $client->succeed("nix copy --to ssh-ng://nix-ssh\@server \$(cat mach-id-path)"); 35 + $client->succeed("nix-store --realise \$(cat mach-id-path) --store /root/other-store --substituters ssh-ng://nix-ssh\@server"); 36 + $client->succeed("diff /root/other-store\$(cat mach-id-path) /etc/machine-id"); 37 + ''; 38 + } 39 + )
+2 -15
nixos/tests/openssh.nix
··· 1 1 import ./make-test.nix ({ pkgs, ... }: 2 2 3 - let 4 - snakeOilPrivateKey = pkgs.writeText "privkey.snakeoil" '' 5 - -----BEGIN EC PRIVATE KEY----- 6 - MHcCAQEEIHQf/khLvYrQ8IOika5yqtWvI0oquHlpRLTZiJy5dRJmoAoGCCqGSM49 7 - AwEHoUQDQgAEKF0DYGbBwbj06tA3fd/+yP44cvmwmHBWXZCKbS+RQlAKvLXMWkpN 8 - r1lwMyJZoSGgBHoUahoYjTh9/sJL7XLJtA== 9 - -----END EC PRIVATE KEY----- 10 - ''; 11 - 12 - snakeOilPublicKey = pkgs.lib.concatStrings [ 13 - "ecdsa-sha2-nistp256 AAAAE2VjZHNhLXNoYTItbmlzdHAyNTYAAAAIbmlzdHA" 14 - "yNTYAAABBBChdA2BmwcG49OrQN33f/sj+OHL5sJhwVl2Qim0vkUJQCry1zFpKTa" 15 - "9ZcDMiWaEhoAR6FGoaGI04ff7CS+1yybQ= sakeoil" 16 - ]; 17 - 3 + let inherit (import ./ssh-keys.nix pkgs) 4 + snakeOilPrivateKey snakeOilPublicKey; 18 5 in { 19 6 name = "openssh"; 20 7 meta = with pkgs.stdenv.lib.maintainers; {
+15
nixos/tests/ssh-keys.nix
··· 1 + pkgs: 2 + { snakeOilPrivateKey = pkgs.writeText "privkey.snakeoil" '' 3 + -----BEGIN EC PRIVATE KEY----- 4 + MHcCAQEEIHQf/khLvYrQ8IOika5yqtWvI0oquHlpRLTZiJy5dRJmoAoGCCqGSM49 5 + AwEHoUQDQgAEKF0DYGbBwbj06tA3fd/+yP44cvmwmHBWXZCKbS+RQlAKvLXMWkpN 6 + r1lwMyJZoSGgBHoUahoYjTh9/sJL7XLJtA== 7 + -----END EC PRIVATE KEY----- 8 + ''; 9 + 10 + snakeOilPublicKey = pkgs.lib.concatStrings [ 11 + "ecdsa-sha2-nistp256 AAAAE2VjZHNhLXNoYTItbmlzdHAyNTYAAAAIbmlzdHA" 12 + "yNTYAAABBBChdA2BmwcG49OrQN33f/sj+OHL5sJhwVl2Qim0vkUJQCry1zFpKTa" 13 + "9ZcDMiWaEhoAR6FGoaGI04ff7CS+1yybQ= sakeoil" 14 + ]; 15 + }