version v4 - tested on hosting

This commit is contained in:
Pavel Galkin 2026-01-31 08:24:40 +03:00
parent 87f6ba4736
commit 30472bbb3a
4 changed files with 925 additions and 0 deletions

21
LICENSE Normal file
View file

@ -0,0 +1,21 @@
MIT License
Copyright (c) 2026
Permission is hereby granted, free of charge, to any person obtaining a copy
of this software and associated documentation files (the "Software"), to deal
in the Software without restriction, including without limitation the rights
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
copies of the Software, and to permit persons to whom the Software is
furnished to do so, subject to the following conditions:
The above copyright notice and this permission notice shall be included in all
copies or substantial portions of the Software.
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
SOFTWARE.

228
README-EN.md Normal file
View file

@ -0,0 +1,228 @@
# MikroTik CHR Installer
Automated MikroTik Cloud Hosted Router (CHR) installation script for Linux VPS/VDS servers.
[![License: MIT](https://img.shields.io/badge/License-MIT-yellow.svg)](https://opensource.org/licenses/MIT)
[![Русский](https://img.shields.io/badge/lang-Русский-blue.svg)](README.md)
## 📋 Overview
This script automates the complete installation of MikroTik Cloud Hosted Router (CHR) on any Linux-based VPS or VDS server. It handles everything from downloading the CHR image to configuring network settings and performing the installation — all with a single command.
### Key Features
- 🚀 **One-command installation** — fully automated process
- 🌐 **Auto-detection of network settings** — IP address, gateway, interface
- 📦 **Automatic dependency installation** — works on Debian/Ubuntu, CentOS, RHEL, Fedora
- 🔧 **Pre-configured autorun** — CHR boots with network already configured
- ✅ **Image validation** — MBR signature and integrity checks
- 🔄 **Flexible options** — customizable version, password, and installation modes
## 🎯 Use Cases
### 1. Quick VPS Migration to MikroTik
Replace your Linux VPS with a full MikroTik router in minutes. Perfect for:
- Setting up a VPN server (WireGuard, L2TP, PPTP, OpenVPN)
- Creating a secure gateway for your infrastructure
- Building a remote network management point
### 2. Network Lab Environment
Quickly deploy MikroTik instances for:
- Testing RouterOS configurations before production
- Learning MikroTik administration
- Certification exam preparation (MTCNA, MTCRE, etc.)
### 3. Site-to-Site VPN Hub
Transform a cheap VPS into a central VPN hub connecting multiple sites:
- Cloud-based router for distributed networks
- Backup connectivity point
- Geographic routing optimization
### 4. Traffic Management & Monitoring
Deploy CHR for:
- Bandwidth management and QoS
- Traffic analysis with built-in tools
- Firewall and security gateway
## 📦 Requirements
- Linux-based VPS/VDS server (Debian, Ubuntu, CentOS, RHEL, Fedora)
- Root access
- Minimum 128 MB RAM (256 MB+ recommended)
- At least 128 MB disk space
- Active internet connection
## 🚀 Quick Start
### One-Line Installation
```bash
wget -qO- https://raw.githubusercontent.com/YOUR_REPO/mikrotik-chr-installer/main/chr-installer.sh | bash
```
### Manual Installation
```bash
# Download the script
wget https://raw.githubusercontent.com/YOUR_REPO/mikrotik-chr-installer/main/chr-installer.sh
# Make it executable
chmod +x chr-installer.sh
# Run the installer
sudo ./chr-installer.sh
```
## 📖 Usage Examples
### Basic Installation (Interactive)
```bash
sudo ./chr-installer.sh
```
The script will:
1. Download the latest CHR image
2. Detect your network configuration
3. Ask for confirmation before writing to disk
4. Prompt for reboot after installation
### Fully Automated Installation
```bash
sudo ./chr-installer.sh --yes --reboot
```
No user interaction required — perfect for automation and scripts.
### Custom Version and Password
```bash
sudo ./chr-installer.sh --version 7.14.3 --password MySecurePass123
```
### Clean Installation (No Auto-Configuration)
```bash
sudo ./chr-installer.sh --clean
```
CHR will boot with default settings. Useful when you want to configure everything manually.
### Automation Script Example
```bash
#!/bin/bash
# Deploy MikroTik CHR on multiple servers
SERVERS="192.168.1.10 192.168.1.11 192.168.1.12"
PASSWORD="StrongPassword123"
for server in $SERVERS; do
ssh root@$server "curl -sL https://example.com/chr-installer.sh | bash -s -- --yes --reboot --password $PASSWORD"
done
```
## ⚙️ Command Line Options
| Option | Description |
|--------|-------------|
| `--clean` | Clean installation without autorun.scr (manual configuration required) |
| `--force` | Force re-download of the CHR image |
| `--no-verify` | Skip write verification |
| `--yes`, `-y` | Automatic mode, no confirmations |
| `--reboot` | Auto-reboot after installation (requires `--yes`) |
| `--version VER` | Specify CHR version (default: 7.16.1) |
| `--password PASS` | Set admin password (default: PASSWORD) |
| `-h`, `--help` | Show help message |
## 🔧 What the Script Does
1. **Checks dependencies** — installs required tools if missing
2. **Downloads CHR image** — from official MikroTik servers
3. **Validates the image** — checks MBR signature and file integrity
4. **Detects network settings** — IP address, gateway, interface
5. **Creates autorun.scr** — configures CHR to boot with your network settings
6. **Writes to disk** — uses `dd` with direct I/O for reliability
7. **Reboots** — into your new MikroTik CHR
## 🌐 Post-Installation Access
After installation and reboot, access your CHR via:
- **WinBox**: Connect to your server's IP address
- **SSH**: `ssh admin@YOUR_SERVER_IP`
- **WebFig**: `http://YOUR_SERVER_IP`
Default credentials:
- **Username**: `admin`
- **Password**: as specified with `--password` (default: `PASSWORD`)
## ⚠️ Important Notes
- **All data on the target disk will be erased!**
- The script requires root privileges
- Ensure you have console/KVM access in case of issues
- Test in a non-production environment first
- Default CHR license is free (limited to 1 Mbps upload)
## 🔒 Security Recommendations
1. **Change the default password** immediately if you used the default
2. **Disable unused services** after first login
3. **Configure firewall rules** to protect management access
4. **Update to latest RouterOS** version regularly
## 📝 Default CHR Configuration
The autorun script configures:
```routeros
/ip dns set servers=8.8.8.8,8.8.4.4
/ip service set telnet disabled=yes
/ip service set ftp disabled=yes
/ip service set www disabled=no
/ip service set ssh disabled=no
/ip service set api disabled=yes
/ip service set api-ssl disabled=yes
/ip service set winbox disabled=no
/ip address add address=YOUR_IP interface=ether1
/ip route add gateway=YOUR_GATEWAY
```
## 🐛 Troubleshooting
### CHR doesn't boot
- Check console output via VNC/KVM
- Verify the disk was written correctly
- Try `--clean` mode and configure manually
### Network not working after boot
- Verify IP and gateway settings in CHR
- Check if the interface name is `ether1`
- Review firewall rules on the hosting provider
### Can't connect via SSH/WinBox
- Wait 1-2 minutes for CHR to fully boot
- Verify the IP address is correct
- Check hosting provider's firewall/security groups
## 📄 License
This project is licensed under the MIT License - see the [LICENSE](LICENSE) file for details.
## 🤝 Contributing
Contributions are welcome! Please feel free to submit a Pull Request.
## 📮 Support
If you encounter any issues or have questions, please open an issue on GitHub.
---
**Disclaimer**: This script is provided as-is. Always ensure you have backups and console access before running on production systems. MikroTik and RouterOS are trademarks of MikroTik SIA.

228
README.md
View file

@ -0,0 +1,228 @@
# MikroTik CHR Installer
Скрипт автоматической установки MikroTik Cloud Hosted Router (CHR) на Linux VPS/VDS серверы.
[![License: MIT](https://img.shields.io/badge/License-MIT-yellow.svg)](https://opensource.org/licenses/MIT)
[![English](https://img.shields.io/badge/lang-English-blue.svg)](README-EN.md)
## 📋 Описание
Этот скрипт полностью автоматизирует установку MikroTik Cloud Hosted Router (CHR) на любой Linux VPS/VDS сервер. Он выполняет всё: от загрузки образа CHR до настройки сети и записи на диск — одной командой.
### Ключевые возможности
- 🚀 **Установка одной командой** — полностью автоматизированный процесс
- 🌐 **Автоопределение сетевых настроек** — IP-адрес, шлюз, интерфейс
- 📦 **Автоустановка зависимостей** — работает на Debian/Ubuntu, CentOS, RHEL, Fedora
- 🔧 **Преднастроенный autorun** — CHR загружается с уже настроенной сетью
- ✅ **Валидация образа** — проверка MBR-сигнатуры и целостности
- 🔄 **Гибкие настройки** — выбор версии, пароля и режима установки
## 🎯 Сценарии использования
### 1. Быстрая миграция VPS на MikroTik
Замените Linux VPS на полноценный MikroTik роутер за несколько минут. Идеально для:
- Создания VPN-сервера (WireGuard, L2TP, PPTP, OpenVPN)
- Организации защищённого шлюза для инфраструктуры
- Построения удалённой точки управления сетью
### 2. Лабораторная среда
Быстрый деплой MikroTik для:
- Тестирования конфигураций RouterOS перед продакшеном
- Изучения администрирования MikroTik
- Подготовки к сертификации (MTCNA, MTCRE и др.)
### 3. Центральный VPN-хаб
Превратите дешёвый VPS в центральный VPN-хаб для связи нескольких площадок:
- Облачный роутер для распределённых сетей
- Резервная точка связи
- Оптимизация маршрутизации по географии
### 4. Управление трафиком и мониторинг
Разверните CHR для:
- Управления полосой пропускания и QoS
- Анализа трафика встроенными инструментами
- Файрвола и защитного шлюза
## 📦 Требования
- Linux VPS/VDS сервер (Debian, Ubuntu, CentOS, RHEL, Fedora)
- Root-доступ
- Минимум 128 MB RAM (рекомендуется 256 MB+)
- Минимум 128 MB дискового пространства
- Активное интернет-соединение
## 🚀 Быстрый старт
### Установка одной командой
```bash
wget -qO- https://raw.githubusercontent.com/YOUR_REPO/mikrotik-chr-installer/main/chr-installer.sh | bash
```
### Ручная установка
```bash
# Скачать скрипт
wget https://raw.githubusercontent.com/YOUR_REPO/mikrotik-chr-installer/main/chr-installer.sh
# Сделать исполняемым
chmod +x chr-installer.sh
# Запустить установщик
sudo ./chr-installer.sh
```
## 📖 Примеры использования
### Базовая установка (интерактивная)
```bash
sudo ./chr-installer.sh
```
Скрипт выполнит:
1. Загрузку образа CHR
2. Определение сетевой конфигурации
3. Запрос подтверждения перед записью на диск
4. Предложение перезагрузки после установки
### Полностью автоматическая установка
```bash
sudo ./chr-installer.sh --yes --reboot
```
Без взаимодействия с пользователем — идеально для автоматизации.
### Выбор версии и пароля
```bash
sudo ./chr-installer.sh --version 7.14.3 --password MySecurePass123
```
### Чистая установка (без автонастройки)
```bash
sudo ./chr-installer.sh --clean
```
CHR загрузится с настройками по умолчанию. Полезно, когда хотите настроить всё вручную.
### Пример скрипта автоматизации
```bash
#!/bin/bash
# Деплой MikroTik CHR на несколько серверов
SERVERS="192.168.1.10 192.168.1.11 192.168.1.12"
PASSWORD="StrongPassword123"
for server in $SERVERS; do
ssh root@$server "curl -sL https://example.com/chr-installer.sh | bash -s -- --yes --reboot --password $PASSWORD"
done
```
## ⚙️ Параметры командной строки
| Параметр | Описание |
|----------|----------|
| `--clean` | Чистая установка без autorun.scr (требуется ручная настройка) |
| `--force` | Принудительно скачать образ заново |
| `--no-verify` | Пропустить верификацию записи |
| `--yes`, `-y` | Автоматический режим, без подтверждений |
| `--reboot` | Автоперезагрузка после установки (требует `--yes`) |
| `--version VER` | Указать версию CHR (по умолчанию: 7.16.1) |
| `--password PASS` | Установить пароль admin (по умолчанию: PASSWORD) |
| `-h`, `--help` | Показать справку |
## 🔧 Что делает скрипт
1. **Проверяет зависимости** — устанавливает недостающие утилиты
2. **Скачивает образ CHR**с официальных серверов MikroTik
3. **Валидирует образ** — проверяет MBR-сигнатуру и целостность
4. **Определяет сетевые настройки** — IP-адрес, шлюз, интерфейс
5. **Создаёт autorun.scr** — настраивает CHR для загрузки с вашими сетевыми параметрами
6. **Записывает на диск** — использует `dd` с direct I/O для надёжности
7. **Перезагружает** — в ваш новый MikroTik CHR
## 🌐 Доступ после установки
После установки и перезагрузки подключитесь к CHR через:
- **WinBox**: Подключение к IP-адресу сервера
- **SSH**: `ssh admin@IP_ВАШЕГО_СЕРВЕРА`
- **WebFig**: `http://IP_ВАШЕГО_СЕРВЕРА`
Учётные данные по умолчанию:
- **Логин**: `admin`
- **Пароль**: указанный через `--password` (по умолчанию: `PASSWORD`)
## ⚠️ Важно
- **Все данные на целевом диске будут уничтожены!**
- Скрипт требует права root
- Убедитесь, что у вас есть доступ к консоли/KVM на случай проблем
- Сначала протестируйте в непродакшн-среде
- Бесплатная лицензия CHR ограничена скоростью 1 Mbps на upload
## 🔒 Рекомендации по безопасности
1. **Смените пароль по умолчанию** сразу после установки
2. **Отключите неиспользуемые сервисы** после первого входа
3. **Настройте правила файрвола** для защиты управляющего доступа
4. **Регулярно обновляйте RouterOS** до последней версии
## 📝 Конфигурация CHR по умолчанию
Скрипт autorun настраивает:
```routeros
/ip dns set servers=8.8.8.8,8.8.4.4
/ip service set telnet disabled=yes
/ip service set ftp disabled=yes
/ip service set www disabled=no
/ip service set ssh disabled=no
/ip service set api disabled=yes
/ip service set api-ssl disabled=yes
/ip service set winbox disabled=no
/ip address add address=ВАШ_IP interface=ether1
/ip route add gateway=ВАШ_ШЛЮЗ
```
## 🐛 Решение проблем
### CHR не загружается
- Проверьте вывод консоли через VNC/KVM
- Убедитесь, что диск записан корректно
- Попробуйте режим `--clean` и настройте вручную
### Сеть не работает после загрузки
- Проверьте настройки IP и шлюза в CHR
- Убедитесь, что интерфейс называется `ether1`
- Проверьте правила файрвола у хостинг-провайдера
### Не удаётся подключиться через SSH/WinBox
- Подождите 1-2 минуты для полной загрузки CHR
- Проверьте правильность IP-адреса
- Проверьте файрвол/security groups хостинг-провайдера
## 📄 Лицензия
Проект распространяется под лицензией MIT — подробности в файле [LICENSE](LICENSE).
## 🤝 Участие в разработке
Приветствуются любые вклады! Смело создавайте Pull Request.
## 📮 Поддержка
Если возникли проблемы или вопросы — создайте Issue на GitHub.
---
**Отказ от ответственности**: Скрипт предоставляется как есть. Всегда делайте бэкапы и убедитесь в наличии консольного доступа перед запуском на продакшн-системах. MikroTik и RouterOS являются торговыми марками MikroTik SIA.

448
chr-installer.sh Normal file
View file

@ -0,0 +1,448 @@
#!/bin/bash
set -e
# Цвета для вывода
RED='\033[0;31m'
GREEN='\033[0;32m'
YELLOW='\033[1;33m'
CYAN='\033[0;36m'
NC='\033[0m'
log_info() { echo -e "${GREEN}[INFO]${NC} $1"; }
log_warn() { echo -e "${YELLOW}[WARN]${NC} $1"; }
log_error() { echo -e "${RED}[ERROR]${NC} $1"; }
log_debug() { echo -e "${CYAN}[DEBUG]${NC} $1"; }
# ============================================
# КОНФИГУРАЦИЯ
# ============================================
CHR_VERSION="7.16.1"
CHR_URL="https://download.mikrotik.com/routeros/${CHR_VERSION}/chr-${CHR_VERSION}.img.zip"
CHR_ZIP="chr-${CHR_VERSION}.img.zip"
CHR_IMG="chr-${CHR_VERSION}.img"
WORK_DIR="/tmp/chr-install"
MOUNT_POINT="/mnt/chr"
# Настройки CHR
ADMIN_PASSWORD="PASSWORD"
DNS_SERVERS="8.8.8.8,8.8.4.4"
# Флаги
SKIP_AUTORUN=false
FORCE_DOWNLOAD=false
VERIFY_WRITE=true
AUTO_YES=false
AUTO_REBOOT=false
# ============================================
# ПАРСИНГ АРГУМЕНТОВ
# ============================================
usage() {
echo "Использование: $0 [опции]"
echo ""
echo "Опции:"
echo " --clean Чистая установка без autorun.scr"
echo " --force Принудительно скачать образ заново"
echo " --no-verify Пропустить верификацию записи"
echo " --yes, -y Без подтверждений (автоматический режим)"
echo " --reboot Автоматическая перезагрузка (требует --yes)"
echo " --version VER Версия CHR (по умолчанию: $CHR_VERSION)"
echo " --password PASS Пароль admin (по умолчанию: $ADMIN_PASSWORD)"
echo " -h, --help Показать справку"
echo ""
echo "Примеры:"
echo " $0 --clean # Чистая установка с подтверждением"
echo " $0 --yes --reboot # Полностью автоматическая установка"
echo " $0 -y --clean --reboot # Автоматическая чистая установка"
exit 0
}
while [[ $# -gt 0 ]]; do
case $1 in
--clean)
SKIP_AUTORUN=true
shift
;;
--force)
FORCE_DOWNLOAD=true
shift
;;
--no-verify)
VERIFY_WRITE=false
shift
;;
--yes|-y)
AUTO_YES=true
shift
;;
--reboot)
AUTO_REBOOT=true
shift
;;
--version)
CHR_VERSION="$2"
CHR_URL="https://download.mikrotik.com/routeros/${CHR_VERSION}/chr-${CHR_VERSION}.img.zip"
CHR_ZIP="chr-${CHR_VERSION}.img.zip"
CHR_IMG="chr-${CHR_VERSION}.img"
shift 2
;;
--password)
ADMIN_PASSWORD="$2"
shift 2
;;
-h|--help)
usage
;;
*)
log_error "Неизвестная опция: $1"
usage
;;
esac
done
# ============================================
# ПРОВЕРКА ROOT
# ============================================
if [[ $EUID -ne 0 ]]; then
log_error "Скрипт должен запускаться от root"
exit 1
fi
# ============================================
# ПРОВЕРКА ЗАВИСИМОСТЕЙ
# ============================================
log_info "Проверка зависимостей..."
REQUIRED_TOOLS="wget unzip fdisk dd mount umount file md5sum xxd"
MISSING_TOOLS=""
for tool in $REQUIRED_TOOLS; do
if ! command -v $tool &> /dev/null; then
MISSING_TOOLS="$MISSING_TOOLS $tool"
fi
done
if [[ -n "$MISSING_TOOLS" ]]; then
log_warn "Отсутствуют утилиты:$MISSING_TOOLS"
log_info "Попытка установки..."
if command -v apt-get &> /dev/null; then
apt-get update && apt-get install -y wget unzip fdisk coreutils mount xxd
elif command -v yum &> /dev/null; then
yum install -y wget unzip util-linux coreutils vim-common
elif command -v dnf &> /dev/null; then
dnf install -y wget unzip util-linux coreutils vim-common
else
log_error "Установи вручную:$MISSING_TOOLS"
exit 1
fi
fi
log_info "Все зависимости в порядке"
# ============================================
# ПОДГОТОВКА РАБОЧЕЙ ДИРЕКТОРИИ
# ============================================
mkdir -p "$WORK_DIR"
cd "$WORK_DIR"
log_info "Рабочая директория: $WORK_DIR"
log_debug "Свободное место: $(df -h "$WORK_DIR" | tail -1 | awk '{print $4}')"
# ============================================
# СКАЧИВАНИЕ ОБРАЗА
# ============================================
if [[ "$FORCE_DOWNLOAD" == true ]] || [[ ! -f "$CHR_IMG" ]]; then
rm -f "$CHR_ZIP" "$CHR_IMG" "${CHR_IMG}.modified"
log_info "Скачивание CHR ${CHR_VERSION}..."
wget --progress=bar:force -O "$CHR_ZIP" "$CHR_URL"
# Проверка размера скачанного файла
ACTUAL_SIZE=$(stat -c%s "$CHR_ZIP")
log_debug "Размер скачанного файла: $ACTUAL_SIZE байт"
if [[ $ACTUAL_SIZE -lt 30000000 ]]; then
log_error "Файл слишком маленький, скачивание неполное"
exit 1
fi
# Проверка типа файла
FILE_TYPE=$(file "$CHR_ZIP")
log_debug "Тип файла: $FILE_TYPE"
if echo "$FILE_TYPE" | grep -q "Zip archive"; then
log_info "Распаковка ZIP..."
unzip -o "$CHR_ZIP"
elif echo "$FILE_TYPE" | grep -q "gzip"; then
log_info "Распаковка GZIP..."
gunzip -c "$CHR_ZIP" > "$CHR_IMG"
else
log_error "Неизвестный формат: $FILE_TYPE"
exit 1
fi
rm -f "$CHR_ZIP"
else
log_info "Используется существующий образ: $CHR_IMG"
fi
# ============================================
# ВАЛИДАЦИЯ ОБРАЗА (РАСШИРЕННАЯ)
# ============================================
log_info "Валидация образа..."
if [[ ! -f "$CHR_IMG" ]]; then
log_error "Образ не найден!"
ls -la "$WORK_DIR"
exit 1
fi
IMG_SIZE=$(stat -c%s "$CHR_IMG")
log_debug "Размер образа: $IMG_SIZE байт ($(( IMG_SIZE / 1024 / 1024 )) MB)"
# Проверка MBR сигнатуры (последние 2 байта первого сектора = 55 AA)
MBR_SIG=$(xxd -s 510 -l 2 -p "$CHR_IMG")
if [[ "$MBR_SIG" != "55aa" ]]; then
log_error "Неверная MBR сигнатура: $MBR_SIG (ожидается 55aa)"
exit 1
fi
log_debug "MBR сигнатура: OK (55aa)"
# Сохраняем MD5 оригинального образа
ORIGINAL_MD5=$(md5sum "$CHR_IMG" | awk '{print $1}')
log_info "MD5 оригинального образа: $ORIGINAL_MD5"
# Проверка таблицы разделов
log_debug "Таблица разделов:"
fdisk -l "$CHR_IMG" 2>/dev/null | grep -E "^(Disk|Device|${CHR_IMG})" || true
log_info "Образ прошёл валидацию ✓"
# ============================================
# ОПРЕДЕЛЕНИЕ СЕТЕВЫХ ПАРАМЕТРОВ
# ============================================
log_info "Определение сетевых параметров..."
INTERFACE=$(ip route | grep default | awk '{print $5}' | head -n1)
ADDRESS=$(ip addr show "$INTERFACE" 2>/dev/null | grep 'inet ' | grep -v '127.0.0.1' | awk '{print $2}' | head -n1)
GATEWAY=$(ip route | grep default | awk '{print $3}' | head -n1)
if [[ -z "$INTERFACE" || -z "$ADDRESS" || -z "$GATEWAY" ]]; then
log_error "Не удалось определить сетевые параметры"
log_error "INTERFACE=$INTERFACE ADDRESS=$ADDRESS GATEWAY=$GATEWAY"
exit 1
fi
log_info "Интерфейс: $INTERFACE | Адрес: $ADDRESS | Шлюз: $GATEWAY"
# ============================================
# ОПРЕДЕЛЕНИЕ ДИСКА
# ============================================
log_info "Определение целевого диска..."
echo ""
lsblk -d -o NAME,SIZE,MODEL,TYPE | grep -E "(NAME|disk)"
echo ""
DISK_DEVICE=$(lsblk -ndo NAME,TYPE | grep disk | head -n1 | awk '{print "/dev/"$1}')
if [[ -z "$DISK_DEVICE" ]]; then
log_error "Диск не найден"
exit 1
fi
DISK_SIZE=$(lsblk -ndo SIZE "$DISK_DEVICE")
log_warn "Целевой диск: $DISK_DEVICE ($DISK_SIZE)"
# ============================================
# ВЫБОР ОБРАЗА ДЛЯ ЗАПИСИ
# ============================================
FINAL_IMG="$CHR_IMG"
if [[ "$SKIP_AUTORUN" == true ]]; then
log_warn "Режим --clean: autorun.scr НЕ будет создан"
log_warn "Настройка CHR вручную после загрузки"
else
log_info "Создание autorun.scr..."
# Создаём копию образа для модификации
CHR_IMG_MOD="${CHR_IMG}.modified"
cp "$CHR_IMG" "$CHR_IMG_MOD"
# Монтирование
mkdir -p "$MOUNT_POINT"
OFFSET_SECTORS=$(fdisk -l "$CHR_IMG_MOD" 2>/dev/null | grep "${CHR_IMG_MOD}2" | awk '{print $2}')
if [[ -z "$OFFSET_SECTORS" ]]; then
OFFSET_BYTES=33571840
else
OFFSET_BYTES=$((OFFSET_SECTORS * 512))
fi
log_debug "Монтирование с offset: $OFFSET_BYTES"
mount -o loop,offset="$OFFSET_BYTES" "$CHR_IMG_MOD" "$MOUNT_POINT"
# Проверяем структуру
log_debug "Содержимое смонтированного раздела:"
ls -la "$MOUNT_POINT/" || true
if [[ ! -d "$MOUNT_POINT/rw" ]]; then
log_warn "Директория /rw не существует, создаём..."
mkdir -p "$MOUNT_POINT/rw"
fi
# Создание autorun
cat > "$MOUNT_POINT/rw/autorun.scr" <<EOF
/ip dns set servers=${DNS_SERVERS}
/ip service set telnet disabled=yes
/ip service set ftp disabled=yes
/ip service set www disabled=no
/ip service set ssh disabled=no
/ip service set api disabled=yes
/ip service set api-ssl disabled=yes
/ip service set winbox disabled=no
/ip dhcp-client remove [find]
/ip address add address=${ADDRESS} interface=[/interface ethernet find where name=ether1]
/ip route add gateway=${GATEWAY}
/user set 0 name=admin password=${ADMIN_PASSWORD}
EOF
# Синхронизация ФС перед размонтированием
sync
log_debug "autorun.scr создан:"
cat "$MOUNT_POINT/rw/autorun.scr"
# Проверяем что файл записался
if [[ ! -s "$MOUNT_POINT/rw/autorun.scr" ]]; then
log_error "autorun.scr пустой или не создан!"
umount "$MOUNT_POINT"
exit 1
fi
# Размонтирование с sync
sync
umount "$MOUNT_POINT"
sync
# Проверка MD5 после модификации
MODIFIED_MD5=$(md5sum "$CHR_IMG_MOD" | awk '{print $1}')
log_debug "MD5 после модификации: $MODIFIED_MD5"
if [[ "$ORIGINAL_MD5" == "$MODIFIED_MD5" ]]; then
log_warn "MD5 не изменился — возможно autorun.scr не записался"
fi
# Проверка MBR после модификации
MBR_SIG_MOD=$(xxd -s 510 -l 2 -p "$CHR_IMG_MOD")
if [[ "$MBR_SIG_MOD" != "55aa" ]]; then
log_error "MBR повреждён после модификации! Сигнатура: $MBR_SIG_MOD"
log_error "Используем оригинальный образ без autorun"
rm -f "$CHR_IMG_MOD"
SKIP_AUTORUN=true
FINAL_IMG="$CHR_IMG"
else
log_debug "MBR после модификации: OK"
FINAL_IMG="$CHR_IMG_MOD"
log_info "Autorun настроен ✓"
fi
fi
# ============================================
# ФИНАЛЬНОЕ ПОДТВЕРЖДЕНИЕ
# ============================================
echo ""
echo "============================================"
echo -e "${YELLOW} ТОЧКА НЕВОЗВРАТА!${NC}"
echo "============================================"
echo ""
echo "Образ: $FINAL_IMG"
echo "Диск: $DISK_DEVICE ($DISK_SIZE)"
echo "IP: $ADDRESS"
echo "Шлюз: $GATEWAY"
echo "Autorun: $(if [[ "$SKIP_AUTORUN" == true ]]; then echo "ОТКЛЮЧЕН"; else echo "включен"; fi)"
echo ""
echo -e "${RED}ВСЕ ДАННЫЕ НА $DISK_DEVICE БУДУТ УНИЧТОЖЕНЫ!${NC}"
echo ""
if [[ "$AUTO_YES" == true ]]; then
log_warn "Автоматический режим (--yes), продолжаем без подтверждения..."
else
read -p "Введи 'YES' для продолжения: " confirm
if [[ "$confirm" != "YES" ]]; then
log_info "Отменено"
exit 0
fi
fi
# ============================================
# ЗАПИСЬ НА ДИСК
# ============================================
log_info "Запись образа на $DISK_DEVICE..."
# Переводим FS в read-only чтобы избежать race condition
log_info "Перевод файловой системы в read-only..."
sync
echo 1 > /proc/sys/kernel/sysrq
echo u > /proc/sysrq-trigger
sleep 2
dd if="$FINAL_IMG" of="$DISK_DEVICE" bs=4M oflag=direct status=progress
log_info "Запись завершена"
# sync не нужен - FS уже в read-only, dd с oflag=direct пишет напрямую
# ============================================
# ВЕРИФИКАЦИЯ ЗАПИСИ
# ============================================
# После echo u файловая система в read-only, верификация невозможна
# MBR уже проверен до записи, dd с oflag=direct гарантирует запись
log_info "Верификация пропущена (FS в read-only после remount)"
# ============================================
# ЗАВЕРШЕНИЕ
# ============================================
echo ""
log_info "=========================================="
log_info "Установка CHR завершена успешно!"
log_info "=========================================="
echo ""
if [[ "$SKIP_AUTORUN" == true ]]; then
echo "После загрузки настрой вручную:"
echo " /ip address add address=$ADDRESS interface=ether1"
echo " /ip route add gateway=$GATEWAY"
echo ""
fi
echo "CHR будет доступен: ${ADDRESS%/*}"
echo ""
if [[ "$AUTO_YES" == true && "$AUTO_REBOOT" == true ]]; then
log_info "Автоматическая перезагрузка через 3 секунды..."
sleep 3
echo 1 > /proc/sys/kernel/sysrq
echo s > /proc/sysrq-trigger
sleep 1
echo u > /proc/sysrq-trigger
sleep 1
echo b > /proc/sysrq-trigger
elif [[ "$AUTO_YES" == true ]]; then
log_info "Перезагрузи вручную: reboot"
else
read -p "Перезагрузить сейчас? (y/n): " do_reboot
if [[ "$do_reboot" == "y" ]]; then
log_info "Перезагрузка..."
sleep 2
echo 1 > /proc/sys/kernel/sysrq
echo s > /proc/sysrq-trigger
sleep 1
echo u > /proc/sysrq-trigger
sleep 1
echo b > /proc/sysrq-trigger
else
log_info "Перезагрузи вручную: reboot"
fi
fi