From 08799f0f7f7193ea59fd55f1fdd6cc3fc80c971a Mon Sep 17 00:00:00 2001 From: Justin Oros Date: Thu, 16 Apr 2026 12:58:06 -0700 Subject: [PATCH] add SSH key permission checks with auto-fix to hub and spoke scripts --- hub/setup-hub.sh | 30 ++++++++++++++++++++++++++++++ spoke/setup-spoke.sh | 30 ++++++++++++++++++++++++++++++ 2 files changed, 60 insertions(+) diff --git a/hub/setup-hub.sh b/hub/setup-hub.sh index 4c8dbdf..4eb1319 100644 --- a/hub/setup-hub.sh +++ b/hub/setup-hub.sh @@ -7,6 +7,31 @@ YELLOW='\033[1;33m' CYAN='\033[0;36m' NC='\033[0m' +check_permissions() { + local file="$1" + local label="$2" + if [ ! -f "$file" ]; then + warn "Permission check: $label not found at $file" + return + fi + local perms + perms=$(stat -c "%a" "$file" 2>/dev/null || stat -f "%OLp" "$file" 2>/dev/null) + if [ -z "$perms" ]; then + warn "Could not read permissions for $label ($file)" + return + fi + local world="${perms: -1}" + local group="${perms: -2:1}" + if [ "$world" != "0" ] || [ "$group" != "0" ]; then + warn "UNSAFE PERMISSIONS on $label ($file): $perms — should be 600 or 400" + warn "Fixing permissions automatically..." + chmod 600 "$file" + info "Permissions fixed: $file is now 600" + else + info "Permissions OK: $label ($file) = $perms" + fi +} + info() { echo -e "${GREEN}[+]${NC} $*"; } warn() { echo -e "${YELLOW}[!]${NC} $*"; } die() { echo -e "${RED}[ERROR]${NC} $*" >&2; exit 1; } @@ -187,6 +212,11 @@ groupadd fuse 2>/dev/null || true usermod -aG fuse "$HUB_USER" 2>/dev/null || true info "$HUB_USER added to fuse group." +header "Permission Checks" +info "Checking SSH directory permissions..." +check_permissions "$SSH_DIR/authorized_keys" "authorized_keys" +[ -f "$RCLONE_CONF" ] && check_permissions "$RCLONE_CONF" "rclone.conf" || true + header "Rclone Setup" RCLONE_CONF="$ARMBIAN_HOME/.config/rclone/rclone.conf" mkdir -p "$(dirname "$RCLONE_CONF")" diff --git a/spoke/setup-spoke.sh b/spoke/setup-spoke.sh index 55c8a76..5ca9f27 100644 --- a/spoke/setup-spoke.sh +++ b/spoke/setup-spoke.sh @@ -34,6 +34,31 @@ retry_or_abort() { done } +check_permissions() { + local file="$1" + local label="$2" + if [ ! -f "$file" ]; then + warn "Permission check: $label not found at $file" + return + fi + local perms + perms=$(stat -c "%a" "$file" 2>/dev/null || stat -f "%OLp" "$file" 2>/dev/null) + if [ -z "$perms" ]; then + warn "Could not read permissions for $label ($file)" + return + fi + local world="${perms: -1}" + local group="${perms: -2:1}" + if [ "$world" != "0" ] || [ "$group" != "0" ]; then + warn "UNSAFE PERMISSIONS on $label ($file): $perms — should be 600 or 400" + warn "Fixing permissions automatically..." + chmod 600 "$file" + info "Permissions fixed: $file is now 600" + else + info "Permissions OK: $label ($file) = $perms" + fi +} + info() { echo -e "${GREEN}[+]${NC} $*"; } warn() { echo -e "${YELLOW}[!]${NC} $*"; } die() { echo -e "${RED}[ERROR]${NC} $*" >&2; exit 1; } @@ -224,6 +249,11 @@ else info "Password authentication left enabled." fi +info "Checking SSH key permissions..." +check_permissions "$KEY_PATH" "spoke SSH private key" +[ -f "$KEY_PATH.pub" ] && check_permissions "$KEY_PATH.pub" "spoke SSH public key" || true +check_permissions "$SSH_DIR/known_hosts" "known_hosts" || true + info "Scanning hub host key..." sudo -u "$SPOKE_USER" touch "$SSH_DIR/known_hosts" chown "$SPOKE_USER":"$SPOKE_USER" "$SSH_DIR/known_hosts"