commit 87d6ffe8a0b87ba126a90ad1ad9d1783a5dcdf73 Author: Francesco Picone Date: Mon Dec 29 16:00:23 2025 +0100 Primo caricamento diff --git a/Makefile b/Makefile new file mode 100644 index 0000000..d4b5272 --- /dev/null +++ b/Makefile @@ -0,0 +1,48 @@ +.PHONY: postinstall utils hardening sys-tune + +postinstall: utils hardening sys-tune + @echo "[INFO] Post-installazione completata." + +utils: + @echo "[INFO] Installo utilità post-installazione..." + @apt-get update + @DEBIAN_FRONTEND=noninteractive apt-get install -y --no-install-recommends \ + vim tmux net-tools wget jq tree fail2ban software-properties-common \ + htop lsof + +hardening: + @echo "[INFO] Configuro auto-aggiornamenti di sicurezza, sysctl e Docker..." + @DEBIAN_FRONTEND=noninteractive apt-get install -y --no-install-recommends unattended-upgrades + @printf 'APT::Periodic::Update-Package-Lists "1";\nAPT::Periodic::Unattended-Upgrade "1";\n' | tee /etc/apt/apt.conf.d/20auto-upgrades >/dev/null + @mkdir -p /etc/sysctl.d + @tee /etc/sysctl.d/99-hardening.conf >/dev/null <<'EOF' +net.ipv4.conf.all.rp_filter=1 +net.ipv4.tcp_syncookies=1 +net.ipv4.icmp_echo_ignore_broadcasts=1 +kernel.kptr_restrict=2 +kernel.randomize_va_space=2 +EOF + @sysctl --system || true + @mkdir -p /etc/docker + @tee /etc/docker/daemon.json >/dev/null <<'EOF' +{ + "log-driver": "json-file", + "log-opts": { "max-size": "10m", "max-file": "3" }, + "live-restore": true +} +EOF + @systemctl reload docker || systemctl restart docker || true + @mkdir -p /etc/fail2ban/jail.d + @tee /etc/fail2ban/jail.d/sshd-local.conf >/dev/null <<'EOF' +[sshd] +enabled = true +bantime = 1h +findtime = 10m +maxretry = 5 +EOF + @systemctl restart fail2ban || true + +sys-tune: + @echo "[INFO] Configuro Fail2ban..." + @systemctl enable fail2ban || true + @systemctl restart fail2ban || true diff --git a/README.md b/README.md new file mode 100644 index 0000000..a3ef656 --- /dev/null +++ b/README.md @@ -0,0 +1,39 @@ +# Setup Ubuntu Server + Docker + Portainer + +Questo repository contiene uno script per configurare rapidamente un server Ubuntu: +- Aggiorna il sistema e installa pacchetti base +- Configura repository e installa Docker (CE, CLI, containerd, buildx, compose plugin) +- Chiede il nome utente, lo crea e lo aggiunge al gruppo `docker` +- Esegue una post-installazione tramite `make` +- Clona il repo Portainer e ne esegue il deploy via Docker + +In aggiunta, applica misure di hardening (senza SSH hardening): +- Impostazione timezone (default: Europe/Rome) +- Auto-aggiornamenti di sicurezza (`unattended-upgrades`) +- Fail2ban: jail `sshd` abilitata con limiti prudenziali +- Docker: `daemon.json` con `live-restore` e rotazione log + +## Requisiti +- Esegui su Ubuntu Server (root/sudo necessario) +- Connettività Internet + +## Uso +1. Copia la cartella `linux-server-setup` sul server Ubuntu. +2. Esegui lo script di setup: + +```bash +sudo bash scripts/setup.sh +``` + +3. Inserisci il nome utente quando richiesto. Lo script: + - creerà l'utente (se non esiste) e imposterà la password + - installerà Docker e aggiungerà l'utente al gruppo `docker` + - eseguirà `make postinstall` per utilità post-installazione + - clonerà `https://git.pyconetwork.it/francesco/portainer.git` in `/opt/portainer` e tenterà il deploy con `docker compose up -d` + +## Note +- Dopo l'aggiunta al gruppo `docker`, è necessario fare logout/login per applicare i permessi. +- Se il repository Portainer non contiene un `docker-compose.yml/compose.yml`, lo script proverà `make deploy` se presente; altrimenti mostrerà un avviso. +- Il target `postinstall` installa: `vim`, `tmux`, `net-tools`, `wget`, `jq`, `tree`, `ufw`, `fail2ban`, `software-properties-common`, `htop`, `lsof`, e abilita UFW + Fail2ban. + - Il target `postinstall` installa: `vim`, `tmux`, `net-tools`, `wget`, `jq`, `tree`, `fail2ban`, `software-properties-common`, `htop`, `lsof`. + diff --git a/scripts/setup.sh b/scripts/setup.sh new file mode 100644 index 0000000..ce45f6e --- /dev/null +++ b/scripts/setup.sh @@ -0,0 +1,140 @@ +#!/usr/bin/env bash +set -euo pipefail + +# Questo script prepara un Ubuntu Server con utilità di base, +# installa Docker, chiede un utente da creare e lo aggiunge al gruppo docker, +# esegue i post-install tramite Make, e deploya Portainer dal repository indicato. + +TIMEZONE_DEFAULT="Europe/Rome" + +require_root() { + if [ "$(id -u)" -ne 0 ]; then + echo "[ERRORE] Esegui questo script come utente root (sudo)." >&2 + exit 1 + fi +} + +prompt_user() { + read -rp "Inserisci il nome utente da creare: " NEW_USER + if [ -z "${NEW_USER}" ]; then + echo "[ERRORE] Il nome utente non può essere vuoto." >&2 + exit 1 + fi + + read -rp "Inserisci il timezone (es. Europe/Rome) [${TIMEZONE_DEFAULT}]: " TIMEZONE + TIMEZONE=${TIMEZONE:-$TIMEZONE_DEFAULT} +} + +create_user_if_needed() { + if id -u "${NEW_USER}" >/dev/null 2>&1; then + echo "[INFO] L'utente '${NEW_USER}' esiste già, procedo." + else + echo "[INFO] Creo l'utente '${NEW_USER}'." + useradd -m -s /bin/bash "${NEW_USER}" + echo "[INFO] Imposto la password per '${NEW_USER}'." + read -srp "Inserisci la password per ${NEW_USER}: " USER_PASS + echo + echo "${NEW_USER}:${USER_PASS}" | chpasswd + fi +} + +configure_timezone() { + echo "[INFO] Configuro timezone su '${TIMEZONE}'..." + if command -v timedatectl >/dev/null 2>&1; then + timedatectl set-timezone "${TIMEZONE}" || echo "[ATTENZIONE] Impossibile impostare il timezone." + else + echo "[ATTENZIONE] 'timedatectl' non disponibile, salta configurazione timezone." + fi +} + +install_base_packages() { + echo "[INFO] Aggiorno il sistema e installo pacchetti di base..." + export DEBIAN_FRONTEND=noninteractive + apt update && apt -y full-upgrade + apt install -y git curl htop zip unzip make + apt autoremove -y --purge +} + +install_docker() { + echo "[INFO] Preparo repository Docker e installo pacchetti Docker..." + apt update + apt install -y ca-certificates curl + install -m 0755 -d /etc/apt/keyrings + curl -fsSL https://download.docker.com/linux/ubuntu/gpg -o /etc/apt/keyrings/docker.asc + chmod a+r /etc/apt/keyrings/docker.asc + + tee /etc/apt/sources.list.d/docker.sources <<'EOF' +Types: deb +URIs: https://download.docker.com/linux/ubuntu +Suites: $(. /etc/os-release && echo "${UBUNTU_CODENAME:-$VERSION_CODENAME}") +Components: stable +Signed-By: /etc/apt/keyrings/docker.asc +EOF + + apt update + apt install -y docker-ce docker-ce-cli containerd.io docker-buildx-plugin docker-compose-plugin + systemctl enable --now docker +} + +add_user_to_docker_group() { + echo "[INFO] Aggiungo l'utente '${NEW_USER}' al gruppo docker..." + groupadd -f docker + usermod -aG docker "${NEW_USER}" + echo "[INFO] Ricorda: per applicare il gruppo docker, '${NEW_USER}' deve fare logout/login." +} + +run_make_postinstall() { + echo "[INFO] Eseguo Make per installare le utilità post-installazione..." + # Esegue il Makefile nella root del progetto (una cartella sopra 'scripts') + local ROOT_DIR + ROOT_DIR="$(cd "$(dirname "${BASH_SOURCE[0]}")"/.. && pwd)" + make -C "${ROOT_DIR}" postinstall +} + +clone_and_deploy_portainer() { + echo "[INFO] Clono il repository Portainer e avvio il deploy..." + local PORTAINER_DIR + PORTAINER_DIR="/opt/portainer" + + if [ ! -d "${PORTAINER_DIR}" ]; then + git clone https://git.pyconetwork.it/francesco/portainer.git "${PORTAINER_DIR}" + else + ( + cd "${PORTAINER_DIR}" && git pull --rebase + ) + fi + + ( + cd "${PORTAINER_DIR}" + if [ -f docker-compose.yml ] || [ -f compose.yml ]; then + docker compose up -d + else + if [ -f Makefile ]; then + make deploy || true + else + echo "[ATTENZIONE] Nessun docker-compose.yml/compose.yml trovato. Verifica il repository per le istruzioni di deploy." + fi + fi + ) + + chown -R "${NEW_USER}":"${NEW_USER}" "${PORTAINER_DIR}" +} + +main() { + require_root + prompt_user + create_user_if_needed + configure_timezone + install_base_packages + install_docker + add_user_to_docker_group + run_make_postinstall + clone_and_deploy_portainer + + echo "[FATTO] Setup completato. Docker è installato e Portainer è stato deployato (se possibile)." + echo "- Utente: ${NEW_USER} (aggiunto al gruppo docker)" + echo "- Timezone: ${TIMEZONE}" + echo "- Ricorda di eseguire logout/login per applicare i gruppi." +} + +main "$@"