|
1 | 1 | #!/bin/bash |
2 | 2 | echo "----------------------------------------------" |
3 | | -echo "Running Phala Cloud Pre-Launch Script v0.0.18" |
| 3 | +echo "Running Phala Cloud Pre-Launch Script v0.0.19" |
4 | 4 | echo "----------------------------------------------" |
5 | 5 | set -e |
6 | 6 |
|
@@ -53,6 +53,40 @@ check_docker_login() { |
53 | 53 | fi |
54 | 54 | } |
55 | 55 |
|
| 56 | +# Function: print the SHA256 fingerprint of every authorized key |
| 57 | +# |
| 58 | +# Output matches `ssh-keygen -lf` and the fingerprints GitHub and Phala Cloud |
| 59 | +# display, so an operator can match the boot log against the account's key list. |
| 60 | +# The guest image ships neither ssh-keygen nor a base64 applet (BusyBox has |
| 61 | +# base32 only), so openssl does both the decode and the digest. |
| 62 | +print_authorized_key_fingerprints() { |
| 63 | + local file="$1" |
| 64 | + if ! command -v openssl >/dev/null 2>&1; then |
| 65 | + echo "openssl not available; skipping SSH key fingerprints" |
| 66 | + return 0 |
| 67 | + fi |
| 68 | + |
| 69 | + local key_type blob comment decoded_bytes fingerprint |
| 70 | + # `|| [[ -n "$key_type" ]]` keeps the final line when the file does not end |
| 71 | + # with a newline; read returns non-zero there but still fills the variables. |
| 72 | + while read -r key_type blob comment || [[ -n "$key_type" ]]; do |
| 73 | + if [[ -z "$blob" ]]; then |
| 74 | + continue |
| 75 | + fi |
| 76 | + # openssl exits 0 on undecodable input and emits nothing, which would |
| 77 | + # otherwise print the SHA256 of the empty string as a real fingerprint. |
| 78 | + decoded_bytes=$(printf '%s' "$blob" | openssl base64 -d -A 2>/dev/null | wc -c || true) |
| 79 | + if [[ "$decoded_bytes" -eq 0 ]]; then |
| 80 | + echo " $key_type <unreadable key>" |
| 81 | + continue |
| 82 | + fi |
| 83 | + fingerprint=$( |
| 84 | + printf '%s' "$blob" | openssl base64 -d -A 2>/dev/null | openssl dgst -sha256 -binary 2>/dev/null | openssl base64 -A 2>/dev/null | tr -d '=' || true |
| 85 | + ) |
| 86 | + echo " $key_type SHA256:$fingerprint" |
| 87 | + done < "$file" |
| 88 | +} |
| 89 | + |
56 | 90 | # Main logic starts here |
57 | 91 | echo "Starting login process..." |
58 | 92 |
|
@@ -309,13 +343,16 @@ if mkdir -p /home/root/.ssh 2>/dev/null; then |
309 | 343 |
|
310 | 344 | if [[ -f /dstack/user_config ]] && jq empty /dstack/user_config 2>/dev/null; then |
311 | 345 | if [[ $(jq 'has("ssh_authorized_keys")' /dstack/user_config 2>/dev/null) == "true" ]]; then |
312 | | - jq -j '.ssh_authorized_keys' /dstack/user_config >> /home/root/.ssh/authorized_keys |
313 | | - # Remove duplicates if there are multiple keys |
314 | | - if [[ $(cat /home/root/.ssh/authorized_keys | wc -l) -gt 1 ]]; then |
315 | | - sort -u /home/root/.ssh/authorized_keys > /home/root/.ssh/authorized_keys.tmp |
316 | | - mv /home/root/.ssh/authorized_keys.tmp /home/root/.ssh/authorized_keys |
317 | | - fi |
318 | | - echo "Set root authorized_keys from user preferences, total" $(cat /home/root/.ssh/authorized_keys | wc -l) "keys" |
| 346 | + # jq -r terminates the value with a newline; jq -j does not, which |
| 347 | + # both concatenated the next appended key onto the same line and |
| 348 | + # made line-based counting report one key fewer than the file holds. |
| 349 | + jq -r '.ssh_authorized_keys' /dstack/user_config >> /home/root/.ssh/authorized_keys |
| 350 | + # Drop duplicates and the blank line an empty key list produces. |
| 351 | + sort -u /home/root/.ssh/authorized_keys > /home/root/.ssh/authorized_keys.tmp |
| 352 | + mv /home/root/.ssh/authorized_keys.tmp /home/root/.ssh/authorized_keys |
| 353 | + KEY_COUNT=$(grep -c '^[^[:space:]]' /home/root/.ssh/authorized_keys || true) |
| 354 | + echo "Set root authorized_keys from user preferences, total $KEY_COUNT keys" |
| 355 | + print_authorized_key_fingerprints /home/root/.ssh/authorized_keys |
319 | 356 | fi |
320 | 357 | fi |
321 | 358 | else |
|
0 commit comments