- docker-services: 14 generic compose templates (portainer, npm, vaultwarden, gitea, jotty, nextcloud-aio, rustdesk, audiobookshelf, calibre-web, plex, erugo, jswiki, speedtest, watchtower) - install-scripts: bash scripts for Ubuntu server bootstrap, docker, portainer, npm, backup, restore - ansible: 4 playbooks (bootstrap, deploy-services, update-services, security-hardening) + roles skeleton - hermes-install: Hermes CLI setup on macOS - macos-setup: Brewfile + osx-defaults + fish-config - home-nas-tools: metadata index for NAS projects (no binaries) - docs: architecture, security, contributing - README, LICENSE (MIT), .gitignore
179 lines
7.9 KiB
Bash
179 lines
7.9 KiB
Bash
#!/usr/bin/env bash
|
||
#
|
||
# Bootstrap Ubuntu Server (22.04/24.04 LTS)
|
||
# - aktualizace systému
|
||
# - vytvoření deploy uživatele (UID 1000)
|
||
# - základní SSH hardening
|
||
# - UFW firewall
|
||
# - fail2ban
|
||
# - základní utility (curl, wget, git, vim, …)
|
||
#
|
||
# Idempotentní – můžeš spustit víckrát.
|
||
#
|
||
# Použití:
|
||
# sudo bash bootstrap-ubuntu-server.sh
|
||
#
|
||
set -euo pipefail
|
||
|
||
# Barvy
|
||
readonly RED=$'\033[0;31m'
|
||
readonly GREEN=$'\033[0;32m'
|
||
readonly YELLOW=$'\033[1;33m'
|
||
readonly BLUE=$'\033[0;34m'
|
||
readonly NC=$'\033[0m'
|
||
|
||
log() { echo -e "${BLUE}[$(date +%H:%M:%S)]${NC} $*"; }
|
||
ok() { echo -e "${GREEN}✓${NC} $*"; }
|
||
warn() { echo -e "${YELLOW}⚠${NC} $*" >&2; }
|
||
err() { echo -e "${RED}✗${NC} $*" >&2; exit 1; }
|
||
|
||
[[ $EUID -eq 0 ]] || err "Tento skript musí běžet jako root (sudo)."
|
||
|
||
DEPLOY_USER="${DEPLOY_USER:-deploy}"
|
||
DEPLOY_UID="${DEPLOY_UID:-1000}"
|
||
SSH_PORT="${SSH_PORT:-22}"
|
||
TIMEZONE="${TIMEZONE:-Europe/Prague}"
|
||
|
||
# ────────────────────────────────────────────────────────
|
||
# 1. Aktualizace systému
|
||
# ────────────────────────────────────────────────────────
|
||
log "Aktualizace systému..."
|
||
apt-get update -qq
|
||
apt-get upgrade -y -qq
|
||
apt-get dist-upgrade -y -qq
|
||
apt-get autoremove -y -qq
|
||
ok "Systém aktualizován"
|
||
|
||
# ────────────────────────────────────────────────────────
|
||
# 2. Základní utility
|
||
# ────────────────────────────────────────────────────────
|
||
log "Instalace základních utilit..."
|
||
apt-get install -y -qq \
|
||
curl wget git vim nano htop \
|
||
ca-certificates gnupg lsb-release \
|
||
software-properties-common apt-transport-https \
|
||
ufw fail2ban \
|
||
bash-completion
|
||
ok "Utility nainstalovány"
|
||
|
||
# ────────────────────────────────────────────────────────
|
||
# 3. Timezone
|
||
# ────────────────────────────────────────────────────────
|
||
log "Nastavuji timezone: $TIMEZONE"
|
||
timedatectl set-timezone "$TIMEZONE"
|
||
ok "Timezone: $(timedatectl show -p Timezone --value)"
|
||
|
||
# ────────────────────────────────────────────────────────
|
||
# 4. Deploy uživatel (UID 1000)
|
||
# ────────────────────────────────────────────────────────
|
||
if id "$DEPLOY_USER" &>/dev/null; then
|
||
ok "Uživatel $DEPLOY_USER existuje"
|
||
else
|
||
log "Vytvářím uživatele $DEPLOY_USER (UID $DEPLOY_UID)..."
|
||
adduser --uid "$DEPLOY_UID" --gecos "" --disabled-password --shell /bin/bash "$DEPLOY_USER"
|
||
passwd -d "$DEPLOY_USER" # bez hesla (key-based auth)
|
||
mkdir -p /home/"$DEPLOY_USER"/.ssh
|
||
chmod 700 /home/"$DEPLOY_USER"/.ssh
|
||
# Přidání authorized_keys během deploymentu – zde necháme prázdné
|
||
touch /home/"$DEPLOY_USER"/.ssh/authorized_keys
|
||
chmod 600 /home/"$DEPLOY_USER"/.ssh/authorized_keys
|
||
chown -R "$DEPLOY_USER":"$DEPLOY_USER" /home/"$DEPLOY_USER"/.ssh
|
||
ok "Uživatel $DEPLOY_USER vytvořen"
|
||
fi
|
||
|
||
# Přidání do sudo bez hesla (volitelné, bezpečnostní)
|
||
if ! grep -q "^$DEPLOY_USER.*NOPASSWD" /etc/sudoers.d/"$DEPLOY_USER" 2>/dev/null; then
|
||
echo "$DEPLOY_USER ALL=(ALL) NOPASSWD:ALL" > /etc/sudoers.d/"$DEPLOY_USER"
|
||
chmod 440 /etc/sudoers.d/"$DEPLOY_USER"
|
||
ok "$DEPLOY_USER přidán do sudoers (NOPASSWD)"
|
||
fi
|
||
|
||
# ────────────────────────────────────────────────────────
|
||
# 5. SSH hardening
|
||
# ────────────────────────────────────────────────────────
|
||
log "SSH hardening..."
|
||
SSHD_CONFIG="/etc/ssh/sshd_config"
|
||
cp "$SSHD_CONFIG" "$SSHD_CONFIG.bak.$(date +%Y%m%d)" 2>/dev/null || true
|
||
|
||
# Nastavit port
|
||
sed -i "s/^#\?Port .*/Port $SSH_PORT/" "$SSHD_CONFIG"
|
||
# Zakázat root login
|
||
sed -i 's/^#\?PermitRootLogin .*/PermitRootLogin no/' "$SSHD_CONFIG"
|
||
# Zakázat password auth (jen klíče)
|
||
sed -i 's/^#\?PasswordAuthentication .*/PasswordAuthentication no/' "$SSHD_CONFIG"
|
||
# X11 forwarding vypnout
|
||
sed -i 's/^#\?X11Forwarding .*/X11Forwarding no/' "$SSHD_CONFIG"
|
||
# ClientAliveInterval
|
||
sed -i 's/^#\?ClientAliveInterval .*/ClientAliveInterval 300/' "$SSHD_CONFIG"
|
||
sed -i 's/^#\?ClientAliveCountMax .*/ClientAliveCountMax 2/' "$SSHD_CONFIG"
|
||
|
||
# Validace configu
|
||
sshd -t && systemctl restart ssh
|
||
ok "SSH nakonfigurován (port $SSH_PORT, root login zakázán)"
|
||
|
||
# ────────────────────────────────────────────────────────
|
||
# 6. UFW firewall
|
||
# ────────────────────────────────────────────────────────
|
||
log "Konfigurace UFW..."
|
||
ufw --force reset
|
||
ufw default deny incoming
|
||
ufw default allow outgoing
|
||
ufw allow "$SSH_PORT"/tcp comment "SSH"
|
||
# Služby (zakomentuj co nepoužíváš)
|
||
ufw allow 80/tcp comment "HTTP"
|
||
ufw allow 443/tcp comment "HTTPS"
|
||
# Docker swarm (volitelně)
|
||
# ufw allow 2377/tcp comment "Docker swarm"
|
||
# ufw allow 7946/tcp comment "Docker swarm gossip"
|
||
# ufw allow 7946/udp comment "Docker swarm gossip"
|
||
# ufw allow 4789/udp comment "Docker overlay"
|
||
# SSH z home (volitelně)
|
||
# ufw allow from 192.168.0.0/24 to any port $SSH_PORT proto tcp
|
||
|
||
ufw --force enable
|
||
ok "UFW aktivní, SSH povoleno"
|
||
|
||
# ────────────────────────────────────────────────────────
|
||
# 7. Fail2ban
|
||
# ────────────────────────────────────────────────────────
|
||
log "Konfigurace fail2ban..."
|
||
cat > /etc/fail2ban/jail.local <<EOF
|
||
[DEFAULT]
|
||
bantime = 1h
|
||
findtime = 10m
|
||
maxretry = 5
|
||
|
||
[sshd]
|
||
enabled = true
|
||
port = $SSH_PORT
|
||
filter = sshd
|
||
logpath = /var/log/auth.log
|
||
maxretry = 3
|
||
EOF
|
||
systemctl enable --now fail2ban
|
||
systemctl restart fail2ban
|
||
ok "Fail2ban aktivní"
|
||
|
||
# ────────────────────────────────────────────────────────
|
||
# 8. Čas a DNS
|
||
# ────────────────────────────────────────────────────────
|
||
log "Konfigurace timesyncd..."
|
||
apt-get install -y -qq systemd-timesyncd
|
||
sed -i 's/^#NTP=.*/NTP=0.pool.ntp.org 1.pool.ntp.org/' /etc/systemd/timesyncd.conf
|
||
systemctl restart systemd-timesyncd
|
||
ok "Time sync aktivní"
|
||
|
||
# ────────────────────────────────────────────────────────
|
||
# Hotovo
|
||
# ────────────────────────────────────────────────────────
|
||
echo
|
||
ok "Bootstrap dokončen!"
|
||
echo
|
||
echo "📋 Další kroky:"
|
||
echo " 1. sudo bash install-docker.sh"
|
||
echo " 2. sudo bash install-portainer.sh"
|
||
echo " 3. sudo bash install-nginx-proxy.sh"
|
||
echo " 4. Přidej svůj SSH klíč: sudo -u $DEPLOY_USER bash -c 'echo \"<tvuj-klic>\" >> ~/.ssh/authorized_keys'"
|
||
echo
|
||
echo "⚠️ Před odhlášením se ujisti, že máš funkční SSH přístup jako $DEPLOY_USER!"
|