#!/usr/bin/env bash set -euo pipefail usage() { cat <<'EOF' Usage: sudo ./ops/install-chart-debug \ --public-key 'ssh-ed25519 AAAA...' \ --container-pattern '^chart-app-' \ [--url https://chart.amow.com] EOF } public_key="" container_pattern="" public_url="https://chart.amow.com" while [[ $# -gt 0 ]]; do case "$1" in --public-key) public_key=${2:-}; shift 2 ;; --container-pattern) container_pattern=${2:-}; shift 2 ;; --url) public_url=${2:-}; shift 2 ;; *) usage >&2; exit 2 ;; esac done [[ $EUID -eq 0 ]] || { echo "run as root" >&2; exit 1; } [[ "$public_key" =~ ^(ssh-ed25519|sk-ssh-ed25519@openssh.com)[[:space:]]+[A-Za-z0-9+/=]+([[:space:]].*)?$ ]] || { echo "an Ed25519 public key is required" >&2; exit 2; } [[ -n "$container_pattern" && "$container_pattern" != *$'\n'* ]] || { echo "a container-name regex is required" >&2; exit 2; } [[ "$public_url" =~ ^https://[^/]+$ ]] || { echo "--url must be an HTTPS origin" >&2; exit 2; } script_dir=$(cd -- "$(dirname -- "${BASH_SOURCE[0]}")" && pwd) install -o root -g root -m 0755 "$script_dir/chart-debug-command" /usr/local/sbin/chart-debug-command if ! id chart-debug >/dev/null 2>&1; then useradd --create-home --shell /bin/bash chart-debug fi passwd --lock chart-debug >/dev/null install -d -o chart-debug -g chart-debug -m 0700 /home/chart-debug/.ssh forced='restrict,command="/usr/bin/sudo -n /usr/local/sbin/chart-debug-command \"$SSH_ORIGINAL_COMMAND\""' printf '%s %s\n' "$forced" "$public_key" \ > /home/chart-debug/.ssh/authorized_keys chown chart-debug:chart-debug /home/chart-debug/.ssh/authorized_keys chmod 0600 /home/chart-debug/.ssh/authorized_keys printf 'CHART_CONTAINER_PATTERN=%q\nCHART_PUBLIC_URL=%q\n' \ "$container_pattern" "$public_url" > /etc/chart-debug.conf chown root:root /etc/chart-debug.conf chmod 0600 /etc/chart-debug.conf cat > /etc/sudoers.d/chart-debug <<'EOF' Defaults:chart-debug !requiretty chart-debug ALL=(root) NOPASSWD: /usr/local/sbin/chart-debug-command * EOF chmod 0440 /etc/sudoers.d/chart-debug visudo -cf /etc/sudoers.d/chart-debug >/dev/null matches=0 while read -r _ name; do [[ "$name" =~ $container_pattern ]] && matches=$((matches + 1)) done < <(docker ps --format '{{.ID}} {{.Names}}') [[ $matches -eq 1 ]] || { echo "warning: container pattern currently matches $matches running containers" >&2 } echo "installed restricted chart-debug access"