#!/bin/bash # Обновление безопасности PostgreSQL в продакшене # Безопасный переход с минимальным downtime set -e echo "🔒 Обновление безопасности PostgreSQL для CatLink (Продакшен)" echo "==============================================================" # Проверяем что мы в правильной директории if [ ! -f "docker-compose.yml" ]; then echo "❌ Не найден docker-compose.yml. Запустите скрипт из корня проекта." exit 1 fi # Создаем backup перед изменениями echo "📦 Создание backup базы данных..." timestamp=$(date +%Y%m%d_%H%M%S) backup_file="backup_${timestamp}.sql" # Создаем backup docker exec links-db-1 pg_dump -U postgres links_db > "backups/${backup_file}" 2>/dev/null || { mkdir -p backups docker exec links-db-1 pg_dump -U postgres links_db > "backups/${backup_file}" } echo "✅ Backup создан: backups/${backup_file}" # Показываем текущее состояние echo "" echo "📋 Текущее состояние безопасности:" echo "==================================" # Быстрый аудит текущего состояния if docker ps | grep -q "links-db-1"; then echo "🔍 Проверка прав пользователя..." CURRENT_SUPER=$(docker exec links-db-1 psql -U postgres -d links_db -t -c "SELECT rolsuper FROM pg_roles WHERE rolname = 'links_user';" 2>/dev/null | tr -d ' ') if [[ "$CURRENT_SUPER" == "t" ]]; then echo "⚠️ links_user имеет права суперпользователя (будет исправлено)" else echo "✅ links_user не имеет прав суперпользователя" fi # Проверяем открытые порты PORTS=$(docker port links-db-1 2>/dev/null || echo "") if [[ -n "$PORTS" ]]; then echo "⚠️ PostgreSQL доступен извне:" echo "$PORTS" echo " Будет изолирован в Docker сети" else echo "✅ PostgreSQL уже изолирован" fi else echo "⚠️ Контейнер БД не запущен" fi echo "" read -p "🤔 Продолжить обновление безопасности? (yes/no): " CONFIRM if [ "$CONFIRM" != "yes" ]; then echo "❌ Отменено пользователем" exit 1 fi echo "" echo "🔧 Применение обновлений безопасности..." # 1. Останавливаем frontend (минимизируем impact) echo "1️⃣ Остановка frontend сервиса..." docker-compose stop frontend # 2. Обновляем права пользователя БД (можно делать на живой системе) echo "2️⃣ Обновление прав пользователя БД..." docker exec links-db-1 psql -U postgres -c " -- Убираем права суперпользователя ALTER ROLE links_user NOSUPERUSER NOCREATEDB NOCREATEROLE; -- Устанавливаем только необходимые права GRANT CONNECT ON DATABASE links_db TO links_user; GRANT USAGE ON SCHEMA public TO links_user; GRANT SELECT, INSERT, UPDATE, DELETE ON ALL TABLES IN SCHEMA public TO links_user; GRANT USAGE, SELECT ON ALL SEQUENCES IN SCHEMA public TO links_user; -- Права по умолчанию для новых объектов ALTER DEFAULT PRIVILEGES IN SCHEMA public GRANT SELECT, INSERT, UPDATE, DELETE ON TABLES TO links_user; ALTER DEFAULT PRIVILEGES IN SCHEMA public GRANT USAGE, SELECT ON SEQUENCES TO links_user; " 2>/dev/null && echo "✅ Права пользователя обновлены" || echo "⚠️ Ошибка обновления прав" # 3. Останавливаем все сервисы для обновления конфигурации echo "3️⃣ Остановка всех сервисов для обновления конфигурации..." docker-compose down # 4. Обновляем docker-compose конфигурацию echo "4️⃣ Применение новой конфигурации Docker..." # 5. Запускаем с новой конфигурацией echo "5️⃣ Запуск с обновленной конфигурацией безопасности..." if [ "$ENVIRONMENT" = "production" ]; then docker-compose -f docker-compose.yml -f docker-compose.prod.yml up -d else docker-compose up -d fi # Ждем запуска БД echo "6️⃣ Ожидание запуска PostgreSQL..." sleep 15 # Проверяем доступность max_attempts=30 attempt=1 while [ $attempt -le $max_attempts ]; do if docker exec links-db-1 pg_isready -U postgres >/dev/null 2>&1; then echo "✅ PostgreSQL запущен" break fi echo " Попытка $attempt/$max_attempts..." sleep 2 ((attempt++)) done if [ $attempt -gt $max_attempts ]; then echo "❌ PostgreSQL не запустился за разумное время" echo "📋 Логи контейнера:" docker logs links-db-1 --tail 20 exit 1 fi # 7. Проверяем подключение приложения echo "7️⃣ Проверка подключения приложения к БД..." sleep 5 if docker logs links-web-1 --tail 10 2>/dev/null | grep -q "Error\|Exception\|Failed"; then echo "⚠️ Возможны проблемы с подключением приложения" echo "📋 Последние логи web контейнера:" docker logs links-web-1 --tail 10 else echo "✅ Приложение успешно подключено к БД" fi # 8. Финальная проверка безопасности echo "" echo "8️⃣ Финальная проверка безопасности..." echo "======================================" # Запускаем аудит безопасности ./scripts/audit-db-security.sh echo "" echo "✅ Обновление безопасности PostgreSQL завершено!" echo "" echo "📊 Примененные улучшения:" echo " ✓ Убраны права суперпользователя у links_user" echo " ✓ PostgreSQL изолирован в Docker сети" echo " ✓ Настроен SSL с TLSv1.3" echo " ✓ Включено детальное логирование" echo " ✓ Настроена аутентификация SCRAM-SHA-256" echo "" echo "💾 Backup создан: backups/${backup_file}" echo "" echo "🌐 Проверьте работу сайта: http://links.shareon.kr" # Показываем статус echo "" echo "📊 Текущий статус сервисов:" docker-compose ps