1556 lines
58 KiB
Bash
1556 lines
58 KiB
Bash
#!/bin/bash
|
||
clear
|
||
set -e
|
||
|
||
# Переменные
|
||
UNINSTALL=false
|
||
REINSTALL=false
|
||
SCRIPT_DIR="$(cd "$(dirname "${BASH_SOURCE[0]}")" && pwd)"
|
||
LOG_FILE="/tmp/altcor_install_$(date +%Y%m%d_%H%M%S).log"
|
||
|
||
# Цвета для вывода
|
||
RED='\033[0;31m'
|
||
GREEN='\033[0;32m'
|
||
YELLOW='\033[1;33m'
|
||
BLUE='\033[0;34m'
|
||
CYAN='\033[0;36m'
|
||
NC='\033[0m'
|
||
|
||
# Обработка параметров командной строки
|
||
while getopts ":ur" opt; do
|
||
case $opt in
|
||
u) UNINSTALL=true ;;
|
||
r) REINSTALL=true ;;
|
||
\?)
|
||
echo -e "${RED}[Ошибка]${NC} Неизвестный параметр: -$OPTARG" >&2
|
||
echo "Использование: $0 [-u] [-r]"
|
||
echo " -u Полное удаление"
|
||
echo " -r Переустановка (удаление + установка)"
|
||
exit 1
|
||
;;
|
||
esac
|
||
done
|
||
|
||
# Функции логирования
|
||
log_to_file() { echo "$(date '+%Y-%m-%d %H:%M:%S') - $1" >> "$LOG_FILE"; }
|
||
log_success() { echo -e "${GREEN}[Успех]${NC} $1"; log_to_file "SUCCESS: $1"; }
|
||
log_error() { echo -e "${RED}[Ошибка]${NC} $1"; log_to_file "ERROR: $1"; }
|
||
log_info() { echo -e "${BLUE}[Инфо]${NC} $1"; log_to_file "INFO: $1"; }
|
||
log_warning() { echo -e "${YELLOW}[Предупреждение]${NC} $1"; log_to_file "WARNING: $1"; }
|
||
log_step() { echo -e "${CYAN}[Шаг]${NC} $1"; log_to_file "STEP: $1"; }
|
||
|
||
# Генерация безопасного пароля
|
||
generate_password() {
|
||
if command -v openssl >/dev/null 2>&1; then
|
||
openssl rand -base64 32 | tr -d "=+/" | cut -c1-16
|
||
else
|
||
# Fallback для систем без openssl
|
||
head /dev/urandom | tr -dc A-Za-z0-9 | head -c 16
|
||
fi
|
||
}
|
||
|
||
# Проверка прав администратора
|
||
check_root() {
|
||
if [[ $EUID -ne 0 ]]; then
|
||
log_error "Запустите этот скрипт с правами администратора (sudo)."
|
||
exit 1
|
||
fi
|
||
}
|
||
|
||
# Определение дистрибутива
|
||
detect_distro() {
|
||
if [ -f /etc/os-release ]; then
|
||
source /etc/os-release
|
||
DISTRO="$ID"
|
||
FAMILY="$ID_LIKE"
|
||
VERSION_ID="${VERSION_ID}"
|
||
else
|
||
log_error "Не удалось определить дистрибутив."
|
||
exit 1
|
||
fi
|
||
|
||
if echo "$DISTRO $FAMILY" | grep -qi "debian\|ubuntu"; then
|
||
PKG_MANAGER="apt"
|
||
DISTRO_FAMILY="debian"
|
||
WEBSERVER_SERVICE="apache2"
|
||
WEBROOT="/var/www/html"
|
||
APACHE_CONF="/etc/apache2/sites-available/000-default.conf"
|
||
WEBSERVER_USER="www-data"
|
||
PHP_INI_PATH="/etc/php/8.3/apache2/php.ini"
|
||
DB_SOCKET="/var/run/mysqld/mysqld.sock"
|
||
elif echo "$DISTRO $FAMILY" | grep -qi "rhel\|centos\|fedora\|rocky\|almalinux"; then
|
||
DISTRO_FAMILY="rhel"
|
||
WEBSERVER_SERVICE="httpd"
|
||
WEBROOT="/var/www/html"
|
||
APACHE_CONF="/etc/httpd/conf.d/altcor.conf"
|
||
WEBSERVER_USER="apache"
|
||
DB_SOCKET="/var/lib/mysql/mysql.sock"
|
||
|
||
if command -v dnf >/dev/null 2>&1; then
|
||
PKG_MANAGER="dnf"
|
||
else
|
||
PKG_MANAGER="yum"
|
||
fi
|
||
|
||
# Определяем путь к PHP INI для RHEL семейства
|
||
if [ -f "/etc/opt/remi/php83/php.ini" ]; then
|
||
PHP_INI_PATH="/etc/opt/remi/php83/php.ini"
|
||
PHP_FPM_CONF="/etc/opt/remi/php83/php-fpm.d/www.conf"
|
||
PHP_FPM_SERVICE="php83-php-fpm"
|
||
SOCKET_PATH="/var/opt/remi/php83/run/php-fpm/www.sock"
|
||
elif [ -f "/etc/php.ini" ]; then
|
||
PHP_INI_PATH="/etc/php.ini"
|
||
PHP_FPM_CONF="/etc/php-fpm.d/www.conf"
|
||
PHP_FPM_SERVICE="php-fpm"
|
||
SOCKET_PATH="/run/php-fpm/www.sock"
|
||
fi
|
||
else
|
||
log_error "Дистрибутив '$DISTRO' не поддерживается."
|
||
log_info "Поддерживаются: Debian, Ubuntu, CentOS, RHEL, Fedora, Rocky Linux, AlmaLinux"
|
||
exit 1
|
||
fi
|
||
|
||
log_info "Обнаружен дистрибутив: $DISTRO ($DISTRO_FAMILY)"
|
||
}
|
||
|
||
# Функция для безопасного выполнения команд
|
||
safe_execute() {
|
||
local description="$1"
|
||
shift
|
||
log_info "$description..."
|
||
|
||
if "$@" >/dev/null 2>&1; then
|
||
log_success "$description - выполнено"
|
||
return 0
|
||
else
|
||
log_error "$description - не удалось выполнить"
|
||
log_to_file "FAILED COMMAND: $*"
|
||
return 1
|
||
fi
|
||
}
|
||
|
||
# Проверка статуса компонента
|
||
check_component_status() {
|
||
local component=$1
|
||
local command_check=$2
|
||
local service_check=$3
|
||
|
||
if command -v "$command_check" >/dev/null 2>&1; then
|
||
if [[ -n "$service_check" ]]; then
|
||
if systemctl is-active --quiet "$service_check" 2>/dev/null; then
|
||
return 0 # Установлен и работает
|
||
else
|
||
return 1 # Установлен, но не работает
|
||
fi
|
||
else
|
||
return 0 # Установлен
|
||
fi
|
||
else
|
||
return 2 # Не установлен
|
||
fi
|
||
}
|
||
|
||
# Проверка существующей установки
|
||
check_existing_installation() {
|
||
log_step "Проверка существующей установки..."
|
||
|
||
local apache_status php_status mariadb_status redis_status
|
||
local need_reinstall=false
|
||
|
||
# Проверка Apache
|
||
log_info "Проверка Apache..."
|
||
if [ "$DISTRO_FAMILY" = "debian" ]; then
|
||
check_component_status "Apache" "apache2" "apache2"
|
||
apache_status=$?
|
||
else
|
||
check_component_status "Apache" "httpd" "httpd"
|
||
apache_status=$?
|
||
fi
|
||
|
||
# Проверка PHP
|
||
log_info "Проверка PHP..."
|
||
check_component_status "PHP" "php" ""
|
||
php_status=$?
|
||
|
||
# Проверка MariaDB
|
||
log_info "Проверка MariaDB..."
|
||
check_component_status "MariaDB" "mysql" "mariadb"
|
||
mariadb_status=$?
|
||
|
||
# Проверка Redis
|
||
log_info "Проверка Redis..."
|
||
if systemctl is-active --quiet redis-server 2>/dev/null || systemctl is-active --quiet redis 2>/dev/null; then
|
||
redis_status=0
|
||
elif command -v redis-cli >/dev/null 2>&1; then
|
||
redis_status=1
|
||
else
|
||
redis_status=2
|
||
fi
|
||
|
||
# Вывод статуса компонентов
|
||
echo ""
|
||
display_component_status "Apache" $apache_status
|
||
display_php_status $php_status
|
||
display_component_status "MariaDB" $mariadb_status
|
||
display_component_status "Redis" $redis_status
|
||
|
||
# Проверка конфигурации БД
|
||
if [ -f "/var/www/html/db_config.php" ]; then
|
||
echo -e "Конфигурация БД: ${GREEN}Найдена${NC}"
|
||
else
|
||
echo -e "Конфигурация БД: ${RED}Не найдена${NC}"
|
||
need_reinstall=true
|
||
fi
|
||
|
||
echo ""
|
||
|
||
# Определяем необходимость переустановки
|
||
if [[ $apache_status -ne 0 ]] || [[ $php_status -ne 0 ]] || [[ $mariadb_status -ne 0 ]]; then
|
||
need_reinstall=true
|
||
fi
|
||
|
||
return $([ "$need_reinstall" = "true" ] && echo 1 || echo 0)
|
||
}
|
||
|
||
# Отображение статуса компонента
|
||
display_component_status() {
|
||
local name=$1
|
||
local status=$2
|
||
|
||
case $status in
|
||
0) echo -e "$name: ${GREEN}Установлен и работает${NC}" ;;
|
||
1) echo -e "$name: ${YELLOW}Установлен, но не работает${NC}" ;;
|
||
2) echo -e "$name: ${RED}Не установлен${NC}" ;;
|
||
esac
|
||
}
|
||
|
||
# Отображение статуса PHP с проверкой версии
|
||
display_php_status() {
|
||
local status=$1
|
||
|
||
case $status in
|
||
0)
|
||
local php_version=$(php -v 2>/dev/null | head -1 | cut -d' ' -f2 | cut -d'.' -f1,2 2>/dev/null || echo "неизвестно")
|
||
if [[ "$php_version" == "8.3" ]]; then
|
||
echo -e "PHP: ${GREEN}Установлен (версия $php_version)${NC}"
|
||
else
|
||
echo -e "PHP: ${YELLOW}Установлен (версия $php_version, требуется 8.3)${NC}"
|
||
return 1
|
||
fi
|
||
;;
|
||
2) echo -e "PHP: ${RED}Не установлен${NC}"; return 1 ;;
|
||
esac
|
||
return 0
|
||
}
|
||
|
||
# Полное удаление системы
|
||
full_uninstall() {
|
||
log_step "Начинаем полное удаление Altcor..."
|
||
|
||
# Остановка сервисов
|
||
log_info "Остановка сервисов..."
|
||
for service in nginx apache2 httpd php*-fpm mariadb mysql redis redis-server php83-php-fpm; do
|
||
systemctl stop "$service" 2>/dev/null || true
|
||
done
|
||
|
||
# Удаление пакетов
|
||
log_info "Удаление пакетов..."
|
||
if [ "$DISTRO_FAMILY" = "debian" ]; then
|
||
export DEBIAN_FRONTEND=noninteractive
|
||
|
||
# Подготавливаем автоматические ответы для удаления MariaDB/MySQL
|
||
for db_package in mariadb-server mysql-server; do
|
||
for version in "" "-10.3" "-10.5" "-10.6" "-10.11" "-5.7" "-8.0"; do
|
||
echo "${db_package}${version} mysql-server/remove-data-dir boolean true" | debconf-set-selections 2>/dev/null || true
|
||
done
|
||
done
|
||
|
||
safe_execute "Удаление пакетов (Debian/Ubuntu)" \
|
||
apt purge -y nginx* apache2* php* mariadb* mysql* redis*
|
||
safe_execute "Очистка неиспользуемых пакетов" apt autoremove -y
|
||
else
|
||
safe_execute "Удаление пакетов (RHEL/CentOS/Fedora)" \
|
||
$PKG_MANAGER remove -y nginx httpd php* mariadb* mysql* redis*
|
||
fi
|
||
|
||
# Удаление файлов и директорий
|
||
log_info "Удаление файлов конфигурации и данных..."
|
||
rm -rf /etc/nginx /etc/apache2 /etc/httpd /etc/php* /var/www/html/* \
|
||
/var/lib/mysql* /var/lib/redis* ~/.mysql_history /root/.mysql_history \
|
||
/root/.db_password /etc/opt/remi/php83 /opt/remi/php83 2>/dev/null || true
|
||
|
||
log_success "Полное удаление завершено."
|
||
|
||
if [ "$REINSTALL" = false ]; then
|
||
exit 0
|
||
else
|
||
log_info "Переустановка: удаление завершено, продолжаем установку..."
|
||
echo ""
|
||
fi
|
||
}
|
||
|
||
# Обновление системы и установка базовых пакетов
|
||
update_system() {
|
||
log_step "Обновление системы и установка базовых пакетов..."
|
||
|
||
if [ "$DISTRO_FAMILY" = "debian" ]; then
|
||
export DEBIAN_FRONTEND=noninteractive
|
||
safe_execute "Обновление списка пакетов" apt update -y
|
||
safe_execute "Установка базовых пакетов" \
|
||
apt install -y software-properties-common lsb-release ca-certificates \
|
||
curl wget gnupg2 apt-transport-https unzip
|
||
else
|
||
safe_execute "Обновление системы" $PKG_MANAGER update -y
|
||
safe_execute "Установка EPEL репозитория" $PKG_MANAGER install -y epel-release || true
|
||
safe_execute "Установка базовых пакетов" \
|
||
$PKG_MANAGER install -y curl wget gnupg2 unzip
|
||
fi
|
||
}
|
||
|
||
# Настройка репозиториев PHP 8.3
|
||
setup_php_repositories() {
|
||
log_step "Настройка репозиториев для PHP 8.3..."
|
||
|
||
if [ "$DISTRO_FAMILY" = "debian" ]; then
|
||
if ! apt-cache show php8.3 &>/dev/null; then
|
||
log_info "Добавление репозитория Sury для PHP 8.3..."
|
||
|
||
# Добавляем ключ GPG
|
||
if ! curl -fsSL https://packages.sury.org/php/apt.gpg | gpg --dearmor -o /usr/share/keyrings/php-archive-keyring.gpg 2>/dev/null; then
|
||
log_warning "Не удалось добавить ключ Sury, пробуем PPA..."
|
||
safe_execute "Добавление PPA ondrej/php" add-apt-repository ppa:ondrej/php -y
|
||
else
|
||
# Добавляем репозиторий Sury
|
||
CODENAME=$(lsb_release -cs)
|
||
echo "deb [signed-by=/usr/share/keyrings/php-archive-keyring.gpg] https://packages.sury.org/php/ $CODENAME main" > /etc/apt/sources.list.d/php.list
|
||
fi
|
||
|
||
safe_execute "Обновление списка пакетов после добавления репозитория PHP" apt update -y
|
||
|
||
if ! apt-cache show php8.3 &>/dev/null; then
|
||
log_error "PHP 8.3 недоступен после добавления репозиториев"
|
||
exit 1
|
||
fi
|
||
fi
|
||
log_success "Репозиторий PHP 8.3 настроен"
|
||
|
||
else
|
||
log_info "Настройка репозиториев Remi для RHEL-семейства..."
|
||
|
||
local version_id=$(echo "$VERSION_ID" | cut -d'.' -f1)
|
||
|
||
if [ "$DISTRO" = "fedora" ]; then
|
||
local fedora_version=$(rpm -E %fedora)
|
||
safe_execute "Установка Remi репозитория для Fedora" \
|
||
$PKG_MANAGER install -y "https://rpms.remirepo.net/fedora/remi-release-${fedora_version}.rpm"
|
||
else
|
||
safe_execute "Установка Remi репозитория для RHEL/CentOS" \
|
||
$PKG_MANAGER install -y "https://rpms.remirepo.net/enterprise/remi-release-${version_id}.rpm"
|
||
fi
|
||
|
||
# Включаем модуль PHP 8.3 если доступен DNF
|
||
if command -v dnf >/dev/null 2>&1; then
|
||
safe_execute "Сброс модуля PHP" dnf module reset php -y || true
|
||
safe_execute "Включение модуля PHP 8.3" dnf module enable php:remi-8.3 -y || true
|
||
fi
|
||
|
||
log_success "Репозиторий Remi настроен"
|
||
fi
|
||
}
|
||
|
||
# Установка компонентов системы
|
||
install_components() {
|
||
log_step "Установка основных компонентов..."
|
||
|
||
# Остановка конфликтующих сервисов
|
||
log_info "Остановка конфликтующих сервисов..."
|
||
for service in nginx httpd apache2 php*-fpm mariadb mysql; do
|
||
systemctl stop "$service" 2>/dev/null || true
|
||
done
|
||
systemctl disable nginx httpd 2>/dev/null || true
|
||
|
||
sleep 3
|
||
|
||
# Удаление старых версий
|
||
remove_old_packages
|
||
|
||
# Установка Apache
|
||
if [ "$DISTRO_FAMILY" = "debian" ]; then
|
||
safe_execute "Установка Apache" apt install -y apache2
|
||
else
|
||
safe_execute "Установка Apache (httpd)" $PKG_MANAGER install -y httpd
|
||
fi
|
||
|
||
# Установка MariaDB
|
||
install_mariadb
|
||
|
||
# Установка PHP 8.3
|
||
install_php83
|
||
|
||
# Установка дополнительных компонентов
|
||
install_additional_components
|
||
}
|
||
|
||
# Удаление старых пакетов
|
||
remove_old_packages() {
|
||
log_info "Удаление старых версий пакетов..."
|
||
|
||
if [ "$DISTRO_FAMILY" = "debian" ]; then
|
||
export DEBIAN_FRONTEND=noninteractive
|
||
|
||
# Настройка автоматических ответов для MySQL/MariaDB
|
||
for db_package in mariadb-server mysql-server; do
|
||
for version in "" "-10.3" "-10.5" "-10.6" "-10.11" "-5.7" "-8.0"; do
|
||
echo "${db_package}${version} mysql-server/remove-data-dir boolean true" | debconf-set-selections 2>/dev/null || true
|
||
done
|
||
done
|
||
|
||
apt remove -y nginx nginx-common nginx-core 2>/dev/null || true
|
||
apt remove -y php7.* php8.0* php8.1* php8.2* libapache2-mod-php7.* libapache2-mod-php8.0* libapache2-mod-php8.1* libapache2-mod-php8.2* 2>/dev/null || true
|
||
apt remove --purge -y -o Dpkg::Options::="--force-confdef" -o Dpkg::Options::="--force-confold" mariadb* mysql* 2>/dev/null || true
|
||
apt autoremove -y 2>/dev/null || true
|
||
else
|
||
$PKG_MANAGER remove -y nginx php php7* php80* php81* php82* mariadb* mysql* 2>/dev/null || true
|
||
fi
|
||
|
||
# Удаление файлов данных MySQL/MariaDB
|
||
rm -rf /var/lib/mysql* /etc/mysql* /var/log/mysql* /etc/my.cnf* 2>/dev/null || true
|
||
}
|
||
|
||
# Установка MariaDB
|
||
install_mariadb() {
|
||
log_info "Установка MariaDB..."
|
||
|
||
if [ "$DISTRO_FAMILY" = "debian" ]; then
|
||
export DEBIAN_FRONTEND=noninteractive
|
||
echo "mariadb-server mysql-server/root_password password ''" | debconf-set-selections 2>/dev/null || true
|
||
echo "mariadb-server mysql-server/root_password_again password ''" | debconf-set-selections 2>/dev/null || true
|
||
safe_execute "Установка MariaDB" apt install -y mariadb-server
|
||
else
|
||
safe_execute "Установка MariaDB" $PKG_MANAGER install -y mariadb-server
|
||
fi
|
||
|
||
# Запуск и включение MariaDB
|
||
safe_execute "Запуск MariaDB" systemctl start mariadb
|
||
safe_execute "Включение MariaDB в автозагрузку" systemctl enable mariadb
|
||
|
||
# Ожидание полного запуска
|
||
log_info "Ожидание полного запуска MariaDB..."
|
||
local retry_count=0
|
||
while ! systemctl is-active --quiet mariadb && [ $retry_count -lt 10 ]; do
|
||
sleep 2
|
||
((retry_count++))
|
||
done
|
||
|
||
if ! systemctl is-active --quiet mariadb; then
|
||
log_error "MariaDB не удалось запустить"
|
||
exit 1
|
||
fi
|
||
}
|
||
|
||
# Установка PHP 8.3
|
||
install_php83() {
|
||
log_info "Установка PHP 8.3 и расширений..."
|
||
|
||
if [ "$DISTRO_FAMILY" = "debian" ]; then
|
||
export DEBIAN_FRONTEND=noninteractive
|
||
local php_packages="php8.3 php8.3-cli php8.3-common php8.3-mysql php8.3-curl php8.3-gd php8.3-mbstring php8.3-xml php8.3-zip php8.3-opcache php8.3-intl php8.3-bcmath php8.3-json php8.3-readline libapache2-mod-php8.3"
|
||
else
|
||
# Определяем доступные пакеты PHP для RHEL семейства
|
||
if $PKG_MANAGER list available | grep -q "php83-php\b"; then
|
||
local php_packages="php83-php php83-php-cli php83-php-common php83-php-mysqlnd php83-php-curl php83-php-gd php83-php-mbstring php83-php-xml php83-php-zip php83-php-opcache php83-php-intl php83-php-bcmath php83-php-json php83-php-fpm"
|
||
else
|
||
local php_packages="php php-cli php-common php-mysqlnd php-curl php-gd php-mbstring php-xml php-zip php-opcache php-intl php-bcmath php-json php-fpm"
|
||
fi
|
||
fi
|
||
|
||
if ! $PKG_MANAGER install -y $php_packages >/dev/null 2>&1; then
|
||
log_error "Не удалось установить PHP пакеты. Подробности в логе: $LOG_FILE"
|
||
$PKG_MANAGER install -y $php_packages 2>&1 | tee -a "$LOG_FILE"
|
||
exit 1
|
||
fi
|
||
|
||
# Создание символических ссылок для php83 (если нужно)
|
||
if command -v php83 >/dev/null 2>&1 && [ ! -f /usr/bin/php ]; then
|
||
ln -sf /opt/remi/php83/root/usr/bin/php /usr/bin/php 2>/dev/null || true
|
||
echo 'export PATH=/opt/remi/php83/root/usr/bin:$PATH' > /etc/profile.d/php83.sh
|
||
fi
|
||
|
||
# Проверка установки PHP
|
||
verify_php_installation
|
||
}
|
||
|
||
# Проверка установки PHP
|
||
verify_php_installation() {
|
||
log_info "Проверка установки PHP..."
|
||
|
||
if ! command -v php >/dev/null 2>&1; then
|
||
log_error "PHP не найден после установки"
|
||
exit 1
|
||
fi
|
||
|
||
local php_version=$(php -v 2>/dev/null | head -1 | cut -d' ' -f2 | cut -d'.' -f1,2 2>/dev/null || echo "неизвестно")
|
||
if [[ "$php_version" != "8.3" ]]; then
|
||
log_warning "PHP версия $php_version (ожидалась 8.3)"
|
||
|
||
# Попытка исправления версии для Debian
|
||
if [ "$DISTRO_FAMILY" = "debian" ] && [ -f /usr/bin/php8.3 ]; then
|
||
update-alternatives --set php /usr/bin/php8.3 2>/dev/null || true
|
||
php_version=$(php -v 2>/dev/null | head -1 | cut -d' ' -f2 | cut -d'.' -f1,2 2>/dev/null || echo "неизвестно")
|
||
fi
|
||
fi
|
||
|
||
if [[ "$php_version" == "8.3" ]]; then
|
||
log_success "PHP 8.3 успешно установлен"
|
||
else
|
||
log_error "Не удалось установить PHP 8.3 (текущая версия: $php_version)"
|
||
exit 1
|
||
fi
|
||
|
||
# Проверка расширений PHP
|
||
verify_php_extensions
|
||
}
|
||
|
||
# Проверка расширений PHP
|
||
verify_php_extensions() {
|
||
log_info "Проверка PHP расширений..."
|
||
|
||
local required_extensions="mysqli pdo_mysql curl gd mbstring xml zip opcache intl bcmath json"
|
||
local missing_extensions=""
|
||
|
||
for ext in $required_extensions; do
|
||
if php -m 2>/dev/null | grep -q "^$ext$"; then
|
||
log_success "Расширение $ext: установлено"
|
||
else
|
||
log_warning "Расширение $ext: НЕ найдено"
|
||
missing_extensions="$missing_extensions $ext"
|
||
fi
|
||
done
|
||
|
||
if [ -n "$missing_extensions" ]; then
|
||
log_warning "Попытка установки отсутствующих расширений:$missing_extensions"
|
||
install_missing_php_extensions "$missing_extensions"
|
||
fi
|
||
}
|
||
|
||
# Установка недостающих расширений PHP
|
||
install_missing_php_extensions() {
|
||
local missing_extensions="$1"
|
||
|
||
if [ "$DISTRO_FAMILY" = "debian" ]; then
|
||
for ext in $missing_extensions; do
|
||
if [[ "$ext" =~ ^(mysqli|pdo_mysql)$ ]]; then
|
||
apt install -y php8.3-mysql 2>/dev/null || true
|
||
else
|
||
apt install -y "php8.3-$ext" 2>/dev/null || true
|
||
fi
|
||
done
|
||
else
|
||
for ext in $missing_extensions; do
|
||
if [[ "$ext" =~ ^(mysqli|pdo_mysql)$ ]]; then
|
||
$PKG_MANAGER install -y php*-mysqlnd 2>/dev/null || true
|
||
else
|
||
$PKG_MANAGER install -y "php*-$ext" 2>/dev/null || true
|
||
fi
|
||
done
|
||
fi
|
||
}
|
||
|
||
# Установка дополнительных компонентов
|
||
install_additional_components() {
|
||
log_info "Установка дополнительных компонентов (Redis, LibreOffice, Java)..."
|
||
|
||
if [ "$DISTRO_FAMILY" = "debian" ]; then
|
||
export DEBIAN_FRONTEND=noninteractive
|
||
safe_execute "Установка дополнительных компонентов" \
|
||
apt install -y redis-server libreoffice default-jre
|
||
else
|
||
safe_execute "Установка дополнительных компонентов" \
|
||
$PKG_MANAGER install -y redis libreoffice java-11-openjdk
|
||
fi
|
||
}
|
||
|
||
# Настройка Apache и PHP
|
||
configure_apache_php() {
|
||
log_step "Настройка Apache и PHP..."
|
||
|
||
if [ "$DISTRO_FAMILY" = "debian" ]; then
|
||
configure_apache_debian
|
||
else
|
||
configure_apache_rhel
|
||
fi
|
||
|
||
# Настройка PHP.ini
|
||
configure_php_ini
|
||
|
||
# Создание виртуального хоста
|
||
create_virtual_host
|
||
|
||
# Проверка конфигурации Apache
|
||
verify_apache_config
|
||
}
|
||
|
||
# Настройка Apache для Debian/Ubuntu
|
||
configure_apache_debian() {
|
||
log_info "Настройка Apache для Debian/Ubuntu..."
|
||
|
||
# Включение модулей
|
||
a2enmod php8.3 rewrite ssl headers expires deflate 2>/dev/null || true
|
||
|
||
# Отключение старых версий PHP
|
||
for php_ver in 7.4 8.0 8.1 8.2; do
|
||
a2dismod "php$php_ver" 2>/dev/null || true
|
||
done
|
||
}
|
||
|
||
# Настройка Apache для RHEL семейства
|
||
configure_apache_rhel() {
|
||
log_info "Настройка Apache для RHEL семейства..."
|
||
|
||
# Удаление старых конфигураций PHP
|
||
rm -f /etc/httpd/conf.d/php.conf /etc/httpd/conf.modules.d/*php*.conf 2>/dev/null || true
|
||
|
||
# Настройка PHP-FPM
|
||
configure_php_fpm
|
||
|
||
# Создание конфигурации PHP-FPM для Apache
|
||
create_php_fpm_config
|
||
|
||
# Создание общей конфигурации Altcor
|
||
create_altcor_config
|
||
}
|
||
|
||
# Настройка PHP-FPM
|
||
configure_php_fpm() {
|
||
log_info "Настройка PHP-FPM..."
|
||
|
||
if [ -z "$PHP_FPM_CONF" ] || [ ! -f "$PHP_FPM_CONF" ]; then
|
||
log_error "Файл конфигурации PHP-FPM не найден: $PHP_FPM_CONF"
|
||
exit 1
|
||
fi
|
||
|
||
# Создание резервной копии
|
||
cp "$PHP_FPM_CONF" "${PHP_FPM_CONF}.backup.$(date +%Y%m%d_%H%M%S)"
|
||
|
||
# Настройка параметров PHP-FPM pool
|
||
sed -i "s|;*listen = .*|listen = $SOCKET_PATH|" "$PHP_FPM_CONF"
|
||
sed -i 's/;*listen.owner = .*/listen.owner = apache/' "$PHP_FPM_CONF"
|
||
sed -i 's/;*listen.group = .*/listen.group = apache/' "$PHP_FPM_CONF"
|
||
sed -i 's/;*listen.mode = .*/listen.mode = 0660/' "$PHP_FPM_CONF"
|
||
sed -i 's/;*user = .*/user = apache/' "$PHP_FPM_CONF"
|
||
sed -i 's/;*group = .*/group = apache/' "$PHP_FPM_CONF"
|
||
|
||
# Настройка производительности
|
||
sed -i 's/;*pm = .*/pm = dynamic/' "$PHP_FPM_CONF"
|
||
sed -i 's/;*pm.max_children = .*/pm.max_children = 50/' "$PHP_FPM_CONF"
|
||
sed -i 's/;*pm.start_servers = .*/pm.start_servers = 5/' "$PHP_FPM_CONF"
|
||
sed -i 's/;*pm.min_spare_servers = .*/pm.min_spare_servers = 5/' "$PHP_FPM_CONF"
|
||
sed -i 's/;*pm.max_spare_servers = .*/pm.max_spare_servers = 35/' "$PHP_FPM_CONF"
|
||
|
||
# Создание директории для socket
|
||
local socket_dir=$(dirname "$SOCKET_PATH")
|
||
mkdir -p "$socket_dir"
|
||
chown apache:apache "$socket_dir"
|
||
|
||
# Запуск PHP-FPM
|
||
safe_execute "Запуск PHP-FPM" systemctl start "$PHP_FPM_SERVICE"
|
||
safe_execute "Включение PHP-FPM в автозагрузку" systemctl enable "$PHP_FPM_SERVICE"
|
||
|
||
if ! systemctl is-active --quiet "$PHP_FPM_SERVICE"; then
|
||
log_error "PHP-FPM не удалось запустить"
|
||
systemctl status "$PHP_FPM_SERVICE" --no-pager -l | tee -a "$LOG_FILE"
|
||
exit 1
|
||
fi
|
||
}
|
||
|
||
# Создание конфигурации PHP-FPM для Apache
|
||
create_php_fpm_config() {
|
||
log_info "Создание конфигурации PHP-FPM для Apache..."
|
||
|
||
cat > "/etc/httpd/conf.d/php-fpm.conf" << EOF
|
||
# PHP-FPM configuration for Apache
|
||
# Использование только PHP-FPM, без mod_php
|
||
|
||
# Загрузка необходимых модулей
|
||
<IfModule !mod_rewrite.c>
|
||
LoadModule rewrite_module modules/mod_rewrite.so
|
||
</IfModule>
|
||
<IfModule !mod_headers.c>
|
||
LoadModule headers_module modules/mod_headers.so
|
||
</IfModule>
|
||
<IfModule !mod_expires.c>
|
||
LoadModule expires_module modules/mod_expires.so
|
||
</IfModule>
|
||
<IfModule !mod_deflate.c>
|
||
LoadModule deflate_module modules/mod_deflate.so
|
||
</IfModule>
|
||
<IfModule !mod_proxy.c>
|
||
LoadModule proxy_module modules/mod_proxy.so
|
||
</IfModule>
|
||
<IfModule !mod_proxy_fcgi.c>
|
||
LoadModule proxy_fcgi_module modules/mod_proxy_fcgi.so
|
||
</IfModule>
|
||
|
||
# Обработка PHP файлов через PHP-FPM
|
||
<FilesMatch \.php$>
|
||
SetHandler "proxy:unix:$SOCKET_PATH|fcgi://localhost"
|
||
</FilesMatch>
|
||
|
||
# Настройки производительности
|
||
ProxyTimeout 300
|
||
ProxyPassMatch ^/(.*\.php(/.*)?)$ unix:$SOCKET_PATH|fcgi://localhost/var/www/html/
|
||
EOF
|
||
}
|
||
|
||
# Создание основной конфигурации Altcor
|
||
create_altcor_config() {
|
||
log_info "Создание конфигурации Altcor..."
|
||
|
||
cat > "/etc/httpd/conf.d/altcor.conf" << 'EOF'
|
||
# Altcor main configuration
|
||
|
||
# Безопасность сервера
|
||
ServerTokens Prod
|
||
ServerSignature Off
|
||
|
||
# Основные настройки директории
|
||
<Directory "/var/www/html">
|
||
Options -Indexes +FollowSymLinks
|
||
AllowOverride All
|
||
Require all granted
|
||
|
||
# Сжатие контента
|
||
<IfModule mod_deflate.c>
|
||
SetOutputFilter DEFLATE
|
||
SetEnvIfNoCase Request_URI \
|
||
\.(?:gif|jpe?g|png|ico|exe|t?gz|zip|bz2|sit|rar)$ no-gzip dont-vary
|
||
SetEnvIfNoCase User-Agent "^Mozilla/4\.0[678]" no-gzip
|
||
SetEnvIfNoCase User-Agent "MSIE [1-6]\." no-gzip
|
||
</IfModule>
|
||
|
||
# Кэширование статических ресурсов
|
||
<IfModule mod_expires.c>
|
||
ExpiresActive On
|
||
ExpiresByType image/jpg "access plus 1 month"
|
||
ExpiresByType image/jpeg "access plus 1 month"
|
||
ExpiresByType image/gif "access plus 1 month"
|
||
ExpiresByType image/png "access plus 1 month"
|
||
ExpiresByType image/svg+xml "access plus 1 month"
|
||
ExpiresByType image/webp "access plus 1 month"
|
||
ExpiresByType image/x-icon "access plus 1 month"
|
||
ExpiresByType text/css "access plus 1 month"
|
||
ExpiresByType application/javascript "access plus 1 month"
|
||
ExpiresByType text/javascript "access plus 1 month"
|
||
ExpiresByType font/woff "access plus 1 month"
|
||
ExpiresByType font/woff2 "access plus 1 month"
|
||
ExpiresByType font/ttf "access plus 1 month"
|
||
ExpiresByType font/otf "access plus 1 month"
|
||
ExpiresByType text/html "access plus 0 seconds"
|
||
ExpiresByType application/x-httpd-php "access plus 0 seconds"
|
||
</IfModule>
|
||
|
||
# Заголовки безопасности
|
||
<IfModule mod_headers.c>
|
||
Header always set X-Content-Type-Options nosniff
|
||
Header always set X-Frame-Options SAMEORIGIN
|
||
Header always set X-XSS-Protection "1; mode=block"
|
||
Header always set Referrer-Policy "strict-origin-when-cross-origin"
|
||
<FilesMatch "\.(js|css|png|jpg|jpeg|gif|ico|svg|woff|woff2|ttf|otf)$">
|
||
Header set Cache-Control "public, max-age=2592000"
|
||
</FilesMatch>
|
||
</IfModule>
|
||
</Directory>
|
||
|
||
# Запрет доступа к служебным файлам
|
||
<Files ~ "\.(conf|env|log|bak|backup)$">
|
||
Require all denied
|
||
</Files>
|
||
|
||
<Files ".htaccess">
|
||
Require all denied
|
||
</Files>
|
||
|
||
<DirectoryMatch "^\.|\/\.">
|
||
Require all denied
|
||
</DirectoryMatch>
|
||
|
||
# Защита директории uploads
|
||
<Directory "/var/www/html/uploads">
|
||
<Files ~ "\.(php|phtml|pl|py|jsp|asp|sh|cgi)$">
|
||
Require all denied
|
||
</Files>
|
||
</Directory>
|
||
EOF
|
||
}
|
||
|
||
# Настройка PHP.ini
|
||
configure_php_ini() {
|
||
log_info "Настройка PHP.ini..."
|
||
|
||
if [ ! -f "$PHP_INI_PATH" ]; then
|
||
log_warning "Файл PHP.ini не найден по пути: $PHP_INI_PATH"
|
||
return
|
||
fi
|
||
|
||
# Создание резервной копии
|
||
cp "$PHP_INI_PATH" "${PHP_INI_PATH}.backup.$(date +%Y%m%d_%H%M%S)"
|
||
|
||
# Основные настройки
|
||
sed -i 's/;*upload_max_filesize = .*/upload_max_filesize = 64M/' "$PHP_INI_PATH"
|
||
sed -i 's/;*post_max_size = .*/post_max_size = 64M/' "$PHP_INI_PATH"
|
||
sed -i 's/;*max_execution_time = .*/max_execution_time = 300/' "$PHP_INI_PATH"
|
||
sed -i 's/;*memory_limit = .*/memory_limit = 256M/' "$PHP_INI_PATH"
|
||
sed -i 's/;*max_input_vars = .*/max_input_vars = 3000/' "$PHP_INI_PATH"
|
||
|
||
# Настройки OPcache
|
||
sed -i 's/;*opcache.enable=.*/opcache.enable=1/' "$PHP_INI_PATH"
|
||
sed -i 's/;*opcache.enable_cli=.*/opcache.enable_cli=1/' "$PHP_INI_PATH"
|
||
sed -i 's/;*opcache.memory_consumption=.*/opcache.memory_consumption=128/' "$PHP_INI_PATH"
|
||
sed -i 's/;*opcache.revalidate_freq=.*/opcache.revalidate_freq=2/' "$PHP_INI_PATH"
|
||
sed -i 's/;*opcache.max_accelerated_files=.*/opcache.max_accelerated_files=4000/' "$PHP_INI_PATH"
|
||
|
||
# Настройки безопасности
|
||
sed -i 's/;*expose_php = .*/expose_php = Off/' "$PHP_INI_PATH"
|
||
sed -i 's/;*display_errors = .*/display_errors = Off/' "$PHP_INI_PATH"
|
||
sed -i 's/;*log_errors = .*/log_errors = On/' "$PHP_INI_PATH"
|
||
|
||
log_success "PHP.ini настроен"
|
||
}
|
||
|
||
# Создание виртуального хоста
|
||
create_virtual_host() {
|
||
log_info "Создание конфигурации виртуального хоста..."
|
||
|
||
mkdir -p "$WEBROOT"
|
||
|
||
if [ "$DISTRO_FAMILY" = "debian" ]; then
|
||
cat > "$APACHE_CONF" << EOF
|
||
<VirtualHost *:80>
|
||
DocumentRoot $WEBROOT
|
||
ServerName localhost
|
||
ServerAlias www.localhost
|
||
|
||
<Directory $WEBROOT>
|
||
Options -Indexes +FollowSymLinks
|
||
AllowOverride All
|
||
Require all granted
|
||
|
||
<IfModule mod_deflate.c>
|
||
SetOutputFilter DEFLATE
|
||
SetEnvIfNoCase Request_URI \
|
||
\.(?:gif|jpe?g|png)$ no-gzip dont-vary
|
||
SetEnvIfNoCase Request_URI \
|
||
\.(?:exe|t?gz|zip|bz2|sit|rar)$ no-gzip dont-vary
|
||
</IfModule>
|
||
</Directory>
|
||
|
||
<FilesMatch \.php$>
|
||
SetHandler application/x-httpd-php
|
||
</FilesMatch>
|
||
|
||
<Files ~ "\.(conf|env|log)$">
|
||
Require all denied
|
||
</Files>
|
||
|
||
<IfModule mod_expires.c>
|
||
ExpiresActive On
|
||
ExpiresByType image/jpg "access plus 1 month"
|
||
ExpiresByType image/jpeg "access plus 1 month"
|
||
ExpiresByType image/gif "access plus 1 month"
|
||
ExpiresByType image/png "access plus 1 month"
|
||
ExpiresByType text/css "access plus 1 month"
|
||
ExpiresByType application/javascript "access plus 1 month"
|
||
</IfModule>
|
||
|
||
ErrorLog \${APACHE_LOG_DIR}/error.log
|
||
CustomLog \${APACHE_LOG_DIR}/access.log combined
|
||
</VirtualHost>
|
||
EOF
|
||
fi
|
||
}
|
||
|
||
# Проверка конфигурации Apache
|
||
verify_apache_config() {
|
||
log_info "Проверка конфигурации Apache..."
|
||
|
||
if [ "$DISTRO_FAMILY" = "debian" ]; then
|
||
if ! apache2ctl configtest >/dev/null 2>&1; then
|
||
log_error "Конфигурация Apache содержит ошибки:"
|
||
apache2ctl configtest 2>&1 | tee -a "$LOG_FILE"
|
||
exit 1
|
||
fi
|
||
else
|
||
if ! httpd -t >/dev/null 2>&1; then
|
||
log_error "Конфигурация Apache (httpd) содержит ошибки:"
|
||
httpd -t 2>&1 | tee -a "$LOG_FILE"
|
||
|
||
# Попытка исправления
|
||
if ! httpd -M 2>/dev/null | grep -q "rewrite_module"; then
|
||
echo "LoadModule rewrite_module modules/mod_rewrite.so" >> /etc/httpd/conf.d/altcor.conf
|
||
fi
|
||
|
||
if ! httpd -t >/dev/null 2>&1; then
|
||
log_error "Не удалось исправить конфигурацию Apache"
|
||
exit 1
|
||
fi
|
||
fi
|
||
fi
|
||
|
||
log_success "Конфигурация Apache проверена"
|
||
}
|
||
|
||
# Настройка базы данных
|
||
configure_database() {
|
||
log_step "Настройка базы данных MariaDB..."
|
||
|
||
local db_password=$(generate_password)
|
||
|
||
if ! systemctl is-active --quiet mariadb; then
|
||
log_error "MariaDB не запущен"
|
||
exit 1
|
||
fi
|
||
|
||
# Выполнение настройки безопасности MariaDB
|
||
setup_mariadb_security "$db_password"
|
||
|
||
# Создание конфигурационного файла БД
|
||
create_db_config "$db_password"
|
||
|
||
# Сохранение учетных данных
|
||
save_db_credentials "$db_password"
|
||
|
||
echo "$db_password" # Возвращаем пароль для использования в main
|
||
}
|
||
|
||
# Настройка безопасности MariaDB
|
||
setup_mariadb_security() {
|
||
local db_password="$1"
|
||
|
||
log_info "Выполнение базовой настройки безопасности MariaDB..."
|
||
|
||
if mysql -u root -e "SELECT 1;" >/dev/null 2>&1; then
|
||
log_info "Первичная настройка MariaDB..."
|
||
setup_fresh_mariadb "$db_password"
|
||
elif mysql -u root -p"$db_password" -e "SELECT 1;" >/dev/null 2>&1; then
|
||
log_info "MariaDB уже настроен, обновляем базу данных..."
|
||
update_existing_mariadb "$db_password"
|
||
else
|
||
log_warning "Требуется сброс пароля root в MariaDB..."
|
||
reset_mariadb_password "$db_password"
|
||
fi
|
||
}
|
||
|
||
# Первичная настройка MariaDB
|
||
setup_fresh_mariadb() {
|
||
local db_password="$1"
|
||
local script_file="/tmp/mysql_secure_$(date +%s).sql"
|
||
|
||
cat > "$script_file" << MYSQL_SCRIPT
|
||
ALTER USER 'root'@'localhost' IDENTIFIED BY '$db_password';
|
||
DELETE FROM mysql.user WHERE User='';
|
||
DELETE FROM mysql.user WHERE User='root' AND Host NOT IN ('localhost', '127.0.0.1', '::1');
|
||
DROP DATABASE IF EXISTS test;
|
||
DELETE FROM mysql.db WHERE Db='test' OR Db='test\\_%';
|
||
CREATE DATABASE IF NOT EXISTS ALTCor CHARACTER SET utf8mb4 COLLATE utf8mb4_unicode_ci;
|
||
GRANT ALL PRIVILEGES ON ALTCor.* TO 'root'@'localhost';
|
||
FLUSH PRIVILEGES;
|
||
MYSQL_SCRIPT
|
||
|
||
if mysql -u root < "$script_file" >/dev/null 2>&1; then
|
||
log_success "Первичная настройка MariaDB выполнена"
|
||
else
|
||
log_error "Ошибка при настройке MariaDB"
|
||
rm -f "$script_file"
|
||
exit 1
|
||
fi
|
||
rm -f "$script_file"
|
||
}
|
||
|
||
# Обновление существующей MariaDB
|
||
update_existing_mariadb() {
|
||
local db_password="$1"
|
||
local script_file="/tmp/mysql_update_$(date +%s).sql"
|
||
|
||
cat > "$script_file" << MYSQL_SCRIPT
|
||
CREATE DATABASE IF NOT EXISTS ALTCor CHARACTER SET utf8mb4 COLLATE utf8mb4_unicode_ci;
|
||
GRANT ALL PRIVILEGES ON ALTCor.* TO 'root'@'localhost';
|
||
FLUSH PRIVILEGES;
|
||
MYSQL_SCRIPT
|
||
|
||
if mysql -u root -p"$db_password" < "$script_file" >/dev/null 2>&1; then
|
||
log_success "База данных ALTCor обновлена"
|
||
else
|
||
log_error "Ошибка при обновлении базы данных"
|
||
rm -f "$script_file"
|
||
exit 1
|
||
fi
|
||
rm -f "$script_file"
|
||
}
|
||
|
||
# Сброс пароля MariaDB
|
||
reset_mariadb_password() {
|
||
local db_password="$1"
|
||
|
||
log_info "Сброс пароля root в MariaDB..."
|
||
|
||
systemctl stop mariadb
|
||
mysqld_safe --skip-grant-tables --skip-networking &
|
||
local mysqld_pid=$!
|
||
sleep 5
|
||
|
||
local reset_script="/tmp/mysql_reset_$(date +%s).sql"
|
||
cat > "$reset_script" << MYSQL_SCRIPT
|
||
USE mysql;
|
||
UPDATE user SET password=PASSWORD('$db_password') WHERE User='root';
|
||
UPDATE user SET plugin='mysql_native_password' WHERE User='root';
|
||
FLUSH PRIVILEGES;
|
||
MYSQL_SCRIPT
|
||
|
||
if mysql -u root < "$reset_script" >/dev/null 2>&1; then
|
||
kill $mysqld_pid 2>/dev/null || true
|
||
sleep 3
|
||
killall mysqld_safe mysqld 2>/dev/null || true
|
||
sleep 3
|
||
|
||
systemctl start mariadb
|
||
sleep 3
|
||
|
||
if systemctl is-active --quiet mariadb && mysql -u root -p"$db_password" -e "SELECT 1;" >/dev/null 2>&1; then
|
||
update_existing_mariadb "$db_password"
|
||
log_success "Пароль MariaDB сброшен и база данных настроена"
|
||
else
|
||
log_error "MariaDB не запустился после сброса пароля"
|
||
exit 1
|
||
fi
|
||
else
|
||
log_error "Не удалось сбросить пароль root в MariaDB"
|
||
kill $mysqld_pid 2>/dev/null || true
|
||
exit 1
|
||
fi
|
||
rm -f "$reset_script"
|
||
}
|
||
|
||
# Создание конфигурационного файла БД
|
||
create_db_config() {
|
||
local db_password="$1"
|
||
|
||
log_info "Создание конфигурации базы данных..."
|
||
|
||
cat > "$WEBROOT/db_config.php" << EOF
|
||
<?php
|
||
define('DB_HOST', 'localhost');
|
||
define('DB_USER', 'root');
|
||
define('DB_PASS', '$db_password');
|
||
define('DB_NAME', 'ALTCor');
|
||
define('DB_SOCKET', '$DB_SOCKET');
|
||
define('DB_CHARSET', 'utf8mb4');
|
||
define('OFFICE', '/usr/bin/libreoffice');
|
||
?>
|
||
EOF
|
||
|
||
# Установка правильных прав доступа
|
||
chown "$WEBSERVER_USER:$WEBSERVER_USER" "$WEBROOT/db_config.php"
|
||
chmod 600 "$WEBROOT/db_config.php"
|
||
|
||
# Проверка доступности файла
|
||
if ! sudo -u "$WEBSERVER_USER" test -r "$WEBROOT/db_config.php"; then
|
||
log_error "Веб-сервер не может читать db_config.php"
|
||
exit 1
|
||
fi
|
||
|
||
log_success "Конфигурация БД создана"
|
||
}
|
||
|
||
# Сохранение учетных данных
|
||
save_db_credentials() {
|
||
local db_password="$1"
|
||
local credentials_file="/root/.db_password"
|
||
|
||
cat > "$credentials_file" << EOF
|
||
# Altcor Database Credentials
|
||
DB_HOST=localhost
|
||
DB_USER=root
|
||
DB_PASSWORD=$db_password
|
||
DB_NAME=ALTCor
|
||
DB_SOCKET=$DB_SOCKET
|
||
CREATED=$(date)
|
||
EOF
|
||
|
||
chmod 600 "$credentials_file"
|
||
log_info "Учетные данные сохранены в $credentials_file"
|
||
}
|
||
|
||
# Установка веб-приложения
|
||
setup_web_application() {
|
||
log_step "Настройка веб-приложения..."
|
||
|
||
# Очистка старых файлов (кроме db_config.php)
|
||
find "$WEBROOT" -type f ! -name "db_config.php" -delete 2>/dev/null || true
|
||
|
||
# Загрузка файлов приложения
|
||
download_application_files
|
||
|
||
# Создание .htaccess
|
||
create_htaccess_file
|
||
|
||
# Настройка прав доступа
|
||
setup_file_permissions
|
||
}
|
||
|
||
# Загрузка файлов приложения
|
||
download_application_files() {
|
||
local download_url="https://cloud.altcor.ru/setup/download.php"
|
||
|
||
log_info "Загрузка файлов приложения..."
|
||
|
||
if curl -f -L --max-time 30 -o "$WEBROOT/index.php" "$download_url" 2>/dev/null; then
|
||
if head -n 1 "$WEBROOT/index.php" | grep -q "<?php" || grep -q "<?php" "$WEBROOT/index.php" 2>/dev/null; then
|
||
log_success "Файлы приложения загружены"
|
||
return
|
||
fi
|
||
fi
|
||
|
||
# Если загрузка не удалась, создаем резервную страницу
|
||
log_warning "Не удалось загрузить файлы с $download_url, создаем резервную страницу"
|
||
create_fallback_index
|
||
}
|
||
|
||
# Создание резервной индексной страницы
|
||
create_fallback_index() {
|
||
cat > "$WEBROOT/index.php" << 'EOF'
|
||
<?php
|
||
require_once __DIR__ . '/db_config.php';
|
||
?>
|
||
<!DOCTYPE html>
|
||
<html lang='ru'>
|
||
<head>
|
||
<meta charset='UTF-8'>
|
||
<meta name='viewport' content='width=device-width, initial-scale=1.0'>
|
||
<title>Altcor - Сервер готов</title>
|
||
<style>
|
||
body {
|
||
font-family: -apple-system, BlinkMacSystemFont, 'Segoe UI', sans-serif;
|
||
margin: 0; padding: 40px; background: linear-gradient(135deg, #667eea 0%, #764ba2 100%);
|
||
min-height: 100vh; color: #333;
|
||
}
|
||
.container {
|
||
max-width: 800px; margin: 0 auto; background: white;
|
||
padding: 40px; border-radius: 15px;
|
||
box-shadow: 0 20px 40px rgba(0,0,0,0.1);
|
||
}
|
||
h1 { color: #2c5282; margin-top: 0; text-align: center; }
|
||
.status {
|
||
padding: 15px; margin: 15px 0; border-radius: 8px;
|
||
border-left: 4px solid;
|
||
}
|
||
.success {
|
||
background: #c6f6d5; color: #22543d;
|
||
border-left-color: #38a169;
|
||
}
|
||
.info {
|
||
background: #bee3f8; color: #2a4365;
|
||
border-left-color: #3182ce;
|
||
}
|
||
.grid {
|
||
display: grid; grid-template-columns: repeat(auto-fit, minmax(250px, 1fr));
|
||
gap: 20px; margin-top: 20px;
|
||
}
|
||
.card {
|
||
background: #f7fafc; padding: 20px; border-radius: 10px;
|
||
border: 1px solid #e2e8f0;
|
||
}
|
||
</style>
|
||
</head>
|
||
<body>
|
||
<div class='container'>
|
||
<h1>🚀 Altcor - Сервер готов к работе</h1>
|
||
|
||
<div class='status success'>
|
||
<strong>✅ Система успешно установлена</strong><br>
|
||
PHP <?= phpversion() ?> работает корректно<br>
|
||
Время сервера: <?= date('Y-m-d H:i:s T') ?>
|
||
</div>
|
||
|
||
<div class='grid'>
|
||
<div class='card'>
|
||
<h3>🔧 Системная информация</h3>
|
||
<p><strong>Document Root:</strong> <?= $_SERVER['DOCUMENT_ROOT'] ?></p>
|
||
<p><strong>Server Software:</strong> <?= $_SERVER['SERVER_SOFTWARE'] ?? 'N/A' ?></p>
|
||
<p><strong>PHP Version:</strong> <?= phpversion() ?></p>
|
||
</div>
|
||
|
||
<div class='card'>
|
||
<h3>💾 База данных</h3>
|
||
<?php
|
||
try {
|
||
$pdo = new PDO("mysql:host=" . DB_HOST . ";dbname=" . DB_NAME . ";charset=" . DB_CHARSET, DB_USER, DB_PASS);
|
||
echo "<p style='color: #22543d;'>✅ Подключение успешно</p>";
|
||
echo "<p><strong>База:</strong> " . DB_NAME . "</p>";
|
||
echo "<p><strong>Хост:</strong> " . DB_HOST . "</p>";
|
||
} catch (PDOException $e) {
|
||
echo "<p style='color: #e53e3e;'>❌ Ошибка подключения</p>";
|
||
echo "<p>" . htmlspecialchars($e->getMessage()) . "</p>";
|
||
}
|
||
?>
|
||
</div>
|
||
</div>
|
||
|
||
<div class='status info'>
|
||
<strong>🎉 Установка завершена!</strong><br>
|
||
Система готова для развертывания вашего приложения Altcor.
|
||
</div>
|
||
</div>
|
||
</body>
|
||
</html>
|
||
EOF
|
||
}
|
||
|
||
# Создание .htaccess файла
|
||
create_htaccess_file() {
|
||
log_info "Создание .htaccess файла..."
|
||
|
||
cat > "$WEBROOT/.htaccess" << 'EOF'
|
||
# Altcor .htaccess Configuration
|
||
|
||
# Безопасность
|
||
<Files ~ "\.(conf|env|log|bak|backup|sql)$">
|
||
Require all denied
|
||
</Files>
|
||
|
||
<Files ".htaccess">
|
||
Require all denied
|
||
</Files>
|
||
|
||
# Сжатие
|
||
<IfModule mod_deflate.c>
|
||
AddOutputFilterByType DEFLATE text/html text/plain text/xml text/css text/javascript application/javascript application/json application/xml
|
||
</IfModule>
|
||
|
||
# Кэширование
|
||
<IfModule mod_expires.c>
|
||
ExpiresActive On
|
||
ExpiresByType image/jpg "access plus 1 month"
|
||
ExpiresByType image/jpeg "access plus 1 month"
|
||
ExpiresByType image/gif "access plus 1 month"
|
||
ExpiresByType image/png "access plus 1 month"
|
||
ExpiresByType image/svg+xml "access plus 1 month"
|
||
ExpiresByType image/webp "access plus 1 month"
|
||
ExpiresByType text/css "access plus 1 month"
|
||
ExpiresByType application/javascript "access plus 1 month"
|
||
ExpiresByType text/javascript "access plus 1 month"
|
||
ExpiresByType font/woff "access plus 1 month"
|
||
ExpiresByType font/woff2 "access plus 1 month"
|
||
</IfModule>
|
||
|
||
# Заголовки безопасности
|
||
<IfModule mod_headers.c>
|
||
Header always set X-Content-Type-Options nosniff
|
||
Header always set X-Frame-Options SAMEORIGIN
|
||
Header always set X-XSS-Protection "1; mode=block"
|
||
Header always set Referrer-Policy "strict-origin-when-cross-origin"
|
||
</IfModule>
|
||
|
||
# URL Rewriting
|
||
RewriteEngine On
|
||
# RewriteCond %{REQUEST_FILENAME} !-f
|
||
# RewriteCond %{REQUEST_FILENAME} !-d
|
||
# RewriteRule ^(.*)$ index.php [QSA,L]
|
||
EOF
|
||
}
|
||
|
||
# Настройка прав доступа к файлам
|
||
setup_file_permissions() {
|
||
log_info "Настройка прав доступа к файлам..."
|
||
|
||
# Установка владельца и группы
|
||
chown -R "$WEBSERVER_USER:$WEBSERVER_USER" "$WEBROOT"
|
||
|
||
# Установка прав доступа
|
||
find "$WEBROOT" -type d -exec chmod 755 {} \;
|
||
find "$WEBROOT" -type f -exec chmod 644 {} \;
|
||
|
||
# Специальные права для конфигурации БД
|
||
chmod 600 "$WEBROOT/db_config.php"
|
||
|
||
log_success "Права доступа настроены"
|
||
}
|
||
|
||
# Запуск и включение сервисов
|
||
start_services() {
|
||
log_step "Запуск и включение сервисов..."
|
||
|
||
local services_to_restart=""
|
||
local services_to_enable=""
|
||
|
||
# Определяем сервисы для перезапуска
|
||
if [ "$DISTRO_FAMILY" = "debian" ]; then
|
||
services_to_restart="apache2 mariadb"
|
||
services_to_enable="apache2 mariadb"
|
||
else
|
||
services_to_restart="$PHP_FPM_SERVICE httpd mariadb"
|
||
services_to_enable="$PHP_FPM_SERVICE httpd mariadb"
|
||
fi
|
||
|
||
# Добавляем Redis
|
||
if systemctl list-unit-files | grep -q "redis-server.service"; then
|
||
services_to_restart="$services_to_restart redis-server"
|
||
services_to_enable="$services_to_enable redis-server"
|
||
elif systemctl list-unit-files | grep -q "redis.service"; then
|
||
services_to_restart="$services_to_restart redis"
|
||
services_to_enable="$services_to_enable redis"
|
||
fi
|
||
|
||
# Перезапуск сервисов
|
||
for service in $services_to_restart; do
|
||
if safe_execute "Перезапуск $service" systemctl restart "$service"; then
|
||
log_success "$service перезапущен"
|
||
else
|
||
log_error "Не удалось перезапустить $service"
|
||
fi
|
||
done
|
||
|
||
# Включение в автозагрузку
|
||
for service in $services_to_enable; do
|
||
safe_execute "Включение $service в автозагрузку" systemctl enable "$service" || true
|
||
done
|
||
|
||
log_success "Все сервисы настроены"
|
||
}
|
||
|
||
# Финальная проверка работоспособности
|
||
final_verification() {
|
||
log_step "Финальная проверка работоспособности..."
|
||
|
||
local errors=0
|
||
|
||
# Проверка веб-сервера
|
||
if ! systemctl is-active --quiet "$WEBSERVER_SERVICE"; then
|
||
log_error "Веб-сервер ($WEBSERVER_SERVICE) не запущен"
|
||
((errors++))
|
||
else
|
||
log_success "Веб-сервер работает"
|
||
fi
|
||
|
||
# Проверка PHP-FPM (для RHEL семейства)
|
||
if [ "$DISTRO_FAMILY" = "rhel" ] && [ -n "$PHP_FPM_SERVICE" ]; then
|
||
if ! systemctl is-active --quiet "$PHP_FPM_SERVICE"; then
|
||
log_error "PHP-FPM ($PHP_FPM_SERVICE) не запущен"
|
||
((errors++))
|
||
else
|
||
log_success "PHP-FPM работает"
|
||
fi
|
||
fi
|
||
|
||
# Проверка MariaDB
|
||
if ! systemctl is-active --quiet mariadb; then
|
||
log_error "MariaDB не запущен"
|
||
((errors++))
|
||
else
|
||
log_success "MariaDB работает"
|
||
fi
|
||
|
||
# Проверка PHP
|
||
if ! php -r "echo 'PHP OK';" >/dev/null 2>&1; then
|
||
log_error "PHP не работает корректно"
|
||
((errors++))
|
||
else
|
||
log_success "PHP работает корректно"
|
||
fi
|
||
|
||
# Проверка подключения к базе данных
|
||
if [ -f "$WEBROOT/db_config.php" ]; then
|
||
if php -r "
|
||
require '$WEBROOT/db_config.php';
|
||
try {
|
||
\$pdo = new PDO('mysql:host=' . DB_HOST . ';dbname=' . DB_NAME . ';charset=' . DB_CHARSET, DB_USER, DB_PASS);
|
||
echo 'DB OK';
|
||
} catch (Exception \$e) {
|
||
exit(1);
|
||
}
|
||
" >/dev/null 2>&1; then
|
||
log_success "Подключение к базе данных работает"
|
||
else
|
||
log_error "Не удается подключиться к базе данных"
|
||
((errors++))
|
||
fi
|
||
else
|
||
log_error "Файл конфигурации БД не найден"
|
||
((errors++))
|
||
fi
|
||
|
||
if [ $errors -eq 0 ]; then
|
||
log_success "Все компоненты работают корректно"
|
||
return 0
|
||
else
|
||
log_error "Обнаружено $errors ошибок в работе системы"
|
||
return 1
|
||
fi
|
||
}
|
||
|
||
# Отображение итоговой информации
|
||
show_final_info() {
|
||
local db_password="$1"
|
||
local ip_addr=$(hostname -I | awk '{print $1}' 2>/dev/null || echo "N/A")
|
||
|
||
echo ""
|
||
echo "=============================================================="
|
||
if [ "$REINSTALL" = true ]; then
|
||
log_success "Переустановка Altcor успешно завершена!"
|
||
else
|
||
log_success "Установка Altcor успешно завершена!"
|
||
fi
|
||
echo "=============================================================="
|
||
echo ""
|
||
echo -e "${CYAN}🌐 Доступ к сайту:${NC}"
|
||
echo " • http://localhost/"
|
||
echo " • http://$ip_addr/"
|
||
echo ""
|
||
echo -e "${CYAN}💾 Доступ к БД:${NC}"
|
||
echo " • Хост: localhost"
|
||
echo " • Логин: root"
|
||
echo " • Пароль: $db_password"
|
||
echo " • База данных: ALTCor"
|
||
echo ""
|
||
echo -e "${CYAN}📁 Расположение файлов:${NC}"
|
||
echo " • Веб-корень: $WEBROOT"
|
||
echo " • Конфигурация БД: $WEBROOT/db_config.php"
|
||
echo " • Логи Apache: /var/log/apache2/ или /var/log/httpd/"
|
||
echo " • Лог установки: $LOG_FILE"
|
||
echo ""
|
||
echo -e "${CYAN}ℹ️ Дополнительная информация:${NC}"
|
||
echo " • Учетные данные БД: /root/.db_password"
|
||
echo " • Для удаления: $0 -u"
|
||
echo " • Для переустановки: $0 -r"
|
||
echo ""
|
||
echo -e "${GREEN}Система готова к работе!${NC}"
|
||
echo "=============================================================="
|
||
echo ""
|
||
}
|
||
|
||
# Основная функция установки
|
||
proceed_with_installation() {
|
||
echo ""
|
||
echo "🚀 Начинаем установку Altcor..."
|
||
echo ""
|
||
|
||
# Обновление системы и установка базовых пакетов
|
||
update_system
|
||
|
||
# Настройка репозиториев PHP 8.3
|
||
setup_php_repositories
|
||
|
||
# Установка основных компонентов
|
||
install_components
|
||
|
||
# Настройка Apache и PHP
|
||
configure_apache_php
|
||
|
||
# Настройка базы данных
|
||
local db_password
|
||
db_password=$(configure_database)
|
||
|
||
# Настройка веб-приложения
|
||
setup_web_application
|
||
|
||
# Запуск сервисов
|
||
start_services
|
||
|
||
# Финальная проверка
|
||
if final_verification; then
|
||
show_final_info "$db_password"
|
||
else
|
||
log_error "Установка завершена с ошибками. Проверьте лог: $LOG_FILE"
|
||
exit 1
|
||
fi
|
||
}
|
||
|
||
# Интерактивный выбор действий при обнаружении существующей установки
|
||
handle_existing_installation() {
|
||
local need_reinstall=$1
|
||
|
||
if [ $need_reinstall -eq 0 ]; then
|
||
if [ "$REINSTALL" = true ]; then
|
||
log_warning "Обнаружена существующая установка. Начинаем переустановку..."
|
||
return 1 # Требуется переустановка
|
||
else
|
||
log_success "Все компоненты уже установлены и работают корректно"
|
||
echo ""
|
||
echo -e "${YELLOW}Altcor уже полностью установлен и функционирует.${NC}"
|
||
echo ""
|
||
read -p "Хотите переустановить систему? [y/n]: " -n 1 -r
|
||
echo ""
|
||
if [[ $REPLY =~ ^[Yy]$ ]]; then
|
||
log_info "Начинаем переустановку по запросу пользователя..."
|
||
REINSTALL=true
|
||
return 1 # Требуется переустановка
|
||
else
|
||
echo ""
|
||
log_info "Переустановка отменена. Система остается без изменений."
|
||
echo ""
|
||
echo "Для принудительной переустановки используйте: $0 -r"
|
||
echo ""
|
||
exit 0
|
||
fi
|
||
fi
|
||
else
|
||
log_warning "Обнаружены проблемы с установленными компонентами."
|
||
echo ""
|
||
read -p "Хотите переустановить всю систему? [y/n]: " -n 1 -r
|
||
echo ""
|
||
if [[ $REPLY =~ ^[Yy]$ ]]; then
|
||
log_info "Начинаем полную переустановку..."
|
||
REINSTALL=true
|
||
return 1 # Требуется переустановка
|
||
else
|
||
log_info "Продолжаем обычную установку/обновление компонентов..."
|
||
return 0 # Продолжить обычную установку
|
||
fi
|
||
fi
|
||
}
|
||
|
||
# Главная функция
|
||
main() {
|
||
# Инициализация
|
||
log_to_file "=== Начало установки Altcor $(date) ==="
|
||
|
||
# Проверка прав администратора
|
||
check_root
|
||
|
||
# Определение дистрибутива
|
||
detect_distro
|
||
|
||
# Обработка различных режимов работы
|
||
if [ "$UNINSTALL" = true ]; then
|
||
full_uninstall
|
||
elif [ "$REINSTALL" = true ]; then
|
||
echo ""
|
||
log_step "Начинаем переустановку Altcor..."
|
||
echo ""
|
||
full_uninstall
|
||
proceed_with_installation
|
||
else
|
||
# Проверка существующей установки
|
||
local check_result=0
|
||
check_existing_installation || check_result=$?
|
||
|
||
local action_result=0
|
||
handle_existing_installation $check_result || action_result=$?
|
||
|
||
if [ $action_result -eq 1 ]; then
|
||
if [ "$REINSTALL" = true ]; then
|
||
full_uninstall
|
||
fi
|
||
proceed_with_installation
|
||
elif [ $action_result -eq 0 ]; then
|
||
proceed_with_installation
|
||
fi
|
||
fi
|
||
|
||
log_to_file "=== Завершение установки Altcor $(date) ==="
|
||
}
|
||
|
||
# Обработка сигналов для корректного завершения
|
||
trap 'log_error "Установка прервана пользователем"; exit 130' INT TERM
|
||
|
||
# Запуск основной функции
|
||
main "$@" |