Some checks failed
CI / skip-ci-check (pull_request) Successful in 6s
CI / lint-and-test (pull_request) Failing after 9s
CI / ansible-validation (pull_request) Failing after 6s
CI / secret-scanning (pull_request) Successful in 5s
CI / dependency-scan (pull_request) Successful in 8s
CI / sast-scan (pull_request) Failing after 5s
CI / license-check (pull_request) Successful in 11s
CI / vault-check (pull_request) Failing after 6s
CI / playbook-test (pull_request) Failing after 6s
CI / container-scan (pull_request) Failing after 6s
CI / sonar-analysis (pull_request) Failing after 2s
CI / workflow-summary (pull_request) Successful in 4s
Document pve10 static IPs, monitoring stack, and site LXCs; add portfolio to inventory; Mailcow mailbox automation; vault import/export scripts; security audit guides and UniFi DHCP reference. Co-authored-by: Cursor <cursoragent@cursor.com>
104 lines
3.0 KiB
Bash
Executable File
104 lines
3.0 KiB
Bash
Executable File
#!/usr/bin/env bash
|
|
# Bootstrap root SSH key access via a normal user (default: ladmin).
|
|
# Usage: ./scripts/bootstrap-root-ssh.sh HOSTNAME
|
|
# BOOTSTRAP_USER=ladmin TARGET_USER=root SSH_PUBLIC_KEY=~/.ssh/id_ed25519.pub
|
|
|
|
set -euo pipefail
|
|
|
|
REPO_ROOT="$(cd "$(dirname "$0")/.." && pwd)"
|
|
INVENTORY_HOSTS="${INVENTORY_HOSTS:-${REPO_ROOT}/inventories/production/hosts}"
|
|
PUBKEY_FILE="${SSH_PUBLIC_KEY:-${HOME}/.ssh/id_ed25519.pub}"
|
|
BOOTSTRAP_USER="${BOOTSTRAP_USER:-ladmin}"
|
|
TARGET_USER="${TARGET_USER:-root}"
|
|
HOST="${1:-}"
|
|
|
|
if [[ -z "${HOST}" ]]; then
|
|
echo "Usage: $0 HOST" >&2
|
|
exit 1
|
|
fi
|
|
|
|
if [[ ! -f "${PUBKEY_FILE}" ]]; then
|
|
echo "Public key not found: ${PUBKEY_FILE}" >&2
|
|
exit 1
|
|
fi
|
|
|
|
resolve_from_inventory() {
|
|
awk -v host="${HOST}" '
|
|
$1 == host {
|
|
for (i = 2; i <= NF; i++) {
|
|
if ($i ~ /^ansible_host=/) {
|
|
sub(/ansible_host=/, "", $i)
|
|
ip = $i
|
|
}
|
|
if ($i ~ /^ansible_user=/) {
|
|
sub(/ansible_user=/, "", $i)
|
|
user = $i
|
|
}
|
|
}
|
|
}
|
|
END {
|
|
print ip
|
|
print user
|
|
}
|
|
' "${INVENTORY_HOSTS}"
|
|
}
|
|
|
|
IP="$(resolve_from_inventory | sed -n '1p')"
|
|
INV_USER="$(resolve_from_inventory | sed -n '2p')"
|
|
|
|
if [[ -z "${IP}" ]]; then
|
|
echo "Could not resolve ansible_host for ${HOST} in ${INVENTORY_HOSTS}" >&2
|
|
exit 1
|
|
fi
|
|
|
|
echo "==> ${HOST} (${BOOTSTRAP_USER}@${IP} -> ${TARGET_USER})"
|
|
echo " Inventory ansible_user: ${INV_USER:-<unset>}"
|
|
echo " Public key: ${PUBKEY_FILE}"
|
|
echo ""
|
|
|
|
echo "Step 1/3: Install key for ${BOOTSTRAP_USER} (password: ${BOOTSTRAP_USER})"
|
|
ssh-copy-id -i "${PUBKEY_FILE}" -o StrictHostKeyChecking=accept-new \
|
|
"${BOOTSTRAP_USER}@${IP}"
|
|
|
|
echo ""
|
|
echo "Step 2/3: Copy key and configure ${TARGET_USER} via su (password: root)"
|
|
REMOTE_KEY="/tmp/ansible-bootstrap.pub"
|
|
scp -o StrictHostKeyChecking=accept-new "${PUBKEY_FILE}" \
|
|
"${BOOTSTRAP_USER}@${IP}:${REMOTE_KEY}"
|
|
|
|
ssh -t "${BOOTSTRAP_USER}@${IP}" bash -s <<REMOTE_SCRIPT
|
|
set -e
|
|
REMOTE_KEY="${REMOTE_KEY}"
|
|
su - root <<ROOT_SCRIPT
|
|
set -e
|
|
mkdir -p /root/.ssh
|
|
chmod 700 /root/.ssh
|
|
touch /root/.ssh/authorized_keys
|
|
chmod 600 /root/.ssh/authorized_keys
|
|
if ! grep -qF "\$(cat "\${REMOTE_KEY}")" /root/.ssh/authorized_keys 2>/dev/null; then
|
|
cat "\${REMOTE_KEY}" >> /root/.ssh/authorized_keys
|
|
fi
|
|
rm -f "\${REMOTE_KEY}"
|
|
if [ -f /etc/ssh/sshd_config ]; then
|
|
if grep -q '^PermitRootLogin' /etc/ssh/sshd_config; then
|
|
sed -i 's/^#*PermitRootLogin.*/PermitRootLogin prohibit-password/' /etc/ssh/sshd_config
|
|
else
|
|
echo 'PermitRootLogin prohibit-password' >> /etc/ssh/sshd_config
|
|
fi
|
|
systemctl restart ssh 2>/dev/null \
|
|
|| systemctl restart sshd 2>/dev/null \
|
|
|| service ssh restart 2>/dev/null \
|
|
|| true
|
|
fi
|
|
echo "OK: root authorized_keys updated; PermitRootLogin prohibit-password"
|
|
ROOT_SCRIPT
|
|
REMOTE_SCRIPT
|
|
|
|
echo ""
|
|
echo "Step 3/3: Verify ${TARGET_USER} key login"
|
|
ssh -o BatchMode=yes -i "${PUBKEY_FILE}" -o StrictHostKeyChecking=accept-new \
|
|
"${TARGET_USER}@${IP}" "echo OK: ${TARGET_USER}@${IP} accepts your SSH key"
|
|
|
|
echo ""
|
|
echo "Done: ${HOST} — use: ssh -i ${PUBKEY_FILE} ${TARGET_USER}@${IP}"
|