#!/bin/bash
# ========== prepare_vm.sh ==========
# Модуль подготовки ВМ: создание пользователей, настройка SSH, UFW, Docker, Node Exporter
# SSH-ключи встроены в скрипт

# ---------- ЛОГИРОВАНИЕ ----------
LOG_FILE="${LOG_FILE:-/var/log/prepare_vm_$(date +%Y%m%d_%H%M%S).log}"
exec > >(tee -a "$LOG_FILE") 2>&1

log_info() {
    echo "ℹ️  [INFO] $(date '+%Y-%m-%d %H:%M:%S') - $1"
}
log_success() {
    echo "✅ [SUCCESS] $(date '+%Y-%m-%d %H:%M:%S') - $1"
}
log_error() {
    echo "❌ [ERROR] $(date '+%Y-%m-%d %H:%M:%S') - $1" >&2
}
log_step() {
    echo "📋 [STEP] $(date '+%Y-%m-%d %H:%M:%S') - $1"
    echo "=================================================="
}

# ---------- ПРОВЕРКА ROOT ----------
if [[ $EUID -ne 0 ]]; then
    log_error "Модуль prepare_vm.sh должен запускаться с правами root"
    exit 1
fi

# ---------- ПРОВЕРКА ПЕРЕМЕННЫХ ИЗ ГЛАВНОГО СКРИПТА ----------
: "${FULL_DOMAIN:?Переменная FULL_DOMAIN не установлена}"
: "${SSH_PORT:?Переменная SSH_PORT не установлена}"
: "${USER1:?Переменная USER1 не установлена}"
: "${USER2:?Переменная USER2 не установлена}"
: "${USER4:?Переменная USER4 не установлена}"

log_info "Начало подготовки ВМ с параметрами:"
log_info "  FULL_DOMAIN = $FULL_DOMAIN"
log_info "  SSH_PORT    = $SSH_PORT"
log_info "  USER1       = $USER1"
log_info "  USER2       = $USER2"
log_info "  USER4       = $USER4"

# ---------- SSH КЛЮЧИ (ВСТРОЕНЫ) ----------
SSH_KEY1="ssh-rsa AAAAB3NzaC1yc2EAAAADAQABAAABgQCx3j0W/2hWwq0ePMRjRrCybkOvPT8AbcsuEN22fQNmLQ0db+yFtJqW7pvL/Hm+joKjH95j8gHcxLIs792vZCcjO48QqMczM1kYNsTxy98FWkl/b7mPSkVpkMzofiYUsyLSUEBRuW0Qpk6re8uW6hY86LHsoZ7bbmP7CqC4topMB7B4budiJQDheUAsLZANVGdg1wiAzHnxLWDUEEsTIvePNIRflblzmAUGzHVr591U4pfeLqmqj60UyQa6cbxPYQ/6TO0iNEaOVdqWsglBaQwen2EDVY3SNlAXn/1LcSm44SE2a/m1dIXmuT971P0sZHsQcuxPl+DmgwO9x6Xd84LjFRwgC57h03wAGOuz0iBB19KLK97fZ2Em/pKKOmGB2+s08A/yADa6Vzq23Bcug3WdPhuqUGoSvl/pp5itwL9MOjy11r8Qwl46S7ObQkCGDlrggtJNjSCfInnE8zYmEX/Oys+bt7f/2VPlR10/zUQiVVrp6xBJ+cf5afryu5g0qnU= crazygnome@crazygnomes-iMac-Pro.local"

SSH_KEY2="ssh-ed25519 AAAAC3NzaC1lZDI1NTE5AAAAIKqzri0qHJ7vw5gft3oLDzrXaijGI1iCpmCkCN0BO6Gm sevgb5\popovi@41013401425"

SSH_KEY4="ssh-rsa AAAAB3NzaC1yc2EAAAADAQABAAACAQC+oljEUej0ud2w/OCTznVSfTPr/NqHC9ayCncf8zqrCxxM+5RSbB7bAIDighUt7orUId7e7voVpf2mreLiIgpHwi4tnZLU6ecZnn14yyAuCnmRGWJR8gUDJbnc2prOobzCOlc80F4ag46numBXOUrc9Zi/THOmlph0Uu6GMGp0mg+0ia0AphrZYRAWNNiOCdqKpccZbKQCGAxI1SUd+I0z7QRx2S2ZNq6RNXhZKspBQV/RtbZoYjzZ+kqBqaMHtZf3TnV96ACY4A9UB8GndwLl0nXf7KVvQgUBAzUGiLCnh6168jFZevi1/GskoTij9quUjjVs/DVVAZYtDp86hDTiWPUf6L1nhwE9ARvIw/MQGWtdk/sxrH8nInGcg2+Kz0DRJi9RzdS5Yh/S1GWaS0rJUtKZgThNDq1rG0CupFt77+MGGCOoOIMVzCQ+soVaRIHEMyXcAlMLPZcSfGfIW1U9CVoN8A0lnrU5rrph78KRi3R6saYYXPRBenx1qxN1cUiR73KrHsUhYulfHDikKE46RRQ0kYw78i7YcPjugE0d0CEKO+Zis/RQNYFHYQwKP8m7Jj835Fn1IFKmvQX3VEhNtroZMjIEvz7gT09y8m/X6BHu1jWxDyX2ta56c7s8c+Q39qof9+HFzQtB+RYBZDkGDvmx0B7vyWdZVqePsldKDQ== upgrade@freesurfpanel.4rp.su"

log_success "SSH-ключи загружены"

# ---------- ФУНКЦИИ ДЛЯ НАСТРОЙКИ ----------
backup_config() {
    local file="$1"
    local backup="${file}.backup.$(date +%Y%m%d_%H%M%S)"
    if [ -f "$file" ]; then
        cp "$file" "$backup"
        log_info "Бэкап создан: $backup"
    fi
}

create_user() {
    local USERNAME="$1"
    local SSH_KEY="$2"

    if ! id "$USERNAME" &>/dev/null; then
        useradd -m -s /bin/bash "$USERNAME"
        log_success "Пользователь $USERNAME создан"
    else
        log_info "Пользователь $USERNAME уже существует"
    fi

    usermod -aG sudo "$USERNAME"

    HOME_DIR=$(eval echo "~$USERNAME")
    mkdir -p "$HOME_DIR/.ssh"
    echo "$SSH_KEY" > "$HOME_DIR/.ssh/authorized_keys"

    chmod 700 "$HOME_DIR/.ssh"
    chmod 600 "$HOME_DIR/.ssh/authorized_keys"
    chown -R "$USERNAME:$USERNAME" "$HOME_DIR/.ssh"

    log_success "SSH ключ добавлен, sudo включён для $USERNAME"
}

set_sshd_option() {
    local KEY="$1"
    local VALUE="$2"
    if grep -qE "^[#]*\s*$KEY" "$SSHD_CONFIG"; then
        sed -i "s|^[#]*\s*$KEY.*|$KEY $VALUE|" "$SSHD_CONFIG"
    else
        echo "$KEY $VALUE" >> "$SSHD_CONFIG"
    fi
}

# ---------- ИЗМЕНЕНИЕ HOSTNAME ----------
log_step "Изменение hostname на $FULL_DOMAIN"
hostnamectl set-hostname "$FULL_DOMAIN"
if ! grep -q "$FULL_DOMAIN" /etc/hosts; then
    echo "127.0.0.1   $FULL_DOMAIN" >> /etc/hosts
    log_info "Добавлена запись в /etc/hosts"
fi
log_success "Hostname изменён"

# ---------- СОЗДАНИЕ ПОЛЬЗОВАТЕЛЕЙ ----------
log_step "Создание пользователей"
create_user "$USER1" "$SSH_KEY1"
create_user "$USER2" "$SSH_KEY2"
create_user "$USER4" "$SSH_KEY4"

# ---------- НАСТРОЙКА SUDO БЕЗ ПАРОЛЯ ----------
log_step "Настройка sudo без пароля"
backup_config "/etc/sudoers"
SUDOERS_FILE="/etc/sudoers.d/custom_users"
echo "$USER1 ALL=(ALL) NOPASSWD:ALL" > "$SUDOERS_FILE"
echo "$USER2 ALL=(ALL) NOPASSWD:ALL" >> "$SUDOERS_FILE"
echo "$USER4 ALL=(ALL) NOPASSWD:ALL" >> "$SUDOERS_FILE"
chmod 440 "$SUDOERS_FILE"
if visudo -cf "$SUDOERS_FILE" >/dev/null; then
    log_success "sudo без пароля настроен"
else
    log_error "Ошибка в конфигурации sudoers"
    exit 1
fi

# ---------- НАСТРОЙКА SSH ----------
log_step "Настройка SSH"
SSHD_CONFIG="/etc/ssh/sshd_config"
backup_config "$SSHD_CONFIG"

set_sshd_option "Port" "$SSH_PORT"
set_sshd_option "PermitRootLogin" "no"
set_sshd_option "PasswordAuthentication" "no"
set_sshd_option "ChallengeResponseAuthentication" "no"
set_sshd_option "PubkeyAuthentication" "yes"
set_sshd_option "UsePAM" "yes"
set_sshd_option "AllowUsers" "$USER1 $USER2 $USER4"
set_sshd_option "ClientAliveInterval" "300"
set_sshd_option "ClientAliveCountMax" "2"
set_sshd_option "MaxAuthTries" "3"
set_sshd_option "LoginGraceTime" "60"

# ---------- ОЖИДАНИЕ APT ----------
log_step "Проверка блокировки apt/dpkg"
while fuser /var/lib/dpkg/lock-frontend >/dev/null 2>&1 || fuser /var/lib/apt/lists/lock >/dev/null 2>&1; do
    log_info "apt/dpkg заблокирован. Ждём 5 секунд..."
    sleep 5
done
log_success "Блокировка снята"

# ---------- УСТАНОВКА WARP ----------
curl -fsSL https://pkg.cloudflareclient.com/pubkey.gpg | sudo gpg --yes --dearmor --output /usr/share/keyrings/cloudflare-warp-archive-keyring.gpg && echo "deb [signed-by=/usr/share/keyrings/cloudflare-warp-archive-keyring.gpg] https://pkg.cloudflareclient.com/ $(lsb_release -cs) main" | sudo tee /etc/apt/sources.list.d/cloudflare-client.list && sudo apt-get update && sudo apt-get install cloudflare-warp -y && warp-cli registration new && warp-cli mode proxy && warp-cli connect

# ---------- УСТАНОВКА БАЗОВЫХ ПАКЕТОВ ----------
log_step "Установка базовых пакетов"
DEBIAN_FRONTEND=noninteractive apt-get update && \
apt-get install -y \
    ufw \
    cron \
    fail2ban \
    htop \
    net-tools \
    curl \
    wget \
    git \
    ncdu \
    vim \
    nano \
    tree \
    unzip \
    logrotate \
    socat \
    nload \
    apt-transport-https \
    ca-certificates \
    gnupg \
    lsb-release \
    software-properties-common \
    jq \
    dnsutils
log_success "Базовые пакеты установлены"

# ---------- НАСТРОЙКА FAIL2BAN ----------
log_step "Настройка Fail2Ban"
systemctl enable fail2ban
systemctl start fail2ban

cat > /etc/fail2ban/jail.local << EOF
[sshd]
enabled = true
port = $SSH_PORT
filter = sshd
logpath = /var/log/auth.log
maxretry = 5
bantime = 3600
findtime = 600

[sshd-ddos]
enabled = true
port = $SSH_PORT
filter = sshd-ddos
logpath = /var/log/auth.log
maxretry = 10
bantime = 86400
EOF

systemctl restart fail2ban
log_success "Fail2Ban настроен"

# ---------- НАСТРОЙКА UFW ----------
log_step "Настройка UFW"
echo y | ufw reset
sed -i 's/^IPV6=.*/IPV6=no/' /etc/default/ufw

ufw limit "$SSH_PORT"/tcp
ufw allow 80/tcp
ufw allow 443/tcp

# Специальные правила
ufw allow from 185.71.81.102 to any port 9100
ufw allow from 31.76.98.39 to any port 9873
ufw allow from 147.45.210.11 to any port 9873

# Блокировка ICMP
sed -i '/^-A ufw-before-.* -p icmp --icmp-type \(destination-unreachable\|time-exceeded\|parameter-problem\|echo-request\) -j ACCEPT/s/^/# /' /etc/ufw/before.rules
sed -i "/^# don't delete the 'COMMIT' line or these rules won't be processed/i \
# ok icmp codes\n\
-A ufw-before-input -p icmp --icmp-type destination-unreachable -j DROP\n\
-A ufw-before-input -p icmp --icmp-type source-quench -j DROP\n\
-A ufw-before-input -p icmp --icmp-type time-exceeded -j DROP\n\
-A ufw-before-input -p icmp --icmp-type parameter-problem -j DROP\n\
-A ufw-before-input -p icmp --icmp-type echo-request -j DROP\n" /etc/ufw/before.rules

ufw default deny incoming
ufw default allow outgoing
ufw --force enable
ufw status verbose
log_success "UFW настроен"

# ---------- УСТАНОВКА DOCKER ----------
log_step "Установка последней версии Docker"

for pkg in docker docker-engine docker.io containerd runc; do
    if dpkg -l | grep -q "^ii.*$pkg"; then
        apt-get remove -y $pkg 2>/dev/null || true
        log_info "Удалён старый пакет: $pkg"
    fi
done

apt-get update -y
apt-get install -y ca-certificates curl gnupg lsb-release

mkdir -p /etc/apt/keyrings
curl -fsSL https://download.docker.com/linux/ubuntu/gpg | gpg --dearmor -o /etc/apt/keyrings/docker.gpg

echo \
  "deb [arch=$(dpkg --print-architecture) signed-by=/etc/apt/keyrings/docker.gpg] https://download.docker.com/linux/ubuntu \
  $(lsb_release -cs) stable" | tee /etc/apt/sources.list.d/docker.list > /dev/null

apt-get update -y
apt-get install -y docker-ce docker-ce-cli containerd.io docker-compose-plugin

usermod -aG docker "$USER1"
usermod -aG docker "$USER2"

mkdir -p /etc/docker
cat > /etc/docker/daemon.json << EOF
{
  "log-driver": "json-file",
  "log-opts": {
    "max-size": "10m",
    "max-file": "3"
  },
  "iptables": true,
  "ip-forward": true,
  "userland-proxy": false,
  "live-restore": true
}
EOF

systemctl restart docker
systemctl enable docker
log_success "Docker установлен"

# ---------- УСТАНОВКА NODE EXPORTER ----------
log_step "Установка Prometheus Node Exporter"

NODE_EXPORTER_VERSION="1.7.0"
wget -q "https://github.com/prometheus/node_exporter/releases/download/v${NODE_EXPORTER_VERSION}/node_exporter-${NODE_EXPORTER_VERSION}.linux-amd64.tar.gz" -O /tmp/node_exporter.tar.gz
tar xvf /tmp/node_exporter.tar.gz -C /tmp/
cp /tmp/node_exporter-*/node_exporter /usr/local/bin/

if ! id node_exporter &>/dev/null; then
    useradd -rs /bin/false node_exporter
    log_info "Пользователь node_exporter создан"
fi

cat > /etc/systemd/system/node-exporter.service << EOF
[Unit]
Description=Node Exporter
After=network.target

[Service]
User=node_exporter
Group=node_exporter
Type=simple
ExecStart=/usr/local/bin/node_exporter
Restart=on-failure
RestartSec=5s

[Install]
WantedBy=multi-user.target
EOF

systemctl daemon-reload
systemctl enable node-exporter
systemctl start node-exporter
log_success "Node Exporter установлен"

log_success "Модуль prepare_vm.sh выполнен"
