Диагноз: зачем вообще fetch на роутере
Поднял мониторинг, написал скрипт, нужно отправить алерт в Telegram. Или забрать конфиг с внешнего сервера. Или скачать сертификат. Всё это можно сделать прямо из RouterOS — без сторонних инструментов, без SSH-тоннелей, без «а давай поставим Python на роутер».
Tool fetch делает именно это. Работает начиная с RouterOS 3.x, в современных версиях поддерживает HTTPS, POST, заголовки и работу через прокси. По факту это curl для бедных — но для большинства задач хватает с запасом.
Что ты получишь из этой статьи: все флаги с примерами, типовые сценарии от скачивания файла до отправки JSON, troubleshooting по ошибкам которые встречаются чаще всего, и готовые блоки кода которые можно копировать в скрипты.
Времени займёт 15 минут. Нужен: доступ к консоли RouterOS и понимание базового синтаксиса скриптов.
Что будет в статье
- Синтаксис и все параметры tool fetch
- GET-запросы: скачивание файлов и получение данных
- POST-запросы: отправка данных на внешний сервер
- Работа через HTTP-прокси
- HTTPS и работа с IPv6
- Использование в скриптах и планировщике
- Реальные примеры: Telegram, webhook, обновление конфига
- Troubleshooting по ошибкам
Совместимость и системные требования
| Параметр | Значение | Примечание |
|---|---|---|
| RouterOS минимум | v3.x | Базовый HTTP |
| HTTPS поддержка | v6.x+ | Требует синхронизацию времени |
| HTTP POST | v6.x+ | Параметры http-data и http-method |
| IPv6 fetch | v6.40+ | Адрес в квадратных скобках |
| Proxy поддержка | v6.x+ | Параметр proxy-server |
| Проверена на | v7.x (LTS) | Актуальная на момент публикации |
На момент публикации актуальна ветка RouterOS 7.x. Перед использованием проверь свежие релизы на mikrotik.com/download.
Синтаксис tool fetch: все параметры
Полный вид команды выглядит так:
/tool fetch \
url="https://example.com/file" \
mode=http \
http-method=get \
dst-path="/flash/file.txt" \
user="login" \
password="pass" \
http-header-field="Authorization: Bearer token123" \
http-data="key=value" \
proxy-server="192.168.1.100:3128" \
address="192.168.1.100" \
port=80 \
src-path="/path/on/server" \
upload=no \
keep-result=yes \
output=file \
as-value
Не пугайся — большинство параметров опциональны. В реальных задачах используешь 3-4 штуки. Разберём каждый.
Параметры: справочник
| Параметр | Значения | Что делает |
|---|---|---|
| url | строка | Полный URL запроса. Обязателен если не используешь address+src-path |
| mode | http, https, ftp, tftp, sftp | Протокол. По умолчанию определяется из url |
| http-method | get, post, put, head | HTTP-метод запроса. По умолчанию get |
| http-data | строка | Тело POST/PUT запроса |
| http-header-field | строка | Дополнительный HTTP-заголовок |
| dst-path | путь | Куда сохранить скачанный файл |
| output | file, user, none | Куда направить результат: файл, в переменную, никуда |
| as-value | флаг | Вернуть результат как значение (для скриптов) |
| keep-result | yes, no | Сохранять ли ответ. Нужен при output=file |
| proxy-server | ip:port | HTTP-прокси для запроса |
| user / password | строки | HTTP Basic Auth |
| check-certificate | yes, no | Проверять ли SSL-сертификат |
| upload | yes, no | Загрузить файл на сервер вместо скачивания |
| src-path | путь | Локальный файл для upload или путь на FTP |
| address | IP или hostname | Альтернатива url для FTP/TFTP |
| port | число | Порт сервера |
Таблица портов и протоколов
| Протокол | Порт по умолчанию | Параметр mode |
|---|---|---|
| HTTP | 80 | http |
| HTTPS | 443 | https |
| FTP | 21 | ftp |
| TFTP | 69 UDP | tftp |
| SFTP | 22 | sftp |
Архитектура: как работает fetch
Рецепт: базовые примеры
Шаг 1. Скачать файл на роутер
Самый частый сценарий — обновить конфиг или скачать скрипт с внешнего сервера.
/tool fetch url="http://192.168.1.100/backup.rsc" dst-path="/flash/backup.rsc"
Результат: файл появляется в файловой системе RouterOS. Проверяй через:
/file print where name="backup.rsc"
Если файл есть — fetch отработал. Если нет — смотри раздел Troubleshooting.
Шаг 2. HTTPS-запрос с проверкой сертификата
Для HTTPS роутеру нужно синхронизированное время и пул сертификатов. Сначала проверь:
/system clock print
Если время верное — запускай:
/tool fetch url="https://example.com/api/data" \
mode=https \
check-certificate=yes \
output=user \
as-value
Если сертификат не проходит проверку (самоподписанный или внутренний CA) — используй check-certificate=no. Но не оставляй это в продакшне без понимания рисков.
Шаг 3. GET-запрос и получение результата в переменную
Нужно получить данные от API и что-то с ними сделать в скрипте:
:local result [/tool fetch url="http://api.example.com/status" \
output=user as-value]
:put ($result->"data")
Параметр as-value возвращает ответ как массив с ключами status, data, filename. Ключ data содержит тело ответа.
Шаг 4. POST-запрос: отправка данных
Отправить данные на вебхук, в REST API или в Telegram:
/tool fetch url="https://api.telegram.org/bot<TOKEN>/sendMessage" \
http-method=post \
http-data="chat_id=123456789&text=Router+alert" \
output=none
Вот тут важно: http-data передаётся как строка form-urlencoded. Если API ожидает JSON — нужно добавить заголовок Content-Type.
Шаг 5. POST-запрос с JSON-телом
/tool fetch url="https://hooks.example.com/webhook" \
http-method=post \
http-header-field="Content-Type: application/json" \
http-data="{\"event\":\"router_up\",\"host\":\"gw01\"}" \
output=none
Кавычки внутри JSON экранируются через \». Если скрипт сложный — выноси тело в переменную заранее.
Шаг 6. HTTP Basic Authentication
/tool fetch url="http://monitor.example.com/api/push" \
user="apiuser" \
password="secretpass" \
http-method=post \
http-data="status=ok" \
output=none
Шаг 7. Запрос через прокси
Роутер за NAT без прямого доступа в интернет — используй прокси:
/tool fetch url="http://update.example.com/config.rsc" \
proxy-server="10.0.0.1:3128" \
dst-path="/flash/config.rsc"
Прокси указывается как ip:port. Аутентификация на прокси через Basic Auth пока не поддерживается нативно — если прокси требует авторизацию, нужен прокси без неё или обходное решение.
Шаг 8. IPv6 fetch
Адрес IPv6 нужно заключить в квадратные скобки прямо в URL:
/tool fetch url="http://[2001:db8::1]/path/file.txt" \
dst-path="/flash/file.txt"
Если hostname резолвится в IPv6 — всё работает автоматически без квадратных скобок. Скобки нужны только при явном указании IPv6-адреса.
Шаг 9. Загрузка файла на сервер (upload)
/tool fetch address="192.168.1.100" \
src-path="/flash/backup.rsc" \
upload=yes \
user="ftpuser" \
password="ftppass" \
mode=ftp
Шаг 10. Скачать и сразу выполнить скрипт
Классический паттерн для централизованного управления конфигами:
/tool fetch url="http://cfg.example.com/setup.rsc" dst-path="/flash/setup.rsc"
/import /flash/setup.rsc
Сначала скачиваешь, потом импортируешь. Никогда не делай это в одну строку через eval — сначала убедись что файл скачался корректно.
Реальные сценарии использования
Алерт в Telegram при падении линка
Скрипт для Netwatch или scheduler. Срабатывает при изменении статуса интерфейса:
:local botToken "1234567890:ABCdefGHIjklMNOpqrSTUvwxyz"
:local chatId "123456789"
:local hostname [/system identity get name]
:local msg ("ALERT: " . $hostname . " - WAN link DOWN")
/tool fetch \
url=("https://api.telegram.org/bot" . $botToken . "/sendMessage") \
http-method=post \
http-data=("chat_id=" . $chatId . "&text=" . $msg) \
output=none
Точка — оператор конкатенации строк в RouterOS. Собираешь URL и тело динамически.
Проверка внешнего IP и запись в переменную
:local ipResult [/tool fetch url="http://ifconfig.me/ip" \
output=user as-value]
:local currentIP ($ipResult->"data")
:log info ("Current external IP: " . $currentIP)
Динамическое обновление DNS через API
:local apiKey "your-api-key"
:local domain "home.example.com"
:local newIP [/ip address get [find interface="pppoe-out1"] address]
# Убираем маску подсети
:set newIP [:pick $newIP 0 [:find $newIP "/"]]
/tool fetch \
url=("https://dyndns.example.com/update?hostname=" . $domain . "&myip=" . $newIP) \
http-header-field=("Authorization: ApiKey " . $apiKey) \
output=none
Max Bot / мониторинг через webhook
Паттерн для отправки метрик на внешний мониторинг. Работает с любым сервисом который принимает POST:
:local cpuLoad [/system resource get cpu-load]
:local memFree [/system resource get free-memory]
:local hostname [/system identity get name]
:local jsonBody ("{\"host\":\"" . $hostname . "\",\"cpu\":" . $cpuLoad . ",\"mem_free\":" . $memFree . "}")
/tool fetch url="https://metrics.example.com/push" \
http-method=post \
http-header-field="Content-Type: application/json" \
http-data=$jsonBody \
output=none
Скачивание конфига по расписанию
Создаёшь задачу в scheduler, которая раз в сутки тянет конфиг с сервера:
/system scheduler add \
name="fetch-config" \
start-time=03:00:00 \
interval=1d \
on-event="/tool fetch url=\"http://cfg.example.com/gw01.rsc\" dst-path=\"/flash/gw01.rsc\""
Проверка: как убедиться что fetch сработал
Проверить статус последней команды
# Запустить fetch и проверить код ответа
:local res [/tool fetch url="http://example.com/test" output=user as-value]
:put ($res->"status")
Поле status содержит «finished» при успехе. При ошибке fetch выбрасывает исключение — оборачивай в :do { } on-error { }.
Проверить что файл скачался
/file print detail where name="backup.rsc"
Посмотреть лог выполнения
/log print where topics~"script"
/log print where topics~"error"
Тест DNS-резолвинга
/ip dns cache print
/tool resolve address="api.telegram.org"
Обработка ошибок в скриптах
Fetch при ошибке кидает исключение и останавливает скрипт. Нормальная практика — обернуть в do/on-error:
:do {
:local res [/tool fetch url="https://example.com/api" \
output=user as-value]
:local data ($res->"data")
:log info ("Fetch OK: " . $data)
} on-error={
:log error "Fetch failed: connection error or timeout"
}
Это не опциональная практика. Если fetch упадёт без обёртки в планировщике — следующие строки скрипта не выполнятся. Узнаешь об этом в лучшем случае по логу.
Осложнения: ошибки и их решения
could not resolve host
| Причина | Решение |
|---|---|
| DNS не настроен | Проверить /ip dns print, добавить серверы |
| DNS работает но не отвечает | /tool resolve address=»google.com» — если ошибка, DNS недоступен |
| Нет маршрута к DNS-серверу | /ip route print — проверить дефолтный маршрут |
/ip dns set servers=8.8.8.8,1.1.1.1
/tool resolve address="example.com"
SSL error / certificate verification failed
| Причина | Решение |
|---|---|
| Неверное время на роутере | Настроить NTP: /system ntp client set enabled=yes servers=pool.ntp.org |
| Самоподписанный сертификат | Импортировать CA или поставить check-certificate=no |
| Устаревший CA в RouterOS | Обновить RouterOS или импортировать актуальный CA вручную |
/system ntp client set enabled=yes servers=pool.ntp.org
/system clock print
# Убедись что дата и время корректны
# Импорт CA-сертификата:
/certificate import file-name=ca.crt passphrase=""
connection timed out
| Причина | Решение |
|---|---|
| Нет маршрута к серверу | Проверить default route, /ip route print |
| Firewall блокирует исходящий трафик | /ip firewall filter print — проверить правила output/forward |
| Сервер недоступен | /tool ping address=»example.com» |
/ip route print where active=yes
/tool ping address="8.8.8.8" count=4
/ip firewall filter print chain=output
got error response: 403 / 401
Это не ошибка fetch — это ответ сервера. 401 — нет авторизации, 403 — нет прав.
# Проверить что передаёшь правильные учётные данные:
/tool fetch url="http://api.example.com/test" \
user="login" password="pass" \
output=user as-value
fetch через прокси не работает
# Проверить доступность прокси:
/tool ping address="10.0.0.1"
# Проверить что прокси принимает запросы без авторизации:
/tool fetch url="http://ifconfig.me/ip" \
proxy-server="10.0.0.1:3128" \
output=user as-value
fetch не работает из scheduler
Планировщик запускает скрипты в ограниченном окружении. Частая проблема — интерфейс ещё не поднялся в момент выполнения.
# Добавить задержку в начало скрипта:
:delay 10s
# Или проверять наличие маршрута перед запросом:
:if ([/ip route print count-only where active=yes gateway!=""] > 0) do={
/tool fetch url="http://example.com/config.rsc" dst-path="/flash/config.rsc"
}
Некорректные символы в http-data
Пробелы, кириллица и спецсимволы в POST-данных нужно экранировать. Пробел — это +, остальное — percent-encoding.
# Пробел в тексте - заменяем на +:
http-data="chat_id=123&text=Link+is+down"
# Для сложного текста с кириллицей - лучше JSON:
http-data="{\"text\":\"Линк упал\"}"
Альтернативы tool fetch
Fetch не единственный способ получить данные извне. Вот когда стоит смотреть в другую сторону:
| Инструмент | Когда использовать | Ограничения |
|---|---|---|
| tool fetch | HTTP/HTTPS/FTP задачи, скрипты, автоматизация | Нет multipart, ограниченный набор заголовков |
| TFTP (встроен) | Скачать firmware, конфиг по TFTP | Только простая передача файлов |
| FTP через fetch | Загрузка бэкапов на FTP-сервер | FTP без TLS не безопасен |
| Netinstall | Переустановка RouterOS | Не для автоматизации из скриптов |
| SSH из внешней системы | Когда нужны сложные HTTP-операции | Требует внешнего сервера с curl/python |
Профилактика: как не поломать
Мониторинг
Если fetch отправляет алерты — добавь мониторинг самого роутера. Нет смысла в алертах если роутер молчит из-за проблем с сетью.
/tool netwatch add host="8.8.8.8" interval=30s \
up-script="/log info \"Internet OK\"" \
down-script="/log warning \"Internet DOWN - fetch alerts may fail\""
Резервное копирование
# Создать бэкап и отправить на сервер:
/system backup save name="gw01-backup"
/tool fetch address="192.168.1.100" \
src-path="/flash/gw01-backup.backup" \
upload=yes \
user="ftpuser" \
password="ftppass" \
mode=ftp
Что бэкапить: полный backup (.backup) и RSC-экспорт конфига (/export). Как часто: ежедневно. Где хранить: на отдельном сервере, не на самом роутере.
Безопасность
Несколько правил которые нельзя игнорировать:
- Не храни токены и пароли прямо в скриптах — используй /system script env если версия поддерживает, или выноси в переменные которые задаются при запуске
- Ограничь доступ к конфигурации роутера по IP в /ip service
- Не используй check-certificate=no для внешних сервисов — настрой время и импортируй CA
- Лог fetch-запросов с токенами попадает в /log — учти это при настройке remote syslog
# Ограничить WinBox и SSH по IP:
/ip service set winbox address=192.168.1.0/24
/ip service set ssh address=192.168.1.0/24
# Настроить NTP:
/system ntp client set enabled=yes servers=pool.ntp.org,time.cloudflare.com
Обновление RouterOS
Перед обновлением: сделай бэкап, проверь changelog на наличие изменений в tool fetch, проверь скрипты на тестовом устройстве. Откат: /system backup load name=»pre-update-backup».
# Проверить текущую версию:
/system resource print
# Проверить доступные обновления:
/system package update check-for-updates
FAQ: вопросы которые задают чаще всего
Почему fetch не работает с HTTPS на старом RouterOS?
Две причины. Первая — версия RouterOS до 6.x не поддерживает HTTPS в fetch вообще. Вторая — не синхронизировано время. Сертификаты проверяются в том числе по времени: если на роутере 2018 год, а сертификат выпущен в 2023 — проверка провалится. Настрой NTP первым делом.
/system clock print
/system ntp client print
Как проверить что fetch отправил данные правильно?
Используй webhook.site или requestbin.com — сервисы которые принимают любые HTTP-запросы и показывают их содержимое. Направь тестовый fetch туда и посмотри что реально пришло на сервер.
/tool fetch url="https://webhook.site/your-unique-id" \
http-method=post \
http-header-field="Content-Type: application/json" \
http-data="{\"test\":\"hello\"}" \
output=none
Что если нужно передать несколько HTTP-заголовков?
RouterOS поддерживает только один http-header-field в одной команде. Это ограничение платформы. Обходное решение — если нужны несколько заголовков, проверь нельзя ли обойтись одним (например, Authorization + Content-Type). Если без нескольких заголовков никак — задачу придётся решать с внешнего сервера через curl или Python.
Почему fetch работает из консоли но не из scheduler?
Планировщик запускает скрипты в момент загрузки или по таймеру. Если задача запускается при старте — сетевой интерфейс может быть ещё не поднят. Добавь :delay 15s в начало скрипта или проверяй наличие активного маршрута перед запросом fetch.
Как передать бинарные данные через fetch?
Никак. Tool fetch работает только с текстом. Для передачи бинарных файлов используй ftp/sftp upload или настрой внешний сервис.
Можно ли использовать fetch для скачивания больших файлов?
Технически да, но с ограничениями: оперативная память роутера ограничена, при output=user весь ответ буферизуется в памяти. Для файлов больше нескольких мегабайт используй output=file и dst-path. Для RouterOS с ограниченной флеш-памятью — TFTP или FTP могут быть надёжнее.
Прогноз
Теперь у тебя есть полная картина по tool fetch: от базового скачивания файла до отправки JSON в Telegram из скрипта планировщика. Команда простая, параметров немного, а применений — масса. Автоматизация мониторинга, централизованное управление конфигами, интеграция с внешними сервисами — всё это закрывается несколькими строками RouterOS-скрипта.
Одна мысль напоследок. Fetch это инструмент, а не архитектура. Если у тебя десятки роутеров и сложная логика — смотри в сторону Ansible с модулем routeros или централизованного управления через The Dude / Zabbix. Но для одного роутера, простых алертов и автоматического обновления конфига — fetch закрывает задачу элегантно и без лишних зависимостей.
Оставайтесь на связи
Рецепты от IT-боли. Без воды, без рекламы, без маркетинговой шелухи.
Подписаться на IT-Аптеку →



