diff --git a/add_domain.py b/add_domain.py new file mode 100644 index 0000000..8f7451c --- /dev/null +++ b/add_domain.py @@ -0,0 +1,132 @@ +#!/usr/bin/env python3 +import os +import subprocess +import sys +import re + +# GUI +import tkinter as tk +from tkinter import messagebox, simpledialog + +def get_domain(): + try: + with open("/etc/resolv.conf", "r") as f: + for line in f: + if line.strip().startswith("search"): + parts = line.split() + if len(parts) > 1: + return parts[1] + except: + pass + return None + +def update_hosts_file(fqdn, short_hostname): + hosts_path = "/etc/hosts" + try: + with open(hosts_path, "r") as f: + lines = f.readlines() + + new_lines = [line for line in lines if not line.strip().startswith("127.0.")] + new_lines.insert(0, f"127.0.1.1 {fqdn} {short_hostname}\n") + new_lines.insert(0, "127.0.0.1 localhost localhost.localdomain\n") + + with open(hosts_path, "w") as f: + f.writelines(new_lines) + except Exception as e: + raise Exception(f"Ошибка редактирования /etc/hosts: {e}") + +def update_fly_dmrc(domain): + path = "/etc/X11/fly-dm/fly-dmrc" + try: + with open(path, "r") as f: + lines = f.readlines() + + new_lines = [line for line in lines if not line.strip().startswith("PluginOptions=")] + new_lines.append(f"PluginOptions=winbind.DefaultDomain={domain},winbind.Domains={domain}:\n") + + with open(path, "w") as f: + f.writelines(new_lines) + except Exception as e: + print(f"Предупреждение: не удалось отредактировать fly-dmrc: {e}") + +def main(): + root = tk.Tk() + root.withdraw() + + try: + if os.geteuid() != 0: + messagebox.showerror("Ошибка", "Запустите скрипт с правами root (sudo)") + sys.exit(1) + + domain = get_domain() + if not domain: + messagebox.showerror("Ошибка", "Не удалось определить домен из /etc/resolv.conf") + sys.exit(1) + + if os.path.exists("/etc/krb5.keytab"): + messagebox.showerror("Ошибка", "АРМ уже в домене. Сначала выведите его из домена.") + sys.exit(1) + + hostname = simpledialog.askstring("Ввод", "Имя АРМ (короткое):") + if not hostname: sys.exit(0) + + username = simpledialog.askstring("Ввод", "Имя пользователя для ввода в домен:") + if not username: sys.exit(0) + + ### Ввод пароля (show='*' скрывает символы) + password = simpledialog.askstring("Авторизация", f"Введите пароль для пользователя {username}:", show='*') + if not password: sys.exit(0) + + if not hostname.strip() or not username.strip(): + messagebox.showerror("Ошибка", "Поля не могут быть пустыми") + sys.exit(1) + + fqdn = f"{hostname.strip()}.{domain}" + + if not messagebox.askyesno("Подтверждение", f"FQDN: {fqdn}\nДомен: {domain}\nПользователь: {username}\n\nПродолжить?"): + sys.exit(0) + + if os.path.exists("/opt/config/ad_setup.sh"): + subprocess.run("/opt/config/ad_setup.sh", check=False) + + subprocess.run(f"hostnamectl set-hostname {fqdn}", shell=True, check=True) + + update_hosts_file(fqdn, hostname.strip()) + + # adcli join (ПЕРЕДАЕМ ПАРОЛЬ ЧЕРЕЗ stdin) + astra_version = "unknown" + try: + with open("/etc/astra_version", "r") as f: + astra_version = f.read().strip() + except: pass + + cmd = [ + "adcli", "join", + "--os-name=astralinux", + f"--os-version={astra_version}", + "-U", username, + "-D", domain, + "--stdin-password" + ] + + # ВАЖНО: input=password передает пароль в stdin команды + subprocess.run(cmd, input=password, text=True, check=True) + + update_fly_dmrc(domain) + + subprocess.run("systemctl enable sssd", shell=True, check=True) + subprocess.run("systemctl restart sssd", shell=True, check=True) + + messagebox.showinfo("Успех", "АРМ успешно введен в домен и настроен.") + + except subprocess.CalledProcessError as e: + messagebox.showerror("Ошибка", f"Команда завершилась с ошибкой.\nВозможно, неверный пароль или имя пользователя.\n\nКоманда: {e.cmd}") + sys.exit(1) + except Exception as e: + messagebox.showerror("Ошибка", f"Произошла ошибка:\n{e}") + sys.exit(1) + finally: + root.destroy() + +if __name__ == "__main__": + main() \ No newline at end of file diff --git a/admin-helper.py b/admin-helper.py new file mode 100644 index 0000000..1556a9c --- /dev/null +++ b/admin-helper.py @@ -0,0 +1,205 @@ +#!/usr/bin/env python3 +import tkinter as tk +from tkinter import messagebox +import tkinter.ttk as ttk +import urllib.request +import json +import tempfile +import subprocess +import sys +import os +import threading +from urllib.parse import urljoin + +# Список серверов +SERVERS = [ + {"name": "Гринатом (МСК)", "url": "http://gren-s-synd01.gk.rosatom.local/admin_helper/"}, + {"name": "Гринатом (НН)", "url": "http://grenn-s-synd01.gk.rosatom.local/admin_helper/"}, + {"name": "ГК Росатом", "url": "http://gkrs-s-synd01.gk.rosatom.local/admin_helper/"}, +] + +# Имя файла описания (manifest) +MANIFEST_FILE = "scripts.json" + +class AdminHelper: + def __init__(self, root): + self.root = root + self.root.title("Admin Helper (Linux)") + self.root.geometry("500x450") + + # --- Верхняя панель (Выпадающий список) --- + self.server_frame = tk.Frame(root, pady=10, bg="#f0f0f0") + self.server_frame.pack(fill='x') + tk.Label(self.server_frame, text="Сервер:", bg="#f0f0f0", font=("Arial", 10, "bold")).pack(side='left', padx=5) + # Создаем выпадающий список + server_names = [s['name'] for s in SERVERS] + self.server_combo = ttk.Combobox( + self.server_frame, + values=server_names, + state="readonly", # Запрещаем ручной ввод, можно только выбирать + width=30 + ) + self.server_combo.pack(side='left', padx=5) + # Если есть серверы, выбираем первый по умолчанию + if server_names: + self.server_combo.current(0) + # Кнопка "Загрузить" для явного вызова + self.btn_connect = tk.Button( + self.server_frame, + text="Загрузить скрипты", + command=self.on_server_select + ) + self.btn_connect.pack(side='left', padx=5) + self.server_combo.bind("<>") + self.active_server_label = tk.Label(root, text="Выберите сервер", fg="blue") + self.active_server_label.pack(pady=(0, 10)) + + # --- Основная часть (Скролл) --- + self.main_frame = tk.Frame(root) + self.main_frame.pack(expand=True, fill='both') + + self.label_title = tk.Label( + self.main_frame, + text="Выберите действие", + font=("Arial", 14) + ) + self.label_title.pack(pady=10) + + self.canvas = tk.Canvas(self.main_frame) + self.scrollbar = tk.Scrollbar(self.main_frame, orient="vertical", command=self.canvas.yview) + self.scrollable_frame = tk.Frame(self.canvas) + + self.scrollable_frame.bind( + "", + lambda e: self.canvas.configure(scrollregion=self.canvas.bbox("all")) + ) + + self.canvas.create_window((0, 0), window=self.scrollable_frame, anchor="nw") + self.canvas.configure(yscrollcommand=self.scrollbar.set) + + self.canvas.pack(side="left", fill="both", expand=True, padx=20) + self.scrollbar.pack(side="right", fill="y") + + self.status_label = tk.Label(root, text="Ожидание...", bd=1, relief=tk.SUNKEN, anchor=tk.W) + self.status_label.pack(side=tk.BOTTOM, fill=tk.X) + + def on_server_select(self, event=None): + """Срабатывает при выборе сервера из списка""" + selected_name = self.server_combo.get() + + # Ищем данные сервера в общем списке по имени + server_info = next((s for s in SERVERS if s['name'] == selected_name), None) + + if server_info: + self.connect_to_server(server_info) + else: + self.status_label.config(text="Ошибка: сервер не найден") + + def connect_to_server(self, server_info): + base_url = server_info['url'] + name = server_info['name'] + self.active_server_label.config(text=f"Активен: {name}") + + # Очистка + for widget in self.scrollable_frame.winfo_children(): + widget.destroy() + + self.status_label.config(text=f"Загрузка {MANIFEST_FILE}...") + thread = threading.Thread(target=self.load_scripts_from_json, args=(base_url,), daemon=True) + thread.start() + + def download_content(self, url): + """Универсальный загрузчик (текст или бинарник)""" + try: + headers = {'User-Agent': 'Mozilla/5.0'} + req = urllib.request.Request(url, headers=headers) + with urllib.request.urlopen(req) as response: + return response.read() + except Exception as e: + print(f"Ошибка загрузки {url}: {e}") + return None + + def load_scripts_from_json(self, base_url): + # 1. Формируем ссылку на JSON-файл + manifest_url = urljoin(base_url, MANIFEST_FILE) + json_data = self.download_content(manifest_url) + + if not json_data: + self.root.after(0, lambda: self.status_label.config(text="Ошибка: не найден scripts.json")) + return + + # 2. Парсим JSON + try: + script_list = json.loads(json_data) + except json.JSONDecodeError: + self.root.after(0, lambda: self.status_label.config(text="Ошибка: неверный формат JSON")) + return + + # 3. Проходим по списку и скачиваем файлы + count = 0 + for item in script_list: + name = item.get('name', 'Без имени') + filename = item.get('file') + + if not filename: + continue + + script_url = urljoin(base_url, filename) + content = self.download_content(script_url) + + if content: + # Определяем тип по расширению + file_ext = filename.split('.')[-1].lower() + + # Создаем кнопку + self.root.after(0, lambda n=name, c=content, f=filename, ext=file_ext: self.create_action_button(n, c, f, ext)) + count += 1 + + if count == 0: + self.root.after(0, lambda: self.status_label.config(text="Нет доступных скриптов")) + else: + self.root.after(0, lambda: self.status_label.config(text=f"Загружено: {count} скриптов")) + + def create_action_button(self, text, content, filename, ext): + btn = tk.Button( + self.scrollable_frame, + text=text, + width=40, + height=2, + anchor="w" + ) + btn.config(command=lambda c=content, f=filename, e=ext: self.run_file(c, f, e)) + + btn.pack(pady=2, fill='x') + + def run_file(self, content, filename, ext): + try: + # Создаем временный файл + with tempfile.NamedTemporaryFile(mode='wb', suffix=f'.{ext}', delete=False) as tmp_file: + tmp_file.write(content) + tmp_path = tmp_file.name + + # Логика запуска для Linux + if ext == 'bin': + # 1. Делаем файл исполняемым (chmod +x) + os.chmod(tmp_path, 0o755) + # 2. Запускаем напрямую + subprocess.Popen([tmp_path]) + + elif ext == 'sh': + os.chmod(tmp_path, 0o755) + subprocess.Popen(['xterm', '-e', tmp_path]) + + else: + messagebox.showwarning("Внимание", f"Неизвестный тип файла: {ext}") + + # ИЗМЕНЕНИЕ: Убрали всплывающее окно, просто пишем в статус-бар + self.status_label.config(text=f"Запущен: {filename}") + + except Exception as e: + messagebox.showerror("Ошибка", f"Не удалось запустить: {e}") + +if __name__ == "__main__": + root = tk.Tk() + app = AdminHelper(root) + root.mainloop() diff --git a/admin_helper.txt b/admin_helper.txt new file mode 100644 index 0000000..56190f1 --- /dev/null +++ b/admin_helper.txt @@ -0,0 +1,6 @@ +Графическая оболочка для запуска скриптов с сервера управления +Требуется наличие связи с сервером + +Поддерживаемые предприятия: +Гринатом (МСК) +Гринатом (НН) diff --git a/custom_update_lsp.sh b/custom_update_lsp.sh new file mode 100644 index 0000000..51889b9 --- /dev/null +++ b/custom_update_lsp.sh @@ -0,0 +1,446 @@ +#!/usr/bin/env bash +# ============================================== +# Скрипт поэтапного обновления Astra Linux +# ============================================== +# Цвета +RED='\033[0;31m' +GREEN='\033[0;32m' +YELLOW='\033[1;33m' +BLUE='\033[0;34m' +CYAN='\033[0;36m' +BOLD='\033[1m' +RESET='\033[0m' +# Иконки +CHECK="✅" +ERROR="❌" +WARN="⚠️" +ARROW="➜" +ROCKET="🚀" + +# Путь к маркер-файлу +MARKER_FILE="/opt/config/custom_update_status.info" +VERSION_FILE="/etc/astra/build_version" +TARGET_VERSION="1.7.10.72" + +# ============================================== +# Функции работы с маркер-файлом +# ============================================== + +init_marker() { + mkdir -p "$(dirname "$MARKER_FILE")" 2>/dev/null + # Если файла нет - создаем со статусом 5 + if [[ ! -f "$MARKER_FILE" ]]; then + echo "5" > "$MARKER_FILE" + echo -e "${BLUE} Создан маркер-файл: ${MARKER_FILE}${RESET}" + fi +} + +get_status() { + if [[ -f "$MARKER_FILE" ]]; then + cat "$MARKER_FILE" | tr -d ' \t\n\r' + else + echo "5" + fi +} + +set_status() { + echo "$1" > "$MARKER_FILE" + echo -e "${BLUE} Статус обновления: ${BOLD}$1${RESET}" +} + +show_status_info() { + local status=$(get_status) + echo -e "\n${BOLD}${CYAN}━━━ Статус обновления ━━━${RESET}" + case $status in + 1072) + echo -e "${GREEN}${CHECK} Система актуальна (версия $CURRENT_VERSION)${RESET}" + echo -e "${GREEN}${CHECK} Обновление не требуется${RESET}" + ;; + 1) + echo -e "${YELLOW}${WARN} Статус: ${BOLD}1 этап завершен${RESET}" + echo -e "${YELLOW}${WARN} Требуется продолжить обновление (2 этап)${RESET}" + ;; + 2) + echo -e "${YELLOW}${WARN} Статус: ${BOLD}2 этап завершен${RESET}" + echo -e "${YELLOW}${WARN} Требуется продолжить обновление (3 этап)${RESET}" + ;; + 5) + echo -e "${GREEN}${CHECK} Система (версия $CURRENT_VERSION)${RESET}" + echo -e "${GREEN}${CHECK} Обновление не утилитой не выполнялось${RESET}" + ;; + *) + echo -e "${RED}${ERROR} Неизвестный статус: $status${RESET}" + ;; + esac + echo "" +} + +# ============================================== +# Шаг 1: Проверяем права root +# ============================================== + +check_root() { + echo -e "\n${BOLD}${BLUE}════════════════════════════════════════${RESET}" + echo -e "${BOLD}${CYAN} 🔄 ПОЭТАПНОЕ ОБНОВЛЕНИЕ ASTRA LINUX${RESET}" + echo -e "${BOLD}${BLUE}════════════════════════════════════════${RESET}\n" + + if [[ $EUID -ne 0 ]]; then + echo -e "${RED}${ERROR} Ошибка: нужны права root!${RESET}" + echo -e "${YELLOW}Используйте: sudo $0${RESET}\n" + read -p "Нажмите Enter для завершения..." + exit 1 + else + echo -e "${GREEN}${CHECK} Права root: OK${RESET}" + fi +} + +# ============================================== +# Шаг 2: Читаем версию +# ============================================== + +get_current_version() { + if [[ -f "$VERSION_FILE" ]]; then + CURRENT_VERSION=$(cat "$VERSION_FILE" | tr -d ' \t\n\r') + echo -e "${GREEN}${CHECK} Текущая версия: ${BOLD}${CYAN}$CURRENT_VERSION${RESET}" + else + echo -e "${RED}${ERROR} Файл версии не найден: $VERSION_FILE${RESET}" + CURRENT_VERSION="unknown" + read -p "Нажмите Enter для завершения..." + exit 1 + fi +} + +# ============================================== +# Шаг 3: Проверяем статус и версию +# ============================================== + +check_status_and_version() { + local status=$(get_status) + + echo "" + + # Если система уже обновлена до целевой версии + if [[ "$CURRENT_VERSION" == "$TARGET_VERSION" ]]; then + echo -e "${GREEN}${CHECK} ${BOLD}Система обновлена до версии $TARGET_VERSION${RESET}" + + # Если статус 0 - всё хорошо, выходим + if [[ "$status" == "1072" ]]; then + echo -e "${GREEN}${CHECK} Все этапы завершены${RESET}\n" + read -p "Нажмите Enter для завершения..." + exit 0 + fi + + # Если статус 1 - система обновлена, но защита не установлена + if [[ "$status" == "1" ]]; then + echo -e "${YELLOW}${WARN} Система обновлена, но защита не установлена${RESET}" + echo -e "${CYAN}${ARROW} Продолжаем со 2 этапа${RESET}" + STAGE=2 + return + fi + + # Если статус 2 - защита установлена, нужна чистка + if [[ "$status" == "2" ]]; then + echo -e "${YELLOW}${WARN} Защита установлена, требуется чистка${RESET}" + echo -e "${CYAN}${ARROW} Продолжаем с 3 этапа${RESET}" + STAGE=3 + return + fi + fi + + # Если версия ниже целевой + echo -e "${YELLOW}${WARN} Текущая версия ($CURRENT_VERSION) ниже целевой ($TARGET_VERSION)${RESET}" + show_status_info + + # Определяем этап на основе статуса + case $status in + 5) + echo -e "${CYAN}${ARROW} Начинаем обновление с 1 этапа${RESET}" + STAGE=1 + ;; + 1) + echo -e "${CYAN}${ARROW} Продолжаем со 2 этапа (установка защиты)${RESET}" + STAGE=2 + ;; + 2) + echo -e "${CYAN}${ARROW} Продолжаем с 3 этапа (чистка и исправление)${RESET}" + STAGE=3 + ;; + *) + echo -e "${RED}${ERROR} Неизвестный статус, сбрасываем на 5${RESET}" + set_status 5 + STAGE=1 + ;; + esac + echo "" +} + +# ============================================== +# Шаг 4: Запрос на обновление +# ============================================== + +ask_update() { + local message="" + + case $STAGE in + 1) + message="Начать обновление системы до версии $TARGET_VERSION (1 этап)? После завершения потребуется перезагрузка" + ;; + 2) + message="Установить корпоративную систему защиты (2 этап)? После завершения потребуется перезагрузка" + ;; + 3) + message="Выполнить чистку системы и исправление багов (3 этап)?" + ;; + esac + + echo "" + read -p "$(echo -e ${YELLOW}${message} [y/N]: ${RESET})" -n 1 -r + echo "" + + if [[ $REPLY =~ ^[Yy]$ ]]; then + echo -e "\n${GREEN}${ROCKET} Запускаем этап $STAGE...${RESET}\n" + return 0 + else + echo -e "\n${YELLOW}${WARN} Обновление отменено пользователем${RESET}\n" + read -p "Нажмите Enter для завершения..." + exit 0 + fi +} + +# ============================================== +# ЭТАП 1: Обновление системы до 1.7.10 +# ============================================== + +stage1_update_system() { + echo -e "${BOLD}${BLUE}━━━ ЭТАП 1: Обновление системы до $TARGET_VERSION ━━━${RESET}\n" + + mgmt_server=$(awk -F' *= *' '/^ *server *=/{print $2}' /etc/puppetlabs/puppet/puppet.conf) + if [[ -z "$mgmt_server" ]]; then + echo -e "${RED}${ERROR} Не удалось получить адрес сервера управления из $puppet_conf${RESET}" + read -p "Нажмите Enter для завершения..." + exit 1 + fi + echo -e "${GREEN}${CHECK} Сервер управления: ${BOLD}${CYAN}$mgmt_server${RESET}" + + echo -e "\n${BLUE Остановка и отключение службы Puppet...${RESET}" + systemctl stop puppet.service 2>/dev/null + systemctl disable puppet.service 2>/dev/null + sleep 5 + + echo -e "\n${BLUE} Настройка репозиториев Astra...${RESET}" + repo_file="/etc/apt/sources.list" + cat > "$repo_file" << EOF +# Astra Linux 1.7.10 репозитории +# Сервер управления: ${mgmt_server} +# Сгенерировано: $(date) + +deb http://${mgmt_server}/astra/1.7.10/repository-base/ 1.7_x86-64 contrib main non-free +deb http://${mgmt_server}/astra/1.7.10/repository-update/ 1.7_x86-64 contrib main non-free +deb http://${mgmt_server}/astra/1.7.10/repository-extended/ 1.7_x86-64 contrib main non-free +deb [trusted=yes] http://${mgmt_server}/astra/1.7/custom/ 1.7_x86-64 contrib main non-free +EOF + + if [[ $? -eq 0 ]]; then + echo -e "${GREEN}${CHECK} Репозитории настроены: $repo_file${RESET}" + else + echo -e "${RED}${ERROR} Ошибка настройки репозиториев${RESET}" + read -p "Нажмите Enter для завершения..." + exit 1 + fi + + echo -e "\n${BLUE} Очистка старых репозиториев...${RESET}" + + if ls /etc/apt/sources.list.d/*.list 2>/dev/null 1>/dev/null; then + echo -e "${YELLOW}${WARN} Найдены файлы в /etc/apt/sources.list.d/${RESET}" + echo -e "${BLUE} Файлы для удаления:${RESET}" + ls -la /etc/apt/sources.list.d/*.list 2>/dev/null || echo " (нет .list файлов)" + rm -f /etc/apt/sources.list.d/*.list 2>/dev/null + echo -e "${GREEN}${CHECK} Все .list файлы удалены${RESET}" + else + echo -e "${GREEN}${CHECK} Папка /etc/apt/sources.list.d/ пуста${RESET}" + fi + + echo -e "\n${BLUE} Обновление списка пакетов...${RESET}" + apt update + sleep 3 + + echo -e "\n${BLUE} Загрузка пакетов...${RESET}" + apt dist-upgrade --download-only -y + + echo -e "\n${BLUE} Подготовка системы к обновлению...${RESET}" + dpkg -s gk-kvm >/dev/null 2>&1 && { apt update && apt install --only-upgrade gk-kvm; } || true + dpkg -s secretnet >/dev/null 2>&1 && { sudo dpkg -P secretnet; } || true + dpkg -s sns >/dev/null 2>&1 && { sudo dpkg -P sns; } || true + dpkg -s gk-kvm >/dev/null 2>&1 && { tarm_unlock; } || true + echo performance | sudo tee /sys/devices/system/cpu/cpu*/cpufreq/scaling_governor + + echo -e "${BLUE} Выполняется обновление...${RESET}" + /usr/sbin/astra-update -A -r -T -K || { + echo -e "${RED}${ERROR} Ошибка обновления пакетов${RESET}" + read -p "Нажмите Enter для завершения..." + exit 1 + } + + /usr/bin/apt -o Dpkg::Options::='--force-confold' install -y gk-eosdo xrdp astra-version --reinstall + dpkg -s gk-kvm >/dev/null 2>&1 && { /usr/bin/apt -o Dpkg::Options::='--force-confold' install -y gk-kvm --reinstall; } || true + dpkg -s gk-kvm >/dev/null 2>&1 && { tarm_lock; } || true + + if [[ -f "$VERSION_FILE" ]]; then + NEW_VERSION=$(cat "$VERSION_FILE" | tr -d ' \t\n\r') + if [[ "$NEW_VERSION" == "$TARGET_VERSION" ]]; then + echo -e "${GREEN}${CHECK} ${BOLD}Система успешно обновлена до $TARGET_VERSION${RESET}" + else + echo -e "${RED}${ERROR} Версия системы: $NEW_VERSION (ожидалось $TARGET_VERSION)${RESET}" + echo -e "${RED}${ERROR} Обновление прошло с ошибкой!${RESET}" + read -p "Нажмите Enter для завершения..." + exit 1 + fi + fi + + # Устанавливаем статус 1 + set_status 1 + + echo -e "\n${GREEN}${CHECK} ${BOLD}1 этап завершен! Система обновлена до $TARGET_VERSION${RESET}" + echo -e "${YELLOW} Требуется перезагрузка для продолжения${RESET}" + echo -e "${YELLOW} После перезагрузки запустите скрипт снова ${RESET}\n" + ask_reboot +} + +# ============================================== +# ЭТАП 2: Установка корпоративной системы защиты +# ============================================== + +stage2_install_security() { + mgmt_server=$(awk -F' *= *' '/^ *server *=/{print $2}' /etc/puppetlabs/puppet/puppet.conf) + if [[ -z "$mgmt_server" ]]; then + echo -e "${RED}${ERROR} Не удалось получить адрес сервера управления из $puppet_conf${RESET}" + read -p "Нажмите Enter для завершения..." + exit 1 + fi + echo -e "${BOLD}${BLUE}━━━ ЭТАП 2: Установка Secret Net ━━━${RESET}\n" + + if [[ -f "$VERSION_FILE" ]]; then + CURRENT_VER=$(cat "$VERSION_FILE" | tr -d ' \t\n\r') + if [[ "$CURRENT_VER" != "$TARGET_VERSION" ]]; then + echo -e "${RED}${ERROR} Система не обновлена до $TARGET_VERSION (текущая: $CURRENT_VER)${RESET}" + echo -e "${RED}${ERROR} Сначала выполните 1 этап обновления${RESET}" + read -p "Нажмите Enter для завершения..." + exit 1 + fi + fi + + echo -e "${BLUE} Установка SecretNet...${RESET}" + cd /tmp/ + wget http://$mgmt_server/SN/secretnet_1.12-4844.astra1.7_amd64.deb + apt install -y /tmp/secretnet_1.12-4844.astra1.7_amd64.deb + echo -e "${BLUE} Установка SecretNet выполнена${RESET}" + + # Устанавливаем статус 2 + set_status 2 + + echo -e "\n${GREEN}${CHECK} ${BOLD}2 этап завершен! Secretnet установлен${RESET}" + echo -e "${YELLOW} Требуется перезагрузка для продолжения${RESET}" + echo -e "${YELLOW} После перезагрузки запустите скрипт снова ${RESET}\n" + ask_reboot +} + +# ============================================== +# ЭТАП 3: Чистка системы и исправление багов +# ============================================== + +stage3_clean_and_fix() { + echo -e "${BOLD}${BLUE}━━━ ЭТАП 3: Чистка системы и исправление багов ━━━${RESET}\n" + + echo -e "${BLUE} Запуск puppet...${RESET}" + /opt/puppetlabs/bin/puppet agent -t; + /opt/puppetlabs/bin/puppet agent -t; + + echo -e "${BLUE} Финальное обновление пакетов...${RESET}" + /usr/sbin/astra-update -A -r -T + + echo -e "${BLUE} Исправление печати kerberos...${RESET}" + rm /usr/lib/cups/backend/smb + ln -s /usr/libexec/samba/smbspool_krb5_wrapper /usr/lib/cups/backend/smb + chmod 700 /usr/lib/cups/backend/smb + + echo -e "${BLUE} Очистка старых ядер...${RESET}" + base_kernel=$(uname -r | sed "s/\(.*\)-\([^0-9]\+\)/\1/") + + kernels_to_remove=$(dpkg -l 'linux-*' | sed -n '/^ii/p' | \ + sed "/$base_kernel/d" | \ + sed 's/^[^ ]* [^ ]* \([^ ]*\).*/\1/' | \ + sed -n '/[0-9]/p' | \ + head -n -1) + + if [ -n "$kernels_to_remove" ]; then + apt purge -y $kernels_to_remove + fi + + echo -e "${BLUE} Очистка пакетов...${RESET}" + apt clean + apt autoclean + apt autopurge -y + aptitude purge ~c -y + + echo -e "${BLUE} Запуск puppet и возвращение в автозапуск...${RESET}" + systemctl enable puppet --now + + echo -e "${GREEN}${CHECK} Чистка и исправление завершены${RESET}\n" + + set_status 1072 + + echo -e "\n${BOLD}${GREEN}════════════════════════════════════════${RESET}" + echo -e "${BOLD}${GREEN} ✅ ОБНОВЛЕНИЕ УСПЕШНО ЗАВЕРШЕНО!${RESET}" + echo -e "${BOLD}${GREEN}════════════════════════════════════════${RESET}" + echo -e "${GREEN}${CHECK} Система: ${BOLD}$TARGET_VERSION${RESET}" + echo -e "${GREEN}${SHIELD} Защита: ${BOLD}установлена${RESET}" + echo -e "${GREEN}${CLEAN} Чистка: ${BOLD}выполнена${RESET}" + echo -e "${BOLD}${GREEN}════════════════════════════════════════${RESET}\n" + + if [[ -f /var/run/reboot-required ]]; then + echo -e "${YELLOW}${WARN} Рекомендуется перезагрузить систему${RESET}" + ask_reboot + fi +} + +# ============================================== +# Запрос перезагрузки +# ============================================== + +ask_reboot() { + read -p "$(echo -e ${YELLOW}Перезагрузить сейчас? [y/N]: ${RESET})" -n 1 -r + echo "" + if [[ $REPLY =~ ^[Yy]$ ]]; then + echo -e "${BLUE} Перезагрузка...${RESET}" + reboot + else + echo -e "${YELLOW}${WARN} Перезагрузка отложена${RESET}" + echo -e "${YELLOW}${WARN} Не забудьте перезагрузить систему вручную!${RESET}" + echo -e "${YELLOW} Для продолжения обновления запустите: sudo $0${RESET}" + fi +} + +# ============================================== +# MAIN +# ============================================== + +main() { + check_root + init_marker + get_current_version + check_status_and_version + ask_update + + case $STAGE in + 1) stage1_update_system ;; + 2) stage2_install_security ;; + 3) stage3_clean_and_fix ;; + *) + echo -e "${RED}${ERROR} Неизвестный этап: $STAGE${RESET}" + read -p "Нажмите Enter для завершения..." + exit 1 + ;; + esac +} + +main "$@" \ No newline at end of file diff --git a/custom_update_lsp.txt b/custom_update_lsp.txt new file mode 100644 index 0000000..0464984 --- /dev/null +++ b/custom_update_lsp.txt @@ -0,0 +1,436 @@ +#!/usr/bin/env bash +# ============================================== +# Скрипт поэтапного обновления Astra Linux +# ============================================== +# Цвета +RED='\033[0;31m' +GREEN='\033[0;32m' +YELLOW='\033[1;33m' +BLUE='\033[0;34m' +CYAN='\033[0;36m' +BOLD='\033[1m' +RESET='\033[0m' +# Иконки +CHECK="✅" +ERROR="❌" +WARN="⚠️" +INFO="ℹ️" +ARROW="➜" +ROCKET="🚀" + +# Путь к маркер-файлу +MARKER_FILE="/opt/config/custom_update_status.info" +VERSION_FILE="/etc/astra/build_version" +TARGET_VERSION="1.7.10.72" + +# ============================================== +# Функции работы с маркер-файлом +# ============================================== + +init_marker() { + mkdir -p "$(dirname "$MARKER_FILE")" 2>/dev/null + # Если файла нет - создаем со статусом 5 + if [[ ! -f "$MARKER_FILE" ]]; then + echo "5" > "$MARKER_FILE" + echo -e "${BLUE}${INFO} Создан маркер-файл: ${MARKER_FILE}${RESET}" + fi +} + +get_status() { + if [[ -f "$MARKER_FILE" ]]; then + cat "$MARKER_FILE" | tr -d ' \t\n\r' + else + echo "5" + fi +} + +set_status() { + echo "$1" > "$MARKER_FILE" + echo -e "${BLUE}${INFO} Статус обновления: ${BOLD}$1${RESET}" +} + +show_status_info() { + local status=$(get_status) + echo -e "\n${BOLD}${CYAN}━━━ Статус обновления ━━━${RESET}" + case $status in + 1072) + echo -e "${GREEN}${CHECK} Система актуальна (версия $CURRENT_VERSION)${RESET}" + echo -e "${GREEN}${CHECK} Обновление не требуется${RESET}" + ;; + 1) + echo -e "${YELLOW}${WARN} Статус: ${BOLD}1 этап завершен${RESET}" + echo -e "${YELLOW}${WARN} Требуется продолжить обновление (2 этап)${RESET}" + ;; + 2) + echo -e "${YELLOW}${WARN} Статус: ${BOLD}2 этап завершен${RESET}" + echo -e "${YELLOW}${WARN} Требуется продолжить обновление (3 этап)${RESET}" + ;; + 5) + echo -e "${GREEN}${CHECK} Система (версия $CURRENT_VERSION)${RESET}" + echo -e "${GREEN}${CHECK} Обновление не утилитой не выполнялось${RESET}" + ;; + *) + echo -e "${RED}${ERROR} Неизвестный статус: $status${RESET}" + ;; + esac + echo "" +} + +# ============================================== +# Шаг 1: Проверяем права root +# ============================================== + +check_root() { + echo -e "\n${BOLD}${BLUE}════════════════════════════════════════${RESET}" + echo -e "${BOLD}${CYAN} ПОЭТАПНОЕ ОБНОВЛЕНИЕ ASTRA LINUX${RESET}" + echo -e "${BOLD}${BLUE}════════════════════════════════════════${RESET}\n" + + if [[ $EUID -ne 0 ]]; then + echo -e "${RED}${ERROR} Ошибка: нужны права root!${RESET}" + echo -e "${YELLOW}${INFO} Используйте: sudo $0${RESET}\n" + exit 1 + else + echo -e "${GREEN}${CHECK} Права root: OK${RESET}" + fi +} + +# ============================================== +# Шаг 2: Читаем версию +# ============================================== + +get_current_version() { + if [[ -f "$VERSION_FILE" ]]; then + CURRENT_VERSION=$(cat "$VERSION_FILE" | tr -d ' \t\n\r') + echo -e "${GREEN}${CHECK} Текущая версия: ${BOLD}${CYAN}$CURRENT_VERSION${RESET}" + else + echo -e "${RED}${ERROR} Файл версии не найден: $VERSION_FILE${RESET}" + CURRENT_VERSION="unknown" + exit 1 + fi +} + +# ============================================== +# Шаг 3: Проверяем статус и версию +# ============================================== + +check_status_and_version() { + local status=$(get_status) + + echo "" + + # Если система уже обновлена до целевой версии + if [[ "$CURRENT_VERSION" == "$TARGET_VERSION" ]]; then + echo -e "${GREEN}${CHECK} ${BOLD}Система обновлена до версии $TARGET_VERSION${RESET}" + + # Если статус 0 - всё хорошо, выходим + if [[ "$status" == "1072" ]]; then + echo -e "${GREEN}${CHECK} Все этапы завершены${RESET}\n" + exit 0 + fi + + # Если статус 1 - система обновлена, но защита не установлена + if [[ "$status" == "1" ]]; then + echo -e "${YELLOW}${WARN} Система обновлена, но защита не установлена${RESET}" + echo -e "${CYAN}${ARROW} Продолжаем со 2 этапа${RESET}" + STAGE=2 + return + fi + + # Если статус 2 - защита установлена, нужна чистка + if [[ "$status" == "2" ]]; then + echo -e "${YELLOW}${WARN} Защита установлена, требуется чистка${RESET}" + echo -e "${CYAN}${ARROW} Продолжаем с 3 этапа${RESET}" + STAGE=3 + return + fi + fi + + # Если версия ниже целевой + echo -e "${YELLOW}${WARN} Текущая версия ($CURRENT_VERSION) ниже целевой ($TARGET_VERSION)${RESET}" + show_status_info + + # Определяем этап на основе статуса + case $status in + 5) + echo -e "${CYAN}${ARROW} Начинаем обновление с 1 этапа${RESET}" + STAGE=1 + ;; + 1) + echo -e "${CYAN}${ARROW} Продолжаем со 2 этапа (установка защиты)${RESET}" + STAGE=2 + ;; + 2) + echo -e "${CYAN}${ARROW} Продолжаем с 3 этапа (чистка и исправление)${RESET}" + STAGE=3 + ;; + *) + echo -e "${RED}${ERROR} Неизвестный статус, сбрасываем на 5${RESET}" + set_status 5 + STAGE=1 + ;; + esac + echo "" +} + +# ============================================== +# Шаг 4: Запрос на обновление +# ============================================== + +ask_update() { + local message="" + + case $STAGE in + 1) + message="Начать обновление системы до версии $TARGET_VERSION (1 этап)? После завершения потребуется перезагрузка" + ;; + 2) + message="Установить корпоративную систему защиты (2 этап)? После завершения потребуется перезагрузка" + ;; + 3) + message="Выполнить чистку системы и исправление багов (3 этап)?" + ;; + esac + + echo "" + read -p "$(echo -e ${YELLOW}${message} [y/N]: ${RESET})" -n 1 -r + echo "" + + if [[ $REPLY =~ ^[Yy]$ ]]; then + echo -e "\n${GREEN}${ROCKET} Запускаем этап $STAGE...${RESET}\n" + return 0 + else + echo -e "\n${YELLOW}${WARN} Обновление отменено пользователем${RESET}\n" + exit 0 + fi +} + +# ============================================== +# ЭТАП 1: Обновление системы до 1.7.10 +# ============================================== + +stage1_update_system() { + echo -e "${BOLD}${BLUE}━━━ ЭТАП 1: Обновление системы до $TARGET_VERSION ━━━${RESET}\n" + + mgmt_server=$(awk -F' *= *' '/^ *server *=/{print $2}' /etc/puppetlabs/puppet/puppet.conf) + if [[ -z "$mgmt_server" ]]; then + echo -e "${RED}${ERROR} Не удалось получить адрес сервера управления из $puppet_conf${RESET}" + exit 1 + fi + echo -e "${GREEN}${CHECK} Сервер управления: ${BOLD}${CYAN}$mgmt_server${RESET}" + + echo -e "\n${BLUE}${INFO} Остановка и отключение службы Puppet...${RESET}" + systemctl stop puppet.service 2>/dev/null + systemctl disable puppet.service 2>/dev/null + sleep 5 + + echo -e "\n${BLUE}${INFO} Настройка репозиториев Astra...${RESET}" + repo_file="/etc/apt/sources.list" + cat > "$repo_file" << EOF +# Astra Linux 1.7.10 репозитории +# Сервер управления: ${mgmt_server} +# Сгенерировано: $(date) + +deb http://${mgmt_server}/astra/1.7.10/repository-base/ 1.7_x86-64 contrib main non-free +deb http://${mgmt_server}/astra/1.7.10/repository-update/ 1.7_x86-64 contrib main non-free +deb http://${mgmt_server}/astra/1.7.10/repository-extended/ 1.7_x86-64 contrib main non-free +deb [trusted=yes] http://${mgmt_server}/astra/1.7/custom/ 1.7_x86-64 contrib main non-free +EOF + + if [[ $? -eq 0 ]]; then + echo -e "${GREEN}${CHECK} Репозитории настроены: $repo_file${RESET}" + else + echo -e "${RED}${ERROR} Ошибка настройки репозиториев${RESET}" + exit 1 + fi + + echo -e "\n${BLUE}${INFO} Очистка старых репозиториев...${RESET}" + + if ls /etc/apt/sources.list.d/*.list 2>/dev/null 1>/dev/null; then + echo -e "${YELLOW}${WARN} Найдены файлы в /etc/apt/sources.list.d/${RESET}" + echo -e "${BLUE}${INFO} Файлы для удаления:${RESET}" + ls -la /etc/apt/sources.list.d/*.list 2>/dev/null || echo " (нет .list файлов)" + rm -f /etc/apt/sources.list.d/*.list 2>/dev/null + echo -e "${GREEN}${CHECK} Все .list файлы удалены${RESET}" + else + echo -e "${GREEN}${CHECK} Папка /etc/apt/sources.list.d/ пуста${RESET}" + fi + + echo -e "\n${BLUE}${INFO} Обновление списка пакетов...${RESET}" + apt update + sleep 3 + + echo -e "\n${BLUE}${INFO} Загрузка пакетов...${RESET}" + apt dist-upgrade --download-only -y + + echo -e "\n${BLUE}${INFO} Подготовка системы к обновлению...${RESET}" + dpkg -s gk-kvm >/dev/null 2>&1 && { apt update && apt install --only-upgrade gk-kvm; } || true + dpkg -s secretnet >/dev/null 2>&1 && { sudo dpkg -P secretnet; } || true + dpkg -s sns >/dev/null 2>&1 && { sudo dpkg -P sns; } || true + dpkg -s gk-kvm >/dev/null 2>&1 && { tarm_unlock; } || true + echo performance | sudo tee /sys/devices/system/cpu/cpu*/cpufreq/scaling_governor + + echo -e "${BLUE}${INFO} Выполняется обновление...${RESET}" + /usr/sbin/astra-update -A -r -T -K || { + echo -e "${RED}${ERROR} Ошибка обновления пакетов${RESET}" + exit 1 + } + + /usr/bin/apt -o Dpkg::Options::='--force-confold' install -y gk-eosdo xrdp astra-version --reinstall + dpkg -s gk-kvm >/dev/null 2>&1 && { /usr/bin/apt -o Dpkg::Options::='--force-confold' install -y gk-kvm --reinstall; } || true + dpkg -s gk-kvm >/dev/null 2>&1 && { tarm_lock; } || true + + if [[ -f "$VERSION_FILE" ]]; then + NEW_VERSION=$(cat "$VERSION_FILE" | tr -d ' \t\n\r') + if [[ "$NEW_VERSION" == "$TARGET_VERSION" ]]; then + echo -e "${GREEN}${CHECK} ${BOLD}Система успешно обновлена до $TARGET_VERSION${RESET}" + else + echo -e "${RED}${ERROR} Версия системы: $NEW_VERSION (ожидалось $TARGET_VERSION)${RESET}" + echo -e "${RED}${ERROR} Обновление прошло с ошибкой!${RESET}" + exit 1 + fi + fi + + # Устанавливаем статус 1 + set_status 1 + + echo -e "\n${GREEN}${CHECK} ${BOLD}1 этап завершен! Система обновлена до $TARGET_VERSION${RESET}" + echo -e "${YELLOW}${REBOOT} Требуется перезагрузка для продолжения${RESET}" + echo -e "${YELLOW}${INFO} После перезагрузки запустите скрипт снова ${RESET}\n" + ask_reboot +} + +# ============================================== +# ЭТАП 2: Установка корпоративной системы защиты +# ============================================== + +stage2_install_security() { + mgmt_server=$(awk -F' *= *' '/^ *server *=/{print $2}' /etc/puppetlabs/puppet/puppet.conf) + if [[ -z "$mgmt_server" ]]; then + echo -e "${RED}${ERROR} Не удалось получить адрес сервера управления из $puppet_conf${RESET}" + exit 1 + fi + echo -e "${BOLD}${BLUE}━━━ ЭТАП 2: Установка Secret Net ━━━${RESET}\n" + + if [[ -f "$VERSION_FILE" ]]; then + CURRENT_VER=$(cat "$VERSION_FILE" | tr -d ' \t\n\r') + if [[ "$CURRENT_VER" != "$TARGET_VERSION" ]]; then + echo -e "${RED}${ERROR} Система не обновлена до $TARGET_VERSION (текущая: $CURRENT_VER)${RESET}" + echo -e "${RED}${ERROR} Сначала выполните 1 этап обновления${RESET}" + exit 1 + fi + fi + + echo -e "${BLUE}${INFO} Установка SecretNet...${RESET}" + cd /tmp/ + wget http://$mgmt_server/SN/secretnet_1.12-4844.astra1.7_amd64.deb + apt install -y /tmp/secretnet_1.12-4844.astra1.7_amd64.deb + echo -e "${BLUE}${INFO} Установка SecretNet выполнена${RESET}" + + # Устанавливаем статус 2 + set_status 2 + + echo -e "\n${GREEN}${CHECK} ${BOLD}2 этап завершен! Secretnet установлен${RESET}" + echo -e "${YELLOW}${REBOOT} Требуется перезагрузка для продолжения${RESET}" + echo -e "${YELLOW}${INFO} После перезагрузки запустите скрипт снова ${RESET}\n" + ask_reboot +} + +# ============================================== +# ЭТАП 3: Чистка системы и исправление багов +# ============================================== + +stage3_clean_and_fix() { + echo -e "${BOLD}${BLUE}━━━ ЭТАП 3: Чистка системы и исправление багов ━━━${RESET}\n" + + echo -e "${BLUE}${INFO} Запуск puppet...${RESET}" + /opt/puppetlabs/bin/puppet agent -t; + /opt/puppetlabs/bin/puppet agent -t; + + echo -e "${BLUE}${INFO} Финальное обновление пакетов...${RESET}" + /usr/sbin/astra-update -A -r -T + + echo -e "${BLUE}${INFO} Исправление печати kerberos...${RESET}" + rm /usr/lib/cups/backend/smb + ln -s /usr/libexec/samba/smbspool_krb5_wrapper /usr/lib/cups/backend/smb + chmod 700 /usr/lib/cups/backend/smb + + echo -e "${BLUE}${INFO} Очистка старых ядер...${RESET}" + base_kernel=$(uname -r | sed "s/\(.*\)-\([^0-9]\+\)/\1/") + + kernels_to_remove=$(dpkg -l 'linux-*' | sed -n '/^ii/p' | \ + sed "/$base_kernel/d" | \ + sed 's/^[^ ]* [^ ]* \([^ ]*\).*/\1/' | \ + sed -n '/[0-9]/p' | \ + head -n -1) + + if [ -n "$kernels_to_remove" ]; then + apt purge -y $kernels_to_remove + fi + + echo -e "${BLUE}${INFO} Очистка пакетов...${RESET}" + apt clean + apt autoclean + apt autopurge -y + aptitude purge ~c -y + + echo -e "${BLUE}${INFO} Запуск puppet и возвращение в автозапуск...${RESET}" + systemctl enable puppet --now + + echo -e "${GREEN}${CHECK} Чистка и исправление завершены${RESET}\n" + + set_status 1072 + + echo -e "\n${BOLD}${GREEN}════════════════════════════════════════${RESET}" + echo -e "${BOLD}${GREEN} ✅ ОБНОВЛЕНИЕ УСПЕШНО ЗАВЕРШЕНО!${RESET}" + echo -e "${BOLD}${GREEN}════════════════════════════════════════${RESET}" + echo -e "${GREEN}${CHECK} Система: ${BOLD}$TARGET_VERSION${RESET}" + echo -e "${GREEN}${SHIELD} Защита: ${BOLD}установлена${RESET}" + echo -e "${GREEN}${CLEAN} Чистка: ${BOLD}выполнена${RESET}" + echo -e "${BOLD}${GREEN}════════════════════════════════════════${RESET}\n" + + if [[ -f /var/run/reboot-required ]]; then + echo -e "${YELLOW}${WARN} Рекомендуется перезагрузить систему${RESET}" + ask_reboot + fi +} + +# ============================================== +# Запрос перезагрузки +# ============================================== + +ask_reboot() { + read -p "$(echo -e ${YELLOW}Перезагрузить сейчас? [y/N]: ${RESET})" -n 1 -r + echo "" + if [[ $REPLY =~ ^[Yy]$ ]]; then + echo -e "${BLUE}${INFO} Перезагрузка...${RESET}" + reboot + else + echo -e "${YELLOW}${WARN} Перезагрузка отложена${RESET}" + echo -e "${YELLOW}${WARN} Не забудьте перезагрузить систему вручную!${RESET}" + echo -e "${YELLOW}${INFO} Для продолжения обновления запустите: sudo $0${RESET}" + fi +} + +# ============================================== +# MAIN +# ============================================== + +main() { + check_root + init_marker + get_current_version + check_status_and_version + ask_update + + case $STAGE in + 1) stage1_update_system ;; + 2) stage2_install_security ;; + 3) stage3_clean_and_fix ;; + *) + echo -e "${RED}${ERROR} Неизвестный этап: $STAGE${RESET}" + exit 1 + ;; + esac +} + +main "$@" \ No newline at end of file diff --git a/custom_update_sns.sh b/custom_update_sns.sh new file mode 100644 index 0000000..fecd5c5 --- /dev/null +++ b/custom_update_sns.sh @@ -0,0 +1,446 @@ +#!/usr/bin/env bash +# ============================================== +# Скрипт поэтапного обновления Astra Linux +# ============================================== +# Цвета +RED='\033[0;31m' +GREEN='\033[0;32m' +YELLOW='\033[1;33m' +BLUE='\033[0;34m' +CYAN='\033[0;36m' +BOLD='\033[1m' +RESET='\033[0m' +# Иконки +CHECK="✅" +ERROR="❌" +WARN="⚠️" +ARROW="➜" +ROCKET="🚀" + +# Путь к маркер-файлу +MARKER_FILE="/opt/config/custom_update_status.info" +VERSION_FILE="/etc/astra/build_version" +TARGET_VERSION="1.7.10.72" + +# ============================================== +# Функции работы с маркер-файлом +# ============================================== + +init_marker() { + mkdir -p "$(dirname "$MARKER_FILE")" 2>/dev/null + # Если файла нет - создаем со статусом 5 + if [[ ! -f "$MARKER_FILE" ]]; then + echo "5" > "$MARKER_FILE" + echo -e "${BLUE} Создан маркер-файл: ${MARKER_FILE}${RESET}" + fi +} + +get_status() { + if [[ -f "$MARKER_FILE" ]]; then + cat "$MARKER_FILE" | tr -d ' \t\n\r' + else + echo "5" + fi +} + +set_status() { + echo "$1" > "$MARKER_FILE" + echo -e "${BLUE} Статус обновления: ${BOLD}$1${RESET}" +} + +show_status_info() { + local status=$(get_status) + echo -e "\n${BOLD}${CYAN}━━━ Статус обновления ━━━${RESET}" + case $status in + 1072) + echo -e "${GREEN}${CHECK} Система актуальна (версия $CURRENT_VERSION)${RESET}" + echo -e "${GREEN}${CHECK} Обновление не требуется${RESET}" + ;; + 1) + echo -e "${YELLOW}${WARN} Статус: ${BOLD}1 этап завершен${RESET}" + echo -e "${YELLOW}${WARN} Требуется продолжить обновление (2 этап)${RESET}" + ;; + 2) + echo -e "${YELLOW}${WARN} Статус: ${BOLD}2 этап завершен${RESET}" + echo -e "${YELLOW}${WARN} Требуется продолжить обновление (3 этап)${RESET}" + ;; + 5) + echo -e "${GREEN}${CHECK} Система (версия $CURRENT_VERSION)${RESET}" + echo -e "${GREEN}${CHECK} Обновление не утилитой не выполнялось${RESET}" + ;; + *) + echo -e "${RED}${ERROR} Неизвестный статус: $status${RESET}" + ;; + esac + echo "" +} + +# ============================================== +# Шаг 1: Проверяем права root +# ============================================== + +check_root() { + echo -e "\n${BOLD}${BLUE}════════════════════════════════════════${RESET}" + echo -e "${BOLD}${CYAN} 🔄 ПОЭТАПНОЕ ОБНОВЛЕНИЕ ASTRA LINUX${RESET}" + echo -e "${BOLD}${BLUE}════════════════════════════════════════${RESET}\n" + + if [[ $EUID -ne 0 ]]; then + echo -e "${RED}${ERROR} Ошибка: нужны права root!${RESET}" + echo -e "${YELLOW}Используйте: sudo $0${RESET}\n" + read -p "Нажмите Enter для завершения..." + exit 1 + else + echo -e "${GREEN}${CHECK} Права root: OK${RESET}" + fi +} + +# ============================================== +# Шаг 2: Читаем версию +# ============================================== + +get_current_version() { + if [[ -f "$VERSION_FILE" ]]; then + CURRENT_VERSION=$(cat "$VERSION_FILE" | tr -d ' \t\n\r') + echo -e "${GREEN}${CHECK} Текущая версия: ${BOLD}${CYAN}$CURRENT_VERSION${RESET}" + else + echo -e "${RED}${ERROR} Файл версии не найден: $VERSION_FILE${RESET}" + CURRENT_VERSION="unknown" + read -p "Нажмите Enter для завершения..." + exit 1 + fi +} + +# ============================================== +# Шаг 3: Проверяем статус и версию +# ============================================== + +check_status_and_version() { + local status=$(get_status) + + echo "" + + # Если система уже обновлена до целевой версии + if [[ "$CURRENT_VERSION" == "$TARGET_VERSION" ]]; then + echo -e "${GREEN}${CHECK} ${BOLD}Система обновлена до версии $TARGET_VERSION${RESET}" + + # Если статус 0 - всё хорошо, выходим + if [[ "$status" == "1072" ]]; then + echo -e "${GREEN}${CHECK} Все этапы завершены${RESET}\n" + read -p "Нажмите Enter для завершения..." + exit 0 + fi + + # Если статус 1 - система обновлена, но защита не установлена + if [[ "$status" == "1" ]]; then + echo -e "${YELLOW}${WARN} Система обновлена, но защита не установлена${RESET}" + echo -e "${CYAN}${ARROW} Продолжаем со 2 этапа${RESET}" + STAGE=2 + return + fi + + # Если статус 2 - защита установлена, нужна чистка + if [[ "$status" == "2" ]]; then + echo -e "${YELLOW}${WARN} Защита установлена, требуется чистка${RESET}" + echo -e "${CYAN}${ARROW} Продолжаем с 3 этапа${RESET}" + STAGE=3 + return + fi + fi + + # Если версия ниже целевой + echo -e "${YELLOW}${WARN} Текущая версия ($CURRENT_VERSION) ниже целевой ($TARGET_VERSION)${RESET}" + show_status_info + + # Определяем этап на основе статуса + case $status in + 5) + echo -e "${CYAN}${ARROW} Начинаем обновление с 1 этапа${RESET}" + STAGE=1 + ;; + 1) + echo -e "${CYAN}${ARROW} Продолжаем со 2 этапа (установка защиты)${RESET}" + STAGE=2 + ;; + 2) + echo -e "${CYAN}${ARROW} Продолжаем с 3 этапа (чистка и исправление)${RESET}" + STAGE=3 + ;; + *) + echo -e "${RED}${ERROR} Неизвестный статус, сбрасываем на 5${RESET}" + set_status 5 + STAGE=1 + ;; + esac + echo "" +} + +# ============================================== +# Шаг 4: Запрос на обновление +# ============================================== + +ask_update() { + local message="" + + case $STAGE in + 1) + message="Начать обновление системы до версии $TARGET_VERSION (1 этап)? После завершения потребуется перезагрузка" + ;; + 2) + message="Установить корпоративную систему защиты (2 этап)? После завершения потребуется перезагрузка" + ;; + 3) + message="Выполнить чистку системы и исправление багов (3 этап)?" + ;; + esac + + echo "" + read -p "$(echo -e ${YELLOW}${message} [y/N]: ${RESET})" -n 1 -r + echo "" + + if [[ $REPLY =~ ^[Yy]$ ]]; then + echo -e "\n${GREEN}${ROCKET} Запускаем этап $STAGE...${RESET}\n" + return 0 + else + echo -e "\n${YELLOW}${WARN} Обновление отменено пользователем${RESET}\n" + read -p "Нажмите Enter для завершения..." + exit 0 + fi +} + +# ============================================== +# ЭТАП 1: Обновление системы до 1.7.10 +# ============================================== + +stage1_update_system() { + echo -e "${BOLD}${BLUE}━━━ ЭТАП 1: Обновление системы до $TARGET_VERSION ━━━${RESET}\n" + + mgmt_server=$(awk -F' *= *' '/^ *server *=/{print $2}' /etc/puppetlabs/puppet/puppet.conf) + if [[ -z "$mgmt_server" ]]; then + echo -e "${RED}${ERROR} Не удалось получить адрес сервера управления из $puppet_conf${RESET}" + read -p "Нажмите Enter для завершения..." + exit 1 + fi + echo -e "${GREEN}${CHECK} Сервер управления: ${BOLD}${CYAN}$mgmt_server${RESET}" + + echo -e "\n${BLUE Остановка и отключение службы Puppet...${RESET}" + systemctl stop puppet.service 2>/dev/null + systemctl disable puppet.service 2>/dev/null + sleep 5 + + echo -e "\n${BLUE} Настройка репозиториев Astra...${RESET}" + repo_file="/etc/apt/sources.list" + cat > "$repo_file" << EOF +# Astra Linux 1.7.10 репозитории +# Сервер управления: ${mgmt_server} +# Сгенерировано: $(date) + +deb http://${mgmt_server}/astra/1.7.10/repository-base/ 1.7_x86-64 contrib main non-free +deb http://${mgmt_server}/astra/1.7.10/repository-update/ 1.7_x86-64 contrib main non-free +deb http://${mgmt_server}/astra/1.7.10/repository-extended/ 1.7_x86-64 contrib main non-free +deb [trusted=yes] http://${mgmt_server}/astra/1.7/custom/ 1.7_x86-64 contrib main non-free +EOF + + if [[ $? -eq 0 ]]; then + echo -e "${GREEN}${CHECK} Репозитории настроены: $repo_file${RESET}" + else + echo -e "${RED}${ERROR} Ошибка настройки репозиториев${RESET}" + read -p "Нажмите Enter для завершения..." + exit 1 + fi + + echo -e "\n${BLUE} Очистка старых репозиториев...${RESET}" + + if ls /etc/apt/sources.list.d/*.list 2>/dev/null 1>/dev/null; then + echo -e "${YELLOW}${WARN} Найдены файлы в /etc/apt/sources.list.d/${RESET}" + echo -e "${BLUE} Файлы для удаления:${RESET}" + ls -la /etc/apt/sources.list.d/*.list 2>/dev/null || echo " (нет .list файлов)" + rm -f /etc/apt/sources.list.d/*.list 2>/dev/null + echo -e "${GREEN}${CHECK} Все .list файлы удалены${RESET}" + else + echo -e "${GREEN}${CHECK} Папка /etc/apt/sources.list.d/ пуста${RESET}" + fi + + echo -e "\n${BLUE} Обновление списка пакетов...${RESET}" + apt update + sleep 3 + + echo -e "\n${BLUE} Загрузка пакетов...${RESET}" + apt dist-upgrade --download-only -y + + echo -e "\n${BLUE} Подготовка системы к обновлению...${RESET}" + dpkg -s gk-kvm >/dev/null 2>&1 && { apt update && apt install --only-upgrade gk-kvm; } || true + dpkg -s secretnet >/dev/null 2>&1 && { sudo dpkg -P secretnet; } || true + dpkg -s sns >/dev/null 2>&1 && { sudo dpkg -P sns; } || true + dpkg -s gk-kvm >/dev/null 2>&1 && { tarm_unlock; } || true + echo performance | sudo tee /sys/devices/system/cpu/cpu*/cpufreq/scaling_governor + + echo -e "${BLUE} Выполняется обновление...${RESET}" + /usr/sbin/astra-update -A -r -T -K || { + echo -e "${RED}${ERROR} Ошибка обновления пакетов${RESET}" + read -p "Нажмите Enter для завершения..." + exit 1 + } + + /usr/bin/apt -o Dpkg::Options::='--force-confold' install -y gk-eosdo xrdp astra-version --reinstall + dpkg -s gk-kvm >/dev/null 2>&1 && { /usr/bin/apt -o Dpkg::Options::='--force-confold' install -y gk-kvm --reinstall; } || true + dpkg -s gk-kvm >/dev/null 2>&1 && { tarm_lock; } || true + + if [[ -f "$VERSION_FILE" ]]; then + NEW_VERSION=$(cat "$VERSION_FILE" | tr -d ' \t\n\r') + if [[ "$NEW_VERSION" == "$TARGET_VERSION" ]]; then + echo -e "${GREEN}${CHECK} ${BOLD}Система успешно обновлена до $TARGET_VERSION${RESET}" + else + echo -e "${RED}${ERROR} Версия системы: $NEW_VERSION (ожидалось $TARGET_VERSION)${RESET}" + echo -e "${RED}${ERROR} Обновление прошло с ошибкой!${RESET}" + read -p "Нажмите Enter для завершения..." + exit 1 + fi + fi + + # Устанавливаем статус 1 + set_status 1 + + echo -e "\n${GREEN}${CHECK} ${BOLD}1 этап завершен! Система обновлена до $TARGET_VERSION${RESET}" + echo -e "${YELLOW} Требуется перезагрузка для продолжения${RESET}" + echo -e "${YELLOW} После перезагрузки запустите скрипт снова ${RESET}\n" + ask_reboot +} + +# ============================================== +# ЭТАП 2: Установка корпоративной системы защиты +# ============================================== + +stage2_install_security() { + mgmt_server=$(awk -F' *= *' '/^ *server *=/{print $2}' /etc/puppetlabs/puppet/puppet.conf) + if [[ -z "$mgmt_server" ]]; then + echo -e "${RED}${ERROR} Не удалось получить адрес сервера управления из $puppet_conf${RESET}" + read -p "Нажмите Enter для завершения..." + exit 1 + fi + echo -e "${BOLD}${BLUE}━━━ ЭТАП 2: Установка Secret Net ━━━${RESET}\n" + + if [[ -f "$VERSION_FILE" ]]; then + CURRENT_VER=$(cat "$VERSION_FILE" | tr -d ' \t\n\r') + if [[ "$CURRENT_VER" != "$TARGET_VERSION" ]]; then + echo -e "${RED}${ERROR} Система не обновлена до $TARGET_VERSION (текущая: $CURRENT_VER)${RESET}" + echo -e "${RED}${ERROR} Сначала выполните 1 этап обновления${RESET}" + read -p "Нажмите Enter для завершения..." + exit 1 + fi + fi + + echo -e "${BLUE} Установка SecretNet...${RESET}" + cd /tmp/ + wget http://$mgmt_server/SN/sns_8.2-2426.astra1.7_amd64.deb + apt install -y /tmp/sns_8.2-2426.astra1.7_amd64.deb + echo -e "${BLUE} Установка SecretNet выполнена${RESET}" + + # Устанавливаем статус 2 + set_status 2 + + echo -e "\n${GREEN}${CHECK} ${BOLD}2 этап завершен! Secretnet установлен${RESET}" + echo -e "${YELLOW} Требуется перезагрузка для продолжения${RESET}" + echo -e "${YELLOW} После перезагрузки запустите скрипт снова ${RESET}\n" + ask_reboot +} + +# ============================================== +# ЭТАП 3: Чистка системы и исправление багов +# ============================================== + +stage3_clean_and_fix() { + echo -e "${BOLD}${BLUE}━━━ ЭТАП 3: Чистка системы и исправление багов ━━━${RESET}\n" + + echo -e "${BLUE} Запуск puppet...${RESET}" + /opt/puppetlabs/bin/puppet agent -t; + /opt/puppetlabs/bin/puppet agent -t; + + echo -e "${BLUE} Финальное обновление пакетов...${RESET}" + /usr/sbin/astra-update -A -r -T + + echo -e "${BLUE} Исправление печати kerberos...${RESET}" + rm /usr/lib/cups/backend/smb + ln -s /usr/libexec/samba/smbspool_krb5_wrapper /usr/lib/cups/backend/smb + chmod 700 /usr/lib/cups/backend/smb + + echo -e "${BLUE} Очистка старых ядер...${RESET}" + base_kernel=$(uname -r | sed "s/\(.*\)-\([^0-9]\+\)/\1/") + + kernels_to_remove=$(dpkg -l 'linux-*' | sed -n '/^ii/p' | \ + sed "/$base_kernel/d" | \ + sed 's/^[^ ]* [^ ]* \([^ ]*\).*/\1/' | \ + sed -n '/[0-9]/p' | \ + head -n -1) + + if [ -n "$kernels_to_remove" ]; then + apt purge -y $kernels_to_remove + fi + + echo -e "${BLUE} Очистка пакетов...${RESET}" + apt clean + apt autoclean + apt autopurge -y + aptitude purge ~c -y + + echo -e "${BLUE} Запуск puppet и возвращение в автозапуск...${RESET}" + systemctl enable puppet --now + + echo -e "${GREEN}${CHECK} Чистка и исправление завершены${RESET}\n" + + set_status 1072 + + echo -e "\n${BOLD}${GREEN}════════════════════════════════════════${RESET}" + echo -e "${BOLD}${GREEN} ✅ ОБНОВЛЕНИЕ УСПЕШНО ЗАВЕРШЕНО!${RESET}" + echo -e "${BOLD}${GREEN}════════════════════════════════════════${RESET}" + echo -e "${GREEN}${CHECK} Система: ${BOLD}$TARGET_VERSION${RESET}" + echo -e "${GREEN}${SHIELD} Защита: ${BOLD}установлена${RESET}" + echo -e "${GREEN}${CLEAN} Чистка: ${BOLD}выполнена${RESET}" + echo -e "${BOLD}${GREEN}════════════════════════════════════════${RESET}\n" + + if [[ -f /var/run/reboot-required ]]; then + echo -e "${YELLOW}${WARN} Рекомендуется перезагрузить систему${RESET}" + ask_reboot + fi +} + +# ============================================== +# Запрос перезагрузки +# ============================================== + +ask_reboot() { + read -p "$(echo -e ${YELLOW}Перезагрузить сейчас? [y/N]: ${RESET})" -n 1 -r + echo "" + if [[ $REPLY =~ ^[Yy]$ ]]; then + echo -e "${BLUE} Перезагрузка...${RESET}" + reboot + else + echo -e "${YELLOW}${WARN} Перезагрузка отложена${RESET}" + echo -e "${YELLOW}${WARN} Не забудьте перезагрузить систему вручную!${RESET}" + echo -e "${YELLOW} Для продолжения обновления запустите: sudo $0${RESET}" + fi +} + +# ============================================== +# MAIN +# ============================================== + +main() { + check_root + init_marker + get_current_version + check_status_and_version + ask_update + + case $STAGE in + 1) stage1_update_system ;; + 2) stage2_install_security ;; + 3) stage3_clean_and_fix ;; + *) + echo -e "${RED}${ERROR} Неизвестный этап: $STAGE${RESET}" + read -p "Нажмите Enter для завершения..." + exit 1 + ;; + esac +} + +main "$@" \ No newline at end of file diff --git a/puppet_connect.bin b/puppet_connect.bin new file mode 100644 index 0000000..491615e Binary files /dev/null and b/puppet_connect.bin differ diff --git a/puppet_connect.py b/puppet_connect.py new file mode 100644 index 0000000..880fd61 --- /dev/null +++ b/puppet_connect.py @@ -0,0 +1,236 @@ +#!/usr/bin/env python3 +import os +import subprocess +import shutil +import socket +import sys +import threading +import queue + +# GUI +import tkinter as tk +from tkinter import messagebox +import tkinter.ttk as ttk + +# ============================================================================== +# НАСТРОЙКИ +# ============================================================================== +PUPPET_SERVER = "gren-s-synd01.gk.rosatom.local" +# ============================================================================== + +class PuppetProgressBar: + def __init__(self, parent, title): + self.top = tk.Toplevel(parent) + self.top.title(title) + self.top.geometry("400x150") + self.top.resizable(False, False) + + # Центрирование окна + self.top.update_idletasks() + width = self.top.winfo_width() + height = self.top.winfo_height() + x = (self.top.winfo_screenwidth() // 2) - (width // 2) + y = (self.top.winfo_screenheight() // 2) - (height // 2) + self.top.geometry(f'+{x}+{y}') + + self.lbl = tk.Label(self.top, text="Выполняется подключение к Puppet...", font=("Arial", 10)) + self.lbl.pack(pady=20) + + self.progress = ttk.Progressbar(self.top, orient="horizontal", length=300, mode="determinate") + self.progress.pack(pady=10) + + self.queue = queue.Queue() + self.line_count = 0 + + # Флаги для ошибок + self.critical_error = False + self.error_type = None + + def start(self, cmd): + threading.Thread(target=self._run_thread, args=(cmd,), daemon=True).start() + self._update_loop() + self.top.wait_window(self.top) + + def _run_thread(self, cmd): + process = None + try: + process = subprocess.Popen( + cmd, + shell=True, + stdout=subprocess.PIPE, + stderr=subprocess.STDOUT, + text=True, + bufsize=1 + ) + + for line in iter(process.stdout.readline, ''): + if line: + # 1. ПРОВЕРКА НА КРИТИЧЕСКУЮ ОШИБКУ + # Ищем ошибку сертификата в текущей строке + if "does not match its private key" in line: + self.critical_error = True + self.error_type = "cert_mismatch" + self.queue.put("CRITICAL_ERROR") + # Убиваем процесс, так как дальше смысла ждать нет + process.terminate() + return + + # Если ошибки нет, двигаем прогресс-бар + self.queue.put("STEP") + + process.wait() + self.queue.put("DONE") + + except Exception as e: + print(f"Thread Error: {e}") + self.queue.put("ERROR") + finally: + if process and process.poll() is None: + process.kill() + + def _update_loop(self): + try: + while True: + msg = self.queue.get_nowait() + + if msg == "STEP": + self.line_count += 1 + value = self.line_count % 101 + self.progress['value'] = value + + elif msg == "CRITICAL_ERROR": + # Если критическая ошибка, сразу закрываем окно + self.top.destroy() + return + + elif msg == "DONE": + self.progress['value'] = 100 + self.lbl.config(text="Готово!") + self.top.after(1000, self.top.destroy) + return + + except queue.Empty: + pass + + if self.top.winfo_exists(): + self.top.after(50, self._update_loop) + +def log_message(msg): + print(f"[LOG] {msg}") + +def get_environment(): + try: + ret_code, output = run_command("lsb_release -a", capture_output=True) + + detected_version = "Не найдена" + for line in output.split('\n'): + line = line.strip() + if line.startswith("Release:"): + detected_version = line.split(":")[1].strip() + if detected_version.startswith("1.8"): + return "new_base_18" + elif detected_version.startswith("1.7"): + return "new_base" + + messagebox.showerror("Ошибка", f"Версия ОС {detected_version} не поддерживается. Нужны 1.7 или 1.8.") + sys.exit(1) + + except Exception as e: + messagebox.showerror("Ошибка", f"Ошибка lsb_release: {e}") + sys.exit(1) + +def run_command(cmd, capture_output=False): + try: + if capture_output: + result = subprocess.run( + cmd, + shell=True, + check=True, + capture_output=True, + text=True + ) + return 0, result.stdout + result.stderr + else: + subprocess.run(cmd, shell=True, check=True) + return 0, "" + except subprocess.CalledProcessError as e: + if capture_output: + return e.returncode, e.stdout + e.stderr + else: + raise e + +def main(): + root = tk.Tk() + root.withdraw() + + try: + # 1. Проверка домена + if not os.path.exists("/etc/krb5.keytab"): + messagebox.showerror("Ошибка", "Введите ПК в домен") + sys.exit(1) + + # 2. Окружение и пути + environment = get_environment() + + if environment == "new_base_18": + puppet_conf = "/etc/puppet/puppet.conf" + ssl_dir = "/var/lib/puppet/ssl" + else: + puppet_conf = "/etc/puppetlabs/puppet/puppet.conf" + ssl_dir = "/etc/puppetlabs/puppet/ssl" + + # 3. Проверка сертификатов + private_keys_dir = os.path.join(ssl_dir, "private_keys") + if os.path.exists(private_keys_dir) and os.listdir(private_keys_dir): + messagebox.showerror("Ошибка", "АРМ уже подключен к puppet") + sys.exit(1) + + # 4. Остановка + log_message("Остановка puppet...") + run_command("systemctl stop puppet", capture_output=False) + + # 5. Запись конфига + conf_content = f"""server = {PUPPET_SERVER} +runinterval = 60m +environment = {environment} +""" + with open(puppet_conf, "w") as f: + f.write(conf_content) + + # 6. Запуск Puppet с прогрессом + pbar = PuppetProgressBar(root, "Подключение к Puppet...") + pbar.start("puppet agent -t") + + # ====================================================================== + # ОБРАБОТКА РЕЗУЛЬТАТА (после закрытия окна) + # ====================================================================== + if pbar.critical_error: + # Если была найдена ошибка сертификата + messagebox.showerror("Ошибка", "Удалите старый сертификат на сервере управления") + log_message("ERROR - need to remove certificate on puppet server") + + # Очистка SSL папки + if os.path.exists(ssl_dir): + shutil.rmtree(ssl_dir) + + sys.exit(1) + # ====================================================================== + + # 7. Финальные шаги (если ошибки не было) + log_message("Финальный прогон...") + subprocess.run("puppet agent -t > /dev/null 2>&1", shell=True) + + log_message("Включение puppet...") + subprocess.run("systemctl start puppet", shell=True, check=True) + subprocess.run("systemctl enable puppet", shell=True, check=True) + + messagebox.showinfo("Успех", "АРМ успешно подключен к puppet") + + except Exception as e: + messagebox.showerror("Критическая ошибка", f"Ошибка: {e}") + sys.exit(1) + finally: + root.destroy() + +if __name__ == "__main__": + main() \ No newline at end of file