Skip to content

Commit 6fdd010

Browse files
bors[bot]LassulusMic92
authored
Merge #34
34: nixos-remote.sh: generate temporary ssh-key r=Mic92 a=Mic92 Co-authored-by: lassulus <[email protected]> Co-authored-by: Jörg Thalheim <[email protected]>
2 parents f33a138 + a67d3ac commit 6fdd010

File tree

7 files changed

+76
-57
lines changed

7 files changed

+76
-57
lines changed

README.md

Lines changed: 0 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -42,8 +42,6 @@ Options:
4242
* -s, --store-paths
4343
set the store paths to the disko-script and nixos-system directly
4444
if this is give, flake is not needed
45-
* --no-ssh-copy
46-
skip copying ssh-keys to target system
4745
* --no-reboot
4846
do not reboot after installation, allowing further customization of the target installation.
4947
* --kexec url

docs/cli.md

Lines changed: 0 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -10,8 +10,6 @@ Options:
1010
* -s, --store-paths
1111
set the store paths to the disko-script and nixos-system directly
1212
if this is give, flake is not needed
13-
* --no-ssh-copy
14-
skip copying ssh-keys to target system
1513
* --kexec url
1614
use another kexec tarball to bootstrap NixOS
1715
* --debug

flake.lock

Lines changed: 9 additions & 9 deletions
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

src/nixos-remote.sh

Lines changed: 49 additions & 28 deletions
Original file line numberDiff line numberDiff line change
@@ -11,8 +11,6 @@ Options:
1111
* -s, --store-paths
1212
set the store paths to the disko-script and nixos-system directly
1313
if this is give, flake is not needed
14-
* --no-ssh-copy
15-
skip copying ssh-keys to target system
1614
* --no-reboot
1715
do not reboot after installation, allowing further customization of the target installation.
1816
* --kexec url
@@ -49,9 +47,10 @@ nix_options=(
4947
"--no-write-lock-file"
5048
)
5149
substitute_on_destination=y
52-
nix_copy_options=()
5350

5451
declare -A disk_encryption_keys
52+
declare -a nix_copy_options
53+
declare -a ssh_copy_id_args
5554

5655
while [[ $# -gt 0 ]]; do
5756
case "$1" in
@@ -76,9 +75,6 @@ while [[ $# -gt 0 ]]; do
7675
kexec_url=$2
7776
shift
7877
;;
79-
--no-ssh-copy-id)
80-
no_ssh_copy=y
81-
;;
8278
--debug)
8379
enable_debug="-x"
8480
print_build_logs=y
@@ -126,14 +122,6 @@ while [[ $# -gt 0 ]]; do
126122
shift
127123
done
128124

129-
# ssh wrapper
130-
timeout_ssh_() {
131-
timeout 10 ssh -o UserKnownHostsFile=/dev/null -o StrictHostKeyChecking=no "$ssh_connection" "$@"
132-
}
133-
ssh_() {
134-
ssh -T -o UserKnownHostsFile=/dev/null -o StrictHostKeyChecking=no "$ssh_connection" "$@"
135-
}
136-
137125
if [[ ${print_build_logs-n} == "y" ]]; then
138126
nix_options+=("-L")
139127
fi
@@ -142,8 +130,16 @@ if [[ ${substitute_on_destination-n} == "y" ]]; then
142130
nix_copy_options+=("--substitute-on-destination")
143131
fi
144132

133+
# ssh wrapper
134+
timeout_ssh_() {
135+
timeout 10 ssh -i "$ssh_key_dir"/nixos-remote -o UserKnownHostsFile=/dev/null -o StrictHostKeyChecking=no "$ssh_connection" "$@"
136+
}
137+
ssh_() {
138+
ssh -T -i "$ssh_key_dir"/nixos-remote -o UserKnownHostsFile=/dev/null -o StrictHostKeyChecking=no "$ssh_connection" "$@"
139+
}
140+
145141
nix_copy() {
146-
NIX_SSHOPTS='-o UserKnownHostsFile=/dev/null -o StrictHostKeyChecking=no' nix copy \
142+
NIX_SSHOPTS="-o UserKnownHostsFile=/dev/null -o StrictHostKeyChecking=no -i $ssh_key_dir/nixos-remote" nix copy \
147143
"${nix_options[@]}" \
148144
"${nix_copy_options[@]}" \
149145
"$@"
@@ -160,29 +156,58 @@ if [[ -z ${ssh_connection-} ]]; then
160156
abort "ssh-host must be set"
161157
fi
162158

159+
# we generate a temporary ssh keypair that we can use during nixos-remote
160+
ssh_key_dir=$(mktemp -d)
161+
trap 'rm -rf "$ssh_key_dir"' EXIT
162+
mkdir -p "$ssh_key_dir"
163+
ssh-keygen -t ed25519 -f "$ssh_key_dir"/nixos-remote -P "" -C "nixos-remote" >/dev/null
164+
163165
# parse flake nixos-install style syntax, get the system attr
164166
if [[ -n ${flake-} ]]; then
165167
if [[ $flake =~ ^(.*)\#([^\#\"]*)$ ]]; then
166168
flake="${BASH_REMATCH[1]}"
167169
flakeAttr="${BASH_REMATCH[2]}"
168170
fi
169171
if [[ -z ${flakeAttr-} ]]; then
170-
echo "Please specify the name of the NixOS configuration to be installed, as a URI fragment in the flake-uri."
171-
echo 'For example, to use the output nixosConfigurations.foo from the flake.nix, append "#foo" to the flake-uri.'
172+
echo "Please specify the name of the NixOS configuration to be installed, as a URI fragment in the flake-uri." >&2
173+
echo 'For example, to use the output nixosConfigurations.foo from the flake.nix, append "#foo" to the flake-uri.' >&2
172174
exit 1
173175
fi
174176
disko_script=$(nix_build "${flake}#nixosConfigurations.${flakeAttr}.config.system.build.disko")
175177
nixos_system=$(nix_build "${flake}#nixosConfigurations.${flakeAttr}.config.system.build.toplevel")
176178
elif [[ -n ${disko_script-} ]] && [[ -n ${nixos_system-} ]]; then
177179
if [[ ! -e ${disko_script} ]] || [[ ! -e ${nixos_system} ]]; then
178-
echo "${disko_script} and ${nixos_system} must be existing store-paths"
179-
exit 1
180+
abort "${disko_script} and ${nixos_system} must be existing store-paths"
180181
fi
181182
:
182183
else
183184
abort "flake must be set"
184185
fi
185186

187+
if [[ -n ${SSH_PRIVATE_KEY-} ]]; then
188+
sshPrivateKeyFile=$(mktemp)
189+
trap 'rm "$sshPrivateKeyFile"' EXIT
190+
(
191+
umask 077
192+
printf '%s' "$SSH_PRIVATE_KEY" >"$sshPrivateKeyFile"
193+
)
194+
unset SSH_AUTH_SOCK # don't use system agent if key was supplied
195+
ssh_copy_id_args+=(-o "IdentityFile=${sshPrivateKeyFile}")
196+
ssh_copy_id_args+=(-f)
197+
fi
198+
199+
until
200+
ssh-copy-id \
201+
-i "$ssh_key_dir"/nixos-remote.pub \
202+
-o ConnectTimeout=10 \
203+
-o UserKnownHostsFile=/dev/null \
204+
-o StrictHostKeyChecking=no \
205+
"${ssh_copy_id_args[@]}" \
206+
"$ssh_connection"
207+
do
208+
sleep 3
209+
done
210+
186211
import_facts() {
187212
local facts filtered_facts
188213
if ! facts=$(
@@ -205,7 +230,7 @@ has_curl=\$(has curl)
205230
FACTS
206231
SSH
207232
); then
208-
return 1
233+
exit 1
209234
fi
210235
filtered_facts=$(echo "$facts" | grep -E '^(has|is)_[a-z0-9_]+=\S+')
211236
if [[ -z $filtered_facts ]]; then
@@ -216,10 +241,7 @@ SSH
216241
export $(echo "$filtered_facts" | xargs)
217242
}
218243

219-
# wait for machine to become reachable (possibly forever)
220-
until import_facts; do
221-
sleep 5
222-
done
244+
import_facts
223245

224246
if [[ ${has_tar-n} == "n" ]]; then
225247
abort "no tar command found, but required to unpack kexec tarball"
@@ -236,10 +258,6 @@ if [[ ${is_arch-n} != "x86_64" ]] && [[ $kexec_url == "$default_kexec_url" ]]; t
236258
abort "The default kexec image only support x86_64 cpus. Checkout https://github.com/numtide/nixos-remote/#using-your-own-kexec-image for more information."
237259
fi
238260

239-
if [[ ${is_kexec-n} != "y" ]] && [[ ${no_ssh_copy-n} != "y" ]]; then
240-
ssh-copy-id -o ConnectTimeout=10 -o UserKnownHostsFile=/dev/null -o StrictHostKeyChecking=no "$ssh_connection"
241-
fi
242-
243261
if [[ ${is_kexec-n} == "n" ]] && [[ ${is_installer-n} == "n" ]]; then
244262
ssh_ <<SSH
245263
set -efu ${enable_debug}
@@ -279,6 +297,9 @@ nix_copy --to "ssh://$ssh_connection" "$disko_script"
279297
ssh_ "$disko_script"
280298

281299
if [[ ${stop_after_disko-n} == "y" ]]; then
300+
# Should we also do this for `--no-reboot`?
301+
echo "WARNING: leaving temporary ssh key at '$ssh_key_dir/nixos-remote' to login to the machine" >&2
302+
trap - EXIT
282303
exit 0
283304
fi
284305

tests/from-nixos-with-sudo.nix

Lines changed: 12 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -2,14 +2,24 @@
22
name = "from-nixos-with-sudo";
33
nodes = {
44
installer = ./modules/installer.nix;
5-
installed = ./modules/installed.nix;
5+
installed = {
6+
services.openssh.enable = true;
7+
virtualisation.memorySize = 4096;
8+
9+
users.users.nixos = {
10+
isNormalUser = true;
11+
openssh.authorizedKeys.keyFiles = [ ./modules/ssh-keys/ssh.pub ];
12+
extraGroups = [ "wheel" ];
13+
};
14+
security.sudo.enable = true;
15+
security.sudo.wheelNeedsPassword = false;
16+
};
617
};
718
testScript = ''
819
start_all()
920
installer.succeed("echo super-secret > /tmp/disk-1.key")
1021
output = installer.succeed("""
1122
nixos-remote \
12-
--no-ssh-copy-id \
1323
--debug \
1424
--kexec /etc/nixos-remote/kexec-installer \
1525
--stop-after-disko \

tests/from-nixos.nix

Lines changed: 6 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -2,7 +2,12 @@
22
name = "from-nixos";
33
nodes = {
44
installer = ./modules/installer.nix;
5-
installed = ./modules/installed.nix;
5+
installed = {
6+
services.openssh.enable = true;
7+
virtualisation.memorySize = 4096;
8+
9+
users.users.root.openssh.authorizedKeys.keyFiles = [ ./modules/ssh-keys/ssh.pub ];
10+
};
611
};
712
testScript = ''
813
def create_test_machine(oldmachine=None, args={}): # taken from <nixpkgs/nixos/tests/installer.nix>
@@ -19,7 +24,6 @@
1924
installer.succeed("echo value > /tmp/extra-files/var/lib/secrets/key")
2025
installer.succeed("""
2126
nixos-remote \
22-
--no-ssh-copy-id \
2327
--debug \
2428
--kexec /etc/nixos-remote/kexec-installer \
2529
--extra-files /tmp/extra-files \

tests/modules/installed.nix

Lines changed: 0 additions & 12 deletions
This file was deleted.

0 commit comments

Comments
 (0)