#!/bin/bash # Скрипт для замены репозиториев на локальные российские зеркала # Поддерживает Debian 12/13 и AlmaLinux 8/9/10 # Как использовать: # # Установка: # wget -O setup-local-repos.sh https://t.mnogoweb.com/mnogoweb/bfc651ecb5b64d798a70eb9a7dee02e7/raw/HEAD/setup-local-repos.sh # chmod +x setup-local-repos.sh # # Основной режим: # sudo ./setup-local-repos.sh # # Проверить текущие репозитории: # sudo ./setup-local-repos.sh --check # # Откатить изменения: # sudo ./setup-local-repos.sh --rollback # # Подробный вывод: # sudo ./setup-local-repos.sh --verbose set -e # Выход при ошибках # Цвета для вывода RED='\033[0;31m' GREEN='\033[0;32m' YELLOW='\033[1;33m' BLUE='\033[0;34m' NC='\033[0m' # No Color # Функция для вывода с цветом print_message() { echo -e "${GREEN}[INFO]${NC} $1" } print_warning() { echo -e "${YELLOW}[WARN]${NC} $1" } print_error() { echo -e "${RED}[ERROR]${NC} $1" } print_debug() { echo -e "${BLUE}[DEBUG]${NC} $1" } # Функция для определения ОС detect_os() { if [ -f /etc/os-release ]; then . /etc/os-release OS_NAME="$ID" OS_VERSION="$VERSION_ID" OS_VERSION_MAJOR=$(echo "$OS_VERSION" | cut -d. -f1) OS_CODENAME="$VERSION_CODENAME" elif [ -f /etc/redhat-release ]; then if grep -qi "alma" /etc/redhat-release; then OS_NAME="almalinux" elif grep -qi "centos" /etc/redhat-release; then OS_NAME="centos" elif grep -qi "rocky" /etc/redhat-release; then OS_NAME="rocky" else OS_NAME="rhel" fi # Извлекаем версию из redhat-release OS_VERSION=$(grep -oE '[0-9]+\.[0-9]+' /etc/redhat-release | head -1) if [ -z "$OS_VERSION" ]; then OS_VERSION=$(grep -oE '[0-9]+' /etc/redhat-release | head -1) fi OS_VERSION_MAJOR=$(echo "$OS_VERSION" | cut -d. -f1) else print_error "Не удалось определить операционную систему" exit 1 fi print_message "Обнаружена ОС: $OS_NAME $OS_VERSION (мажорная версия: $OS_VERSION_MAJOR)" } # Функция для создания резервной копии файла backup_file() { local file="$1" local backup="${file}.backup.$(date +%Y%m%d_%H%M%S)" if [ -f "$file" ]; then cp "$file" "$backup" print_message "Создана резервная копия: $backup" echo "$backup" # Возвращаем имя резервной копии fi } # Функция для проверки доступности зеркала check_mirror() { local mirror="$1" local test_url="$2" print_debug "Проверка доступности зеркала: $mirror" if curl --silent --head --fail --max-time 5 "$test_url" > /dev/null 2>&1; then print_message "Зеркало $mirror доступно" return 0 else print_warning "Зеркало $mirror недоступно или отвечает медленно" return 1 fi } # Функции для Debian setup_debian_repos() { local version="$1" local sources_list="/etc/apt/sources.list" local sources_dir="/etc/apt/sources.list.d/" print_message "Настройка репозиториев для Debian $version" # Создаем резервную копию backup_file "$sources_list" # Российские зеркала для Debian # Список приоритетных зеркал (проверяем доступность) local mirrors=( "http://mirror.yandex.ru/debian/" "http://ftp.ru.debian.org/debian/" "http://mirror.truenetwork.ru/debian/" ) local selected_mirror="" local selected_security_mirror="" # Проверяем доступность зеркал for mirror in "${mirrors[@]}"; do if check_mirror "$mirror" "${mirror}dists/stable/Release"; then selected_mirror="$mirror" # Для зеркал безопасности используем соответствующие URL if [[ "$mirror" == *"mirror.yandex.ru"* ]]; then selected_security_mirror="http://mirror.yandex.ru/debian-security/" elif [[ "$mirror" == *"ftp.ru.debian.org"* ]]; then selected_security_mirror="http://ftp.ru.debian.org/debian-security/" else selected_security_mirror="${mirror%-}/debian-security/" fi break fi done # Если ни одно зеркало не доступно, используем Yandex по умолчанию if [ -z "$selected_mirror" ]; then print_warning "Все зеркала недоступны, используем Yandex по умолчанию" selected_mirror="http://mirror.yandex.ru/debian/" selected_security_mirror="http://mirror.yandex.ru/debian-security/" fi print_message "Используется основное зеркало: $selected_mirror" print_message "Используется зеркало безопасности: $selected_security_mirror" # Определяем кодовое имя релиза local codename case "$version" in "12") codename="bookworm" ;; "13") codename="trixie" ;; *) codename="bookworm" ;; # По умолчанию для других версий esac # Создаем новый sources.list с выбранными зеркалами cat > "$sources_list" << EOF # Российские зеркала для Debian $version ($codename) deb $selected_mirror $codename main contrib non-free non-free-firmware deb $selected_mirror $codename-updates main contrib non-free non-free-firmware deb $selected_security_mirror $codename-security main contrib non-free non-free-firmware # Дополнительные компоненты # deb $selected_mirror $codename-backports main contrib non-free non-free-firmware EOF # Обновляем репозитории в sources.list.d с помощью sed for file in "$sources_dir"*.list; do if [ -f "$file" ]; then backup_file "$file" print_debug "Обновление репозиториев в файле: $(basename "$file")" # Заменяем стандартные репозитории на российские зеркала sed -i \ -e "s|http://deb.debian.org/debian|$selected_mirror|g" \ -e "s|https://deb.debian.org/debian|$selected_mirror|g" \ -e "s|http://security.debian.org|$selected_security_mirror|g" \ -e "s|https://security.debian.org|$selected_security_mirror|g" \ -e "s|http://ftp.debian.org|$selected_mirror|g" \ -e "s|https://ftp.debian.org|$selected_mirror|g" \ "$file" fi done print_message "Обновление списка пакетов..." if apt-get update; then print_message "Список пакетов успешно обновлен" else print_warning "Обновление списка пакетов завершилось с предупреждениями" fi } # Функции для AlmaLinux setup_almalinux_repos() { local version="$1" local repo_dir="/etc/yum.repos.d/" print_message "Настройка репозиториев для AlmaLinux $version" # Российские зеркала для AlmaLinux local mirrors=( "http://mirror.yandex.ru/almalinux/" "http://mirror.nucleus.be/almalinux/" # Российское зеркало Selectel "http://mirror.docker.ru/almalinux/" ) local selected_mirror="" # Проверяем доступность зеркал for mirror in "${mirrors[@]}"; do if check_mirror "$mirror" "${mirror}${version}/BaseOS/x86_64/os/repodata/repomd.xml"; then selected_mirror="$mirror" break fi done # Если ни одно зеркало не доступно, используем Yandex по умолчанию if [ -z "$selected_mirror" ]; then print_warning "Все зеркала недоступны, используем Yandex по умолчанию" selected_mirror="http://mirror.yandex.ru/almalinux/" fi print_message "Используется зеркало: $selected_mirror" # Создаем резервные копии всех репозиториев print_message "Создание резервных копий репозиториев..." for repo_file in "$repo_dir"*.repo; do if [ -f "$repo_file" ]; then backup_file "$repo_file" fi done # Основные файлы репозиториев для AlmaLinux local repo_files=( "almalinux.repo" "almalinux-baseos.repo" "almalinux-appstream.repo" "almalinux-extras.repo" "almalinux-powertools.repo" # Для версии 8 "almalinux-crb.repo" # Для версий 9+ ) # Список паттернов для замены local patterns=( "https://repo.almalinux.org" "http://repo.almalinux.org" "https://mirror.almalinux.org" "http://mirror.almalinux.org" "https://cdn.redhat.com" "http://cdn.redhat.com" ) # Заменяем URL во всех репозиторных файлах с помощью sed print_message "Замена URL репозиториев на российские зеркала..." for repo_file in "$repo_dir"*.repo; do if [ -f "$repo_file" ]; then local filename=$(basename "$repo_file") print_debug "Обработка файла: $filename" # Создаем временный файл для новой конфигурации local temp_file=$(mktemp) # Обрабатываем файл построчно while IFS= read -r line; do # Заменяем baseurl и metalink if [[ "$line" =~ ^(baseurl|metalink)\s*= ]]; then # Заменяем все паттерны на выбранное зеркало local new_line="$line" for pattern in "${patterns[@]}"; do new_line="${new_line//$pattern/$selected_mirror}" done # Для baseurl добавляем параметры репозитория if [[ "$new_line" =~ ^baseurl= ]] && [[ ! "$new_line" =~ /\$releasever/ ]]; then new_line="baseurl=$selected_mirror\$releasever/\$basearch/os/" fi echo "$new_line" >> "$temp_file" else echo "$line" >> "$temp_file" fi done < "$repo_file" # Заменяем оригинальный файл mv "$temp_file" "$repo_file" # Дополнительная обработка sed для надежности sed -i \ -e "s|https://repo.almalinux.org|$selected_mirror|gI" \ -e "s|http://repo.almalinux.org|$selected_mirror|gI" \ -e "s|https://mirror.almalinux.org|$selected_mirror|gI" \ -e "s|http://mirror.almalinux.org|$selected_mirror|gI" \ -e "s|https://cdn.redhat.com|$selected_mirror|gI" \ -e "s|http://cdn.redhat.com|$selected_mirror|gI" \ "$repo_file" # Отключаем metalink и включаем baseurl sed -i \ -e '/^metalink/s/^/#/' \ -e '/^#baseurl/s/^#//' \ -e '/^mirrorlist/s/^/#/' \ "$repo_file" fi done # Специфичные настройки для разных версий case "$version" in "8") # Для версии 8 for repo_file in "$repo_dir"almalinux*.repo; do if [ -f "$repo_file" ]; then sed -i \ -e "s|/AppStream/|/AppStream/|g" \ -e "s|/PowerTools/|/PowerTools/|g" \ -e "s|/BaseOS/|/BaseOS/|g" \ "$repo_file" fi done ;; "9"|"10") # Для версий 9 и 10 for repo_file in "$repo_dir"almalinux*.repo; do if [ -f "$repo_file" ]; then sed -i \ -e "s|/AppStream/|/AppStream/|g" \ -e "s|/CRB/|/CRB/|g" \ -e "s|/BaseOS/|/BaseOS/|g" \ "$repo_file" fi done ;; esac print_message "Очистка кэша DNF..." dnf clean all print_message "Проверка доступности репозиториев..." if dnf repolist -v; then print_message "Репозитории успешно настроены" # Показываем информацию о репозиториях echo "" print_message "Список активных репозиториев:" dnf repolist enabled else print_warning "Есть проблемы с доступностью репозиториев" print_warning "Проверьте настройки сети или выберите другое зеркало" fi } # Функция для проверки текущих репозиториев check_current_repos() { print_message "Текущие репозитории:" case "$OS_NAME" in "debian") grep -h "^deb" /etc/apt/sources.list /etc/apt/sources.list.d/*.list 2>/dev/null | head -10 ;; "almalinux") grep -h "^\s*baseurl" /etc/yum.repos.d/*.repo 2>/dev/null | head -10 ;; esac } # Функция для отката изменений rollback_changes() { print_message "Поиск резервных копий для отката..." case "$OS_NAME" in "debian") local backup_files=$(find /etc/apt -name "*.backup.*" -type f | sort -r) ;; "almalinux") local backup_files=$(find /etc/yum.repos.d -name "*.backup.*" -type f | sort -r) ;; esac if [ -z "$backup_files" ]; then print_error "Резервные копии не найдены" return 1 fi # Берем последнюю резервную копию local latest_backup=$(echo "$backup_files" | head -1) local original_file="${latest_backup%.backup.*}" print_message "Восстановление из: $latest_backup" print_message "В файл: $original_file" if cp "$latest_backup" "$original_file"; then print_message "Откат выполнен успешно" # Обновляем кэш пакетов case "$OS_NAME" in "debian") apt-get update ;; "almalinux") dnf clean all dnf repolist ;; esac else print_error "Ошибка при откате изменений" fi } # Основная функция main() { # Проверяем права суперпользователя if [ "$EUID" -ne 0 ]; then print_error "Запустите скрипт с правами root (sudo)" exit 1 fi print_message "Начало настройки локальных репозиториев..." # Определяем ОС detect_os # Показываем текущие репозитории check_current_repos echo "" print_warning "Вы собираетесь заменить репозитории на российские зеркала." print_warning "Будут созданы резервные копии конфигурационных файлов." echo "" read -p "Продолжить? (y/N): " -n 1 -r echo if [[ ! $REPLY =~ ^[Yy]$ ]]; then print_message "Операция отменена пользователем" exit 0 fi # Выбираем действие в зависимости от ОС case "$OS_NAME" in "debian") setup_debian_repos "$OS_VERSION_MAJOR" ;; "almalinux") setup_almalinux_repos "$OS_VERSION_MAJOR" ;; "centos"|"rocky"|"rhel") print_warning "Обнаружена $OS_NAME, будет применена конфигурация для AlmaLinux" setup_almalinux_repos "$OS_VERSION_MAJOR" ;; *) print_error "Неподдерживаемая операционная система: $OS_NAME" print_warning "Поддерживаются только Debian, AlmaLinux, CentOS, Rocky Linux и RHEL" exit 1 ;; esac echo "" print_message "Настройка репозиториев успешно завершена!" print_warning "Рекомендуется проверить работоспособность репозиториев:" case "$OS_NAME" in "debian") echo " apt update && apt install -y neofetch" ;; "almalinux"|"centos"|"rocky"|"rhel") echo " dnf update && dnf install -y neofetch" ;; esac } # Обработка аргументов командной строки if [[ $# -gt 0 ]]; then case $1 in "-h"|"--help") echo "Использование: $0 [OPTIONS]" echo "Скрипт для замены штатных репозиториев на локальные российские зеркала" echo "" echo "Опции:" echo " -h, --help Показать эту справку" echo " -c, --check Проверить текущие репозитории" echo " -r, --rollback Откатить последние изменения" echo " -v, --verbose Подробный вывод" echo "" echo "Поддерживаемые ОС:" echo " - Debian 12 (Bookworm)" echo " - Debian 13 (Trixie)" echo " - AlmaLinux 8" echo " - AlmaLinux 9" echo " - AlmaLinux 10" echo " - CentOS/Rocky Linux/RHEL 8/9/10" echo "" echo "Автоматически создаются резервные копии конфигурационных файлов" exit 0 ;; "-c"|"--check") detect_os check_current_repos exit 0 ;; "-r"|"--rollback") detect_os rollback_changes exit 0 ;; "-v"|"--verbose") set -x # Включить режим отладки main ;; *) print_error "Неизвестный аргумент: $1" echo "Используйте $0 --help для справки" exit 1 ;; esac else # Запуск основной функции main fi