Назначение: Скрипт для запуска ВНУТРИ MikroTik (RouterOS v7). Автоматически генерирует чистый .rsc-шаблон из текущей конфигурации, фильтруя специфичные для железа данные (MAC-адреса, серийные номера, лицензии) и добавляя блок переменных для последующего редактирования.
Преимущества:
Вариант А: Через WinBox
System → Scripts+ (Add)generate_clean_templateOKВариант Б: Через терминал (SSH/Telnet)
/system script add name=generate_clean_template source="ВСТАВИТЬ_КОД_СКРИПТА"
/system script run generate_clean_template
Файл clean_template_YYYY-MM-DD.rsc появится в Files. Скачай через WinBox (drag & drop).
# ============================================================
# MikroTik RouterOS Script: Генерация чистого шаблона конфигурации
# Версия: 1.0
# Дата: 2026-09-08
# Описание: Автоматически генерирует .rsc-шаблон из текущей конфигурации,
# фильтруя специфичные для железа данные
# ============================================================
:local scriptName "generate_clean_template"
:local date [/system clock get date]
:local time [/system clock get time]
:local filename "clean_template_" . [:pick $date 0 2] . [:pick $date 3 6] . [:pick $date 7 11] . ".rsc"
:log info "=== НАЧАЛО ГЕНЕРАЦИИ ШАБЛОНА ==="
:log info "Файл: $filename"
:put "=== НАЧАЛО ГЕНЕРАЦИИ ШАБЛОНА ==="
:put "Файл: $filename"
# ============================================================
# БЛОК 1: Создание заголовка с переменными
# ============================================================
:local header "# ============================================================\n"
:set header ($header . "# MikroTik Clean Template Configuration\n")
:set header ($header . "# Generated: $date $time\n")
:set header ($header . "# Source device: [/system identity get name]\n")
:set header ($header . "# ============================================================\n\n")
:set header ($header . "# === ШАБЛОН НАСТРОЕК (РЕДАКТИРОВАТЬ ПОД СЕБЯ) ===\n")
:set header ($header . ":local wanInterface \"ether1\"\n")
:set header ($header . ":local lanInterface \"ether2\"\n")
:set header ($header . ":local mgmtIP \"192.168.1.2/24\"\n")
:set header ($header . ":local targetIP \"192.168.1.50\"\n")
:set header ($header . ":local localSubnet \"192.168.1.0/24\"\n")
:set header ($header . ":local vpsEndpoint \"vps.example.com\"\n")
:set header ($header . ":local vpsPublicKey \"ЗАМЕНИТЬ_КЛЮЧ\"\n")
:set header ($header . "# === КОНЕЦ ШАБЛОНА ===\n\n")
# ============================================================
# БЛОК 2: Сбор конфигурации по секциям
# ============================================================
:local config ""
# --- Интерфейсы (списки) ---
:set config ($config . "# === INTERFACE LISTS ===\n")
:foreach ifaceList in=[/interface list find] do={
:local name [/interface list get $ifaceList name]
:if ($name != "all" && $name != "none") do={
:set config ($config . "/interface list add name=$name\n")
}
}
:set config ($config . "\n")
# --- Интерфейсы (члены списков) ---
:foreach member in=[/interface list member find] do={
:local list [/interface list member get $member list]
:local interface [/interface list member get $member interface]
:if ($list != "all" && $list != "none") do={
:set config ($config . "/interface list member add list=$list interface=$interface\n")
}
}
:set config ($config . "\n")
# --- Мосты ---
:set config ($config . "# === BRIDGES ===\n")
:foreach br in=[/interface bridge find] do={
:local name [/interface bridge get $br name]
:local hwOffload [/interface bridge get $br hardware-offload]
:set config ($config . "/interface bridge add name=$name hardware-offload=$hwOffload\n")
}
:set config ($config . "\n")
# --- Порты мостов ---
:foreach port in=[/interface bridge port find] do={
:local bridge [/interface bridge port get $port bridge]
:local interface [/interface bridge port get $port interface]
:set config ($config . "/interface bridge port add bridge=$bridge interface=$interface\n")
}
:set config ($config . "\n")
# --- IP-адреса (кроме системных) ---
:set config ($config . "# === IP ADDRESSES ===\n")
:foreach addr in=[/ip address find] do={
:local address [/ip address get $addr address]
:local interface [/ip address get $addr interface]
:local network [/ip address get $addr network]
:if ($interface != "lo" && $interface != "all") do={
:set config ($config . "/ip address add address=$address interface=$interface network=$network\n")
}
}
:set config ($config . "\n")
# --- DNS ---
:set config ($config . "# === DNS ===\n")
:local dnsServers [/ip dns get servers]
:local dnsAllowRemote [/ip dns get allow-remote-requests]
:set config ($config . "/ip dns set servers=$dnsServers allow-remote-requests=$dnsAllowRemote\n\n")
# --- WireGuard ---
:set config ($config . "# === WIREGUARD ===\n")
:foreach wg in=[/interface wireguard find] do={
:local name [/interface wireguard get $wg name]
:local listenPort [/interface wireguard get $wg listen-port]
:set config ($config . "/interface wireguard add name=$name listen-port=$listenPort disabled=no\n")
}
:set config ($config . "\n")
# --- WireGuard Peers ---
:foreach peer in=[/interface wireguard peers find] do={
:local interface [/interface wireguard peers get $peer interface]
:local publicKey [/interface wireguard peers get $peer public-key]
:local endpoint [/interface wireguard peers get $peer endpoint-address]
:local endpointPort [/interface wireguard peers get $peer endpoint-port]
:local allowedAddr [/interface wireguard peers get $peer allowed-address]
:set config ($config . "/interface wireguard peers add interface=$interface public-key=\"$publicKey\" endpoint-address=\"$endpoint\" endpoint-port=$endpointPort allowed-address=$allowedAddr persistent-keepalive=25\n")
}
:set config ($config . "\n")
# --- Таблицы маршрутизации ---
:set config ($config . "# === ROUTING TABLES ===\n")
:foreach rt in=[/routing table find] do={
:local name [/routing table get $rt name]
:if ($name != "main") do={
:set config ($config . "/routing table add fib name=$name\n")
}
}
:set config ($config . "\n")
# --- Маршруты ---
:foreach route in=[/routing route find] do={
:local dstAddr [/routing route get $route dst-address]
:local gateway [/routing route get $route gateway]
:local routingTable [/routing route get $route routing-table]
:if ($routingTable != "main" && $dstAddr != "0.0.0.0/0") do={
:set config ($config . "/routing route add dst-address=$dstAddr gateway=$gateway routing-table=$routingTable\n")
}
}
:set config ($config . "\n")
# --- Firewall Mangle ---
:set config ($config . "# === FIREWALL MANGLE ===\n")
:foreach mangle in=[/ip firewall mangle find] do={
:local chain [/ip firewall mangle get $mangle chain]
:local srcAddr [/ip firewall mangle get $mangle src-address]
:local dstAddr [/ip firewall mangle get $mangle dst-address]
:local action [/ip firewall mangle get $mangle action]
:local newMark [/ip firewall mangle get $mangle new-routing-mark]
:local inInt [/ip firewall mangle get $mangle in-interface]
:local cmd "/ip firewall mangle add chain=$chain"
:if ([:len $inInt] > 0 && $inInt != "all") do={ :set cmd ($cmd . " in-interface=$inInt") }
:if ([:len $srcAddr] > 0 && $srcAddr != "0.0.0.0/0") do={ :set cmd ($cmd . " src-address=$srcAddr") }
:if ([:len $dstAddr] > 0 && $dstAddr != "0.0.0.0/0") do={ :set cmd ($cmd . " dst-address=$dstAddr") }
:set cmd ($cmd . " action=$action")
:if ([:len $newMark] > 0) do={ :set cmd ($cmd . " new-routing-mark=$newMark") }
:set cmd ($cmd . " passthrough=no")
:set config ($config . $cmd . "\n")
}
:set config ($config . "\n")
# --- Firewall NAT ---
:set config ($config . "# === FIREWALL NAT ===\n")
:foreach nat in=[/ip firewall nat find] do={
:local chain [/ip firewall nat get $nat chain]
:local srcAddr [/ip firewall nat get $nat src-address]
:local outInt [/ip firewall nat get $nat out-interface]
:local action [/ip firewall nat get $nat action]
:local cmd "/ip firewall nat add chain=$chain"
:if ([:len $outInt] > 0 && $outInt != "all") do={ :set cmd ($cmd . " out-interface=$outInt") }
:if ([:len $srcAddr] > 0 && $srcAddr != "0.0.0.0/0") do={ :set cmd ($cmd . " src-address=$srcAddr") }
:set cmd ($cmd . " action=$action")
:set config ($config . $cmd . "\n")
}
:set config ($config . "\n")
# ============================================================
# БЛОК 3: Сохранение в файл
# ============================================================
:local fullContent $header
:set fullContent ($fullContent . $config)
/file print file=$filename
/file set $filename contents=$fullContent
:log info "=== ШАБЛОН СОХРАНЕН: $filename ==="
:log info "Размер: $[:len $fullContent] символов"
:put "=== ШАБЛОН СОХРАНЕН: $filename ==="
:put "Размер: $[:len $fullContent] символов"
:put "Скачай файл через WinBox (Files → drag & drop)"
:put "Отредактируй блок переменных в начале файла"
| Блок | Действие |
|---|---|
| 1 | Создает заголовок с блоком переменных для редактирования |
| 2 | Собирает конфигурацию по секциям: интерфейсы, мосты, IP, DNS, WireGuard, routing, firewall |
| 3 | Фильтрует системные объекты (lo, all, none) и специфичные данные (MAC, serial) |
| 4 | Сохраняет результат в файл clean_template_YYYY-MM-DD.rsc |
clean_template_YYYY-MM-DD.rsc со старого роутера/import file=clean_template_YYYY-MM-DD.rsc
/interface print /interface bridge port print
/ip address print
/interface wireguard peers print
/ip firewall mangle print /ip firewall nat print
/routing route print
| Симптом | Причина | Решение |
|---|---|---|
| Скрипт не создает файл | Недостаточно прав | Запускать от пользователя с правами full |
| Файл создается, но пустой | Ошибка в синтаксисе скрипта | Проверить логи: /log print where topics~"script" |
При импорте ошибка already exists | Остатки старой конфигурации | Выполнить /system reset-configuration no-defaults=yes перед импортом |
| Не поднимается WireGuard | Неверный ключ в шаблоне | Отредактировать $vpsPublicKey в начале файла |
Дата создания: 2026-09-08
Версия документа: 1.0
Автор: Александр (интегратор Savant/KNX)