homelab infrastructure services
1#!/bin/bash
2# NAS SSH authentication and connectivity functions for tinsnip
3
4# Source core functions
5LIB_DIR="$(cd "$(dirname "${BASH_SOURCE[0]}")" && pwd)"
6source "$LIB_DIR/core.sh"
7
8# Get SSH key for NAS server (checks for existing keys or creates new one)
9get_nas_ssh_key() {
10 local nas_server="$1"
11
12 # 1. Test if default SSH config/keys work
13 if ssh -o BatchMode=yes -o ConnectTimeout=5 "$nas_server" exit 2>/dev/null; then
14 echo "default" # Signal that default SSH works
15 return 0
16 fi
17
18 # 2. Check tinsnip-specific key
19 local tinsnip_key="$HOME/.ssh/tinsnip-${nas_server}"
20 if [[ -f "$tinsnip_key" ]] && ssh -o BatchMode=yes -i "$tinsnip_key" "$nas_server" exit 2>/dev/null; then
21 echo "$tinsnip_key"
22 return 0
23 fi
24
25 # 3. Create tinsnip-specific key if needed
26 if create_tinsnip_ssh_key "$nas_server"; then
27 echo "$tinsnip_key"
28 return 0
29 fi
30
31 return 1 # SSH setup failed
32}
33
34# Create and install SSH key for NAS server
35create_tinsnip_ssh_key() {
36 local nas_server="$1"
37 local tinsnip_key="$HOME/.ssh/tinsnip-${nas_server}"
38
39 log_with_prefix "SSH Setup" "Creating SSH key for $nas_server..."
40
41 # Ensure .ssh directory exists
42 mkdir -p "$HOME/.ssh"
43 chmod 700 "$HOME/.ssh"
44
45 # Generate key with descriptive comment
46 if ! ssh-keygen -t ed25519 -f "$tinsnip_key" -N "" -C "tinsnip-$(date +%Y%m%d)-${nas_server}-$(hostname)" >/dev/null 2>&1; then
47 log_with_prefix "SSH Setup" "❌ Failed to generate SSH key"
48 return 1
49 fi
50
51 # Install public key on NAS
52 log_with_prefix "SSH Setup" "Installing public key on $nas_server..."
53 if ! ssh-copy-id -i "$tinsnip_key" "$nas_server" >/dev/null 2>&1; then
54 log_with_prefix "SSH Setup" "❌ Failed to install public key on $nas_server"
55 log_with_prefix "SSH Setup" "Please ensure password authentication is enabled"
56 rm -f "$tinsnip_key" "${tinsnip_key}.pub"
57 return 1
58 fi
59
60 # Test the new key
61 if ! ssh -o BatchMode=yes -i "$tinsnip_key" "$nas_server" exit 2>/dev/null; then
62 log_with_prefix "SSH Setup" "❌ SSH key test failed"
63 rm -f "$tinsnip_key" "${tinsnip_key}.pub"
64 return 1
65 fi
66
67 log_with_prefix "SSH Setup" "✅ SSH key created and installed successfully"
68 return 0
69}
70
71# Execute SSH command with proper authentication (key or password fallback)
72ssh_to_nas() {
73 local nas_server="$1"
74 shift
75 local ssh_opts=()
76
77 # If no username specified in nas_server, prepend current user
78 if [[ "$nas_server" != *@* ]]; then
79 nas_server="${USER}@${nas_server}"
80 fi
81
82 # Extract SSH options from arguments
83 while [[ $# -gt 0 && "$1" == -* ]]; do
84 ssh_opts+=("$1")
85 shift
86 done
87
88 # Try to use SSH key or default SSH config
89 local key_path
90 if key_path=$(get_nas_ssh_key "$nas_server" 2>/dev/null); then
91 if [[ "$key_path" == "default" ]]; then
92 # Using default SSH authentication (ssh-agent/~/.ssh/)
93 ssh_opts+=("-o" "BatchMode=yes")
94 else
95 # Using specific SSH key
96 ssh_opts+=("-i" "$key_path" "-o" "BatchMode=yes")
97 fi
98 else
99 # No SSH key found, fall back to password auth
100 ssh_opts+=("-o" "BatchMode=no")
101 fi
102
103 # Execute SSH with appropriate options
104 ssh "${ssh_opts[@]}" "$nas_server" "$@"
105}
106
107# Test NAS connectivity
108test_nas_connectivity() {
109 local nas_server="$1"
110
111 if ssh_to_nas "$nas_server" "echo 'SSH test'" &>/dev/null; then
112 return 0
113 else
114 return 1
115 fi
116}
117
118# Setup NAS authentication (interactive, for initial setup)
119setup_nas_auth() {
120 local nas_server="$1"
121
122 log_with_prefix "NAS Auth" "Setting up authentication for $nas_server..."
123
124 if test_nas_connectivity "$nas_server"; then
125 log_with_prefix "NAS Auth" "✅ Authentication already working"
126 return 0
127 fi
128
129 log_with_prefix "NAS Auth" "Creating SSH key for passwordless access..."
130 if create_tinsnip_ssh_key "$nas_server"; then
131 log_with_prefix "NAS Auth" "✅ SSH key setup complete"
132 return 0
133 else
134 warn_with_prefix "NAS Auth" "SSH key setup failed, will use password authentication"
135 return 1
136 fi
137}