Newer
Older
ansible_util / setup.sh
#!/usr/bin/env bash
set -euo pipefail

ANSIBLE_USER="ansible"
SSH_DIR="/home/${ANSIBLE_USER}/.ssh"
KEY_TYPE="ed25519"
KEY_TMP_DIR=""
KEY_TMP_PATH=""

cleanup() {
  if [[ -n "${KEY_TMP_DIR}" && -d "${KEY_TMP_DIR}" ]]; then
    rm -rf "${KEY_TMP_DIR}"
  fi
}
trap cleanup EXIT

if [[ $EUID -ne 0 ]]; then
  echo "This script must be run as root"
  exit 1
fi

echo "==> Creating ansible user (if needed)"
if ! id "${ANSIBLE_USER}" >/dev/null 2>&1; then
  useradd --create-home --shell /bin/bash "${ANSIBLE_USER}"
fi

echo "==> Locking password access for ansible user"
passwd -l "${ANSIBLE_USER}"

echo "==> Configuring sudoers (NOPASSWD)"
SUDOERS_FILE="/etc/sudoers.d/ansible"
SUDOERS_LINE="ansible ALL=(ALL) NOPASSWD:ALL"

if [[ -f "${SUDOERS_FILE}" ]]; then
  if grep -qE '^ansible\s+ALL=\(ALL\)\s+NOPASSWD:ALL' "${SUDOERS_FILE}"; then
    : # already correct
  elif grep -qE '^ansible\s+' "${SUDOERS_FILE}"; then
    sed -i "s|^ansible\s\+.*|${SUDOERS_LINE}|" "${SUDOERS_FILE}"
  else
    echo "${SUDOERS_LINE}" >> "${SUDOERS_FILE}"
  fi
else
  echo "${SUDOERS_LINE}" > "${SUDOERS_FILE}"
  chmod 440 "${SUDOERS_FILE}"
fi

echo "==> Ensuring .ssh directory exists"
mkdir -p "${SSH_DIR}"
chmod 700 "${SSH_DIR}"
chown "${ANSIBLE_USER}:${ANSIBLE_USER}" "${SSH_DIR}"

AUTHORIZED_KEYS="${SSH_DIR}/authorized_keys"
touch "${AUTHORIZED_KEYS}"
chmod 600 "${AUTHORIZED_KEYS}"
chown "${ANSIBLE_USER}:${ANSIBLE_USER}" "${AUTHORIZED_KEYS}"

echo "==> Generating SSH keypair (temporary)"
KEY_TMP_DIR="$(mktemp -d)"
chmod 700 "${KEY_TMP_DIR}"
KEY_TMP_PATH="${KEY_TMP_DIR}/id_${KEY_TYPE}"

KEY_COMMENT="ansible-bootstrap $(date -u +%Y-%m-%d %H:%M:%SZ)"

ssh-keygen \
  -t "${KEY_TYPE}" \
  -f "${KEY_TMP_PATH}" \
  -N "" \
  -C "${KEY_COMMENT}"

echo "==> Installing public key into authorized_keys"
cat "${KEY_TMP_PATH}.pub" >> "${AUTHORIZED_KEYS}"

echo "==> Configuring sshd Match User ansible block"
SSHD_CONFIG="/etc/ssh/sshd_config"

if [[ ! -f /etc/ssh/sshd_config.ansible.bak ]]; then
  cp "${SSHD_CONFIG}" /etc/ssh/sshd_config.ansible.bak
fi

# Remove existing Match User ansible block
sed -i '/^Match User ansible$/,/^Match /d' "${SSHD_CONFIG}"

cat >> "${SSHD_CONFIG}" <<EOF

Match User ansible
    PasswordAuthentication no
    PubkeyAuthentication yes
    ChallengeResponseAuthentication no
    AuthenticationMethods publickey
    UsePAM yes
EOF

echo "==> Restarting SSH daemon"
if command -v systemctl >/dev/null 2>&1; then
  systemctl restart sshd || systemctl restart ssh
else
  service sshd restart || service ssh restart
fi

echo "==> Ensuring python3 is installed"
if ! command -v python3 >/dev/null 2>&1; then
  if command -v apt-get >/dev/null 2>&1; then
    apt-get update
    apt-get install -y python3
  elif command -v dnf >/dev/null 2>&1; then
    dnf install -y python3
  elif command -v yum >/dev/null 2>&1; then
    yum install -y python3
  else
    echo "WARNING: Could not detect package manager. Install python3 manually."
  fi
fi

echo
echo "===================================================="
echo "ANSIBLE PRIVATE KEY (STORE SECURELY)"
echo "===================================================="
cat "${KEY_TMP_PATH}"
echo "===================================================="

echo "==> Done"