#!/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."