at 23.11-beta 6.2 kB view raw
1import ./make-test-python.nix ({ pkgs, ... }: 2 3let inherit (import ./ssh-keys.nix pkgs) 4 snakeOilPrivateKey snakeOilPublicKey; 5in { 6 name = "openssh"; 7 meta = with pkgs.lib.maintainers; { 8 maintainers = [ aszlig eelco ]; 9 }; 10 11 nodes = { 12 13 server = 14 { ... }: 15 16 { 17 services.openssh.enable = true; 18 security.pam.services.sshd.limits = 19 [ { domain = "*"; item = "memlock"; type = "-"; value = 1024; } ]; 20 users.users.root.openssh.authorizedKeys.keys = [ 21 snakeOilPublicKey 22 ]; 23 }; 24 25 server-lazy = 26 { ... }: 27 28 { 29 services.openssh = { enable = true; startWhenNeeded = true; }; 30 security.pam.services.sshd.limits = 31 [ { domain = "*"; item = "memlock"; type = "-"; value = 1024; } ]; 32 users.users.root.openssh.authorizedKeys.keys = [ 33 snakeOilPublicKey 34 ]; 35 }; 36 37 server-localhost-only = 38 { ... }: 39 40 { 41 services.openssh = { 42 enable = true; listenAddresses = [ { addr = "127.0.0.1"; port = 22; } ]; 43 }; 44 }; 45 46 server-localhost-only-lazy = 47 { ... }: 48 49 { 50 services.openssh = { 51 enable = true; startWhenNeeded = true; listenAddresses = [ { addr = "127.0.0.1"; port = 22; } ]; 52 }; 53 }; 54 55 server-match-rule = 56 { ... }: 57 58 { 59 services.openssh = { 60 enable = true; listenAddresses = [ { addr = "127.0.0.1"; port = 22; } { addr = "[::]"; port = 22; } ]; 61 extraConfig = '' 62 # Combined test for two (predictable) Match criterias 63 Match LocalAddress 127.0.0.1 LocalPort 22 64 PermitRootLogin yes 65 66 # Separate tests for Match criterias 67 Match User root 68 PermitRootLogin yes 69 Match Group root 70 PermitRootLogin yes 71 Match Host nohost.example 72 PermitRootLogin yes 73 Match LocalAddress 127.0.0.1 74 PermitRootLogin yes 75 Match LocalPort 22 76 PermitRootLogin yes 77 Match RDomain nohost.example 78 PermitRootLogin yes 79 Match Address 127.0.0.1 80 PermitRootLogin yes 81 ''; 82 }; 83 }; 84 85 server_allowedusers = 86 { ... }: 87 88 { 89 services.openssh = { enable = true; settings.AllowUsers = [ "alice" "bob" ]; }; 90 users.groups = { alice = { }; bob = { }; carol = { }; }; 91 users.users = { 92 alice = { isNormalUser = true; group = "alice"; openssh.authorizedKeys.keys = [ snakeOilPublicKey ]; }; 93 bob = { isNormalUser = true; group = "bob"; openssh.authorizedKeys.keys = [ snakeOilPublicKey ]; }; 94 carol = { isNormalUser = true; group = "carol"; openssh.authorizedKeys.keys = [ snakeOilPublicKey ]; }; 95 }; 96 }; 97 98 client = 99 { ... }: { }; 100 101 }; 102 103 testScript = '' 104 start_all() 105 106 server.wait_for_unit("sshd", timeout=30) 107 server_localhost_only.wait_for_unit("sshd", timeout=30) 108 server_match_rule.wait_for_unit("sshd", timeout=30) 109 110 server_lazy.wait_for_unit("sshd.socket", timeout=30) 111 server_localhost_only_lazy.wait_for_unit("sshd.socket", timeout=30) 112 113 with subtest("manual-authkey"): 114 client.succeed("mkdir -m 700 /root/.ssh") 115 client.succeed( 116 '${pkgs.openssh}/bin/ssh-keygen -t ed25519 -f /root/.ssh/id_ed25519 -N ""' 117 ) 118 public_key = client.succeed( 119 "${pkgs.openssh}/bin/ssh-keygen -y -f /root/.ssh/id_ed25519" 120 ) 121 public_key = public_key.strip() 122 client.succeed("chmod 600 /root/.ssh/id_ed25519") 123 124 server.succeed("mkdir -m 700 /root/.ssh") 125 server.succeed("echo '{}' > /root/.ssh/authorized_keys".format(public_key)) 126 server_lazy.succeed("mkdir -m 700 /root/.ssh") 127 server_lazy.succeed("echo '{}' > /root/.ssh/authorized_keys".format(public_key)) 128 129 client.wait_for_unit("network.target") 130 client.succeed( 131 "ssh -o UserKnownHostsFile=/dev/null -o StrictHostKeyChecking=no server 'echo hello world' >&2", 132 timeout=30 133 ) 134 client.succeed( 135 "ssh -o UserKnownHostsFile=/dev/null -o StrictHostKeyChecking=no server 'ulimit -l' | grep 1024", 136 timeout=30 137 ) 138 139 client.succeed( 140 "ssh -o UserKnownHostsFile=/dev/null -o StrictHostKeyChecking=no server-lazy 'echo hello world' >&2", 141 timeout=30 142 ) 143 client.succeed( 144 "ssh -o UserKnownHostsFile=/dev/null -o StrictHostKeyChecking=no server-lazy 'ulimit -l' | grep 1024", 145 timeout=30 146 ) 147 148 with subtest("configured-authkey"): 149 client.succeed( 150 "cat ${snakeOilPrivateKey} > privkey.snakeoil" 151 ) 152 client.succeed("chmod 600 privkey.snakeoil") 153 client.succeed( 154 "ssh -o UserKnownHostsFile=/dev/null -o StrictHostKeyChecking=no -i privkey.snakeoil server true", 155 timeout=30 156 ) 157 client.succeed( 158 "ssh -o UserKnownHostsFile=/dev/null -o StrictHostKeyChecking=no -i privkey.snakeoil server-lazy true", 159 timeout=30 160 ) 161 162 with subtest("localhost-only"): 163 server_localhost_only.succeed("ss -nlt | grep '127.0.0.1:22'") 164 server_localhost_only_lazy.succeed("ss -nlt | grep '127.0.0.1:22'") 165 166 with subtest("match-rules"): 167 server_match_rule.succeed("ss -nlt | grep '127.0.0.1:22'") 168 169 with subtest("allowed-users"): 170 client.succeed( 171 "cat ${snakeOilPrivateKey} > privkey.snakeoil" 172 ) 173 client.succeed("chmod 600 privkey.snakeoil") 174 client.succeed( 175 "ssh -o UserKnownHostsFile=/dev/null -o StrictHostKeyChecking=no -i privkey.snakeoil alice@server_allowedusers true", 176 timeout=30 177 ) 178 client.succeed( 179 "ssh -o UserKnownHostsFile=/dev/null -o StrictHostKeyChecking=no -i privkey.snakeoil bob@server_allowedusers true", 180 timeout=30 181 ) 182 client.fail( 183 "ssh -o UserKnownHostsFile=/dev/null -o StrictHostKeyChecking=no -i privkey.snakeoil carol@server_allowedusers true", 184 timeout=30 185 ) 186 ''; 187})