#!/usr/bin/env bash exec > >(tee -i /var/log/stackscript.log) 2>&1 set -euo pipefail export DEBIAN_FRONTEND=noninteractive export NEEDRESTART_MODE=a # # # # # # # # touch ~/.hushlogin echo "Updating system..." apt-get update apt-get install -y sudo openssh-server echo "Setting hostname to $NAME" hostnamectl set-hostname "${NAME}" || true : "${SSH_USER:=ansible}" : "${USER_PASSWORD:=}" echo "Creating user $SSH_USER" if ! id -u "${SSH_USER}" >/dev/null 2>&1; then useradd -m -s /bin/bash "${SSH_USER}" fi if [ -n "${USER_PASSWORD}" ]; then echo "${SSH_USER}:${USER_PASSWORD}" | chpasswd fi groupadd -f sudo usermod -aG sudo "${SSH_USER}" mkdir -p /etc/sudoers.d cat > "/etc/sudoers.d/90-${SSH_USER}" <&2 exit 1 fi if [ -n "${GROUP}" ]; then groupadd -f "${GROUP}" usermod -aG "${GROUP}" "${SSH_USER}" fi # SSH setup echo "Configuring SSH..." mkdir -p "${USER_HOME}"/.ssh for i in $(seq 1 60); do if [ -s /root/.ssh/authorized_keys ]; then break fi sleep 2 done if [ -s /root/.ssh/authorized_keys ]; then cp /root/.ssh/authorized_keys "${USER_HOME}"/.ssh/authorized_keys else if [ -n "${SSH_PUBLIC_KEY:-}" ]; then printf '%s\n' "${SSH_PUBLIC_KEY}" > "${USER_HOME}"/.ssh/authorized_keys else echo "No /root/.ssh/authorized_keys and no SSH_PUBLIC_KEY provided" >&2 exit 1 fi fi if [ -n "${SSH_PUBLIC_KEY:-}" ]; then if ! grep -qF "${SSH_PUBLIC_KEY}" "${USER_HOME}"/.ssh/authorized_keys; then printf '%s\n' "${SSH_PUBLIC_KEY}" >> "${USER_HOME}"/.ssh/authorized_keys fi fi chown -R "${SSH_USER}:${SSH_USER}" "${USER_HOME}"/.ssh chmod 700 "${USER_HOME}"/.ssh chmod 600 "${USER_HOME}"/.ssh/authorized_keys chown "${SSH_USER}:${SSH_USER}" "${USER_HOME}" chmod 755 "${USER_HOME}" chmod go-w "${USER_HOME}" mkdir -p /etc/ssh/sshd_config.d cat > /etc/ssh/sshd_config.d/99-infra.conf < /etc/sysctl.d/99-console-quiet.conf < /etc/apt/sources.list.d/docker.list apt-get update apt-get install -y docker-ce docker-ce-cli containerd.io docker-buildx-plugin docker-compose-plugin usermod -aG docker "${SSH_USER}" systemctl enable docker # Docker Compose (v2 plugin installed above) # Ansible echo "Installing Ansible..." pip3 install ansible # Fail2ban echo "Configuring Fail2ban..." cat > /etc/fail2ban/jail.d/sshd.local < /etc/logrotate.d/custom < /dev/null 2>/dev/null || true endscript } EOF # Optional: NTP (Systemd handles this well now) timedatectl set-ntp true # Cleanup echo "Cleaning up..." history -c rm -f /root/.bash_history /home/${SSH_USER}/.bash_history || true unset NAME GROUP SSH_USER USER_PASSWORD SSH_PUBLIC_KEY SSH_PORT TIMEZONE ADD_CLOUDFLARE_IPS echo "StackScript complete. Server ready."