disinto/tools/edge-control/lib/authorized_keys.sh
Claude cf3c63bf68
All checks were successful
ci/woodpecker/push/ci Pipeline was successful
ci/woodpecker/pr/ci Pipeline was successful
ci/woodpecker/pr/smoke-init Pipeline was successful
fix: SSH accept-new and DOMAIN_SUFFIX configuration for edge control
- Changed SSH StrictHostKeyChecking from 'no' to 'accept-new' for better security
- Fixed .env write logic with proper deduplication before appending
- Fixed deregister .env cleanup to use single grep pattern
- Added --domain-suffix option to install.sh
- Removed no-op DOMAIN_SUFFIX sed from install.sh
- Changed cp -n to cp for idempotent script updates
- Fixed authorized_keys.sh SCRIPT_DIR to point to lib/
- Fixed Caddy route management to use POST /routes instead of /load
- Fixed Caddy remove_route to find route by host match, not hardcoded index
2026-04-10 19:09:43 +00:00

99 lines
3 KiB
Bash
Executable file

#!/usr/bin/env bash
# =============================================================================
# lib/authorized_keys.sh — Rebuild authorized_keys from registry
#
# Rebuilds disinto-tunnel's authorized_keys file from the registry.
# Each entry has:
# - restrict flag (no shell, no X11 forwarding, etc.)
# - permitlisten for allowed reverse tunnel ports
# - command="/bin/false" to prevent arbitrary command execution
#
# Functions:
# rebuild_authorized_keys → rebuilds /home/disinto-tunnel/.ssh/authorized_keys
# get_tunnel_authorized_keys → prints the generated authorized_keys content
# =============================================================================
set -euo pipefail
# Source ports library (SCRIPT_DIR is this file's directory, so lib/ports.sh is adjacent)
SCRIPT_DIR="$(cd "$(dirname "${BASH_SOURCE[0]}")" && pwd)"
source "${SCRIPT_DIR}/ports.sh"
# Tunnel user home directory
TUNNEL_USER="disinto-tunnel"
TUNNEL_SSH_DIR="/home/${TUNNEL_USER}/.ssh"
TUNNEL_AUTH_KEYS="${TUNNEL_SSH_DIR}/authorized_keys"
# Ensure tunnel user exists
_ensure_tunnel_user() {
if ! id "$TUNNEL_USER" &>/dev/null; then
useradd -r -s /usr/sbin/nologin -M "$TUNNEL_USER" 2>/dev/null || true
mkdir -p "$TUNNEL_SSH_DIR"
chmod 700 "$TUNNEL_SSH_DIR"
fi
}
# Generate the authorized_keys content from registry
# Output: one authorized_keys line per registered project
generate_authorized_keys_content() {
local content=""
local first=true
# Get all projects from registry
while IFS= read -r line; do
[ -z "$line" ] && continue
local project port pubkey
# shellcheck disable=SC2034
project=$(echo "$line" | jq -r '.name')
port=$(echo "$line" | jq -r '.port')
pubkey=$(echo "$line" | jq -r '.pubkey')
# Skip if missing required fields
[ -z "$port" ] || [ -z "$pubkey" ] && continue
# Build the authorized_keys line
# Format: restrict,port-forwarding,permitlisten="127.0.0.1:<port>",command="/bin/false" <key-type> <key>
local auth_line="restrict,port-forwarding,permitlisten=\"127.0.0.1:${port}\",command=\"/bin/false\" ${pubkey}"
if [ "$first" = true ]; then
content="$auth_line"
first=false
else
content="${content}
${auth_line}"
fi
done < <(list_ports)
if [ -z "$content" ]; then
# No projects registered, create empty file
echo "# No tunnels registered"
else
echo "$content"
fi
}
# Rebuild authorized_keys file
# Usage: rebuild_authorized_keys
rebuild_authorized_keys() {
_ensure_tunnel_user
local content
content=$(generate_authorized_keys_content)
# Write to file
echo "$content" > "$TUNNEL_AUTH_KEYS"
chmod 600 "$TUNNEL_AUTH_KEYS"
chown -R "$TUNNEL_USER":"$TUNNEL_USER" "$TUNNEL_SSH_DIR"
echo "Rebuilt authorized_keys for ${TUNNEL_USER} (entries: $(echo "$content" | grep -c 'ssh-' || echo 0))"
}
# Get the current authorized_keys content (for verification)
# Usage: get_tunnel_authorized_keys
get_tunnel_authorized_keys() {
if [ -f "$TUNNEL_AUTH_KEYS" ]; then
cat "$TUNNEL_AUTH_KEYS"
else
generate_authorized_keys_content
fi
}