💡 Мощный инструмент для автоматизации управления прошивками UniFi в офлайн-среде
- 🎯 Что это?
- ✨ Возможности
- 🏗️ Архитектура
- ⚙️ Требования
- 🚀 Быстрый старт
- 📖 Режимы работы
- 🔧 Примеры использования
- 🌐 Работа с прокси
- 🛠️ Переменные окружения
- 🐛 Отладка
- 📊 Мониторинг
- ❓ FAQ
unifi-fw-cache — это универсальный bash-скрипт для управления кэшем прошивок UniFi Network Controller. Идеальное решение для:
- 🔒 Изолированных сетей без доступа к интернету
- 🏢 Корпоративных сред с жесткими политиками безопасности
- 📦 Массового развертывания устройств UniFi
- 🌍 Региональных зеркал для ускорения обновлений
- 📥 Автоматическое скачивание прошивок из
firmware.json - 📂 Организация файлов в структурированное хранилище
- 🔄 Обновление
firmware_meta.jsonдля интеграции с UniFi - 🔗 Поддержка прямых URL для скачивания прошивок
- 🎯 Автоматическое определение совместимых устройств из каталога
- 👤 Управление правами доступа (unifi:unifi)
- ♻️ Автоматический перезапуск службы
- 💾 Полное зеркалирование репозитория прошивок
- 🏗️ Создание локального хранилища fw-download.ubnt.com
- 🚀 Поддержка массового скачивания
- ✅ Проверка MD5-сумм
- 🎯 Автопоиск совместимых устройств по MD5, имени файла и версии
- 📋 Создание правильного поля
devicesвfirmware_meta.json - 🔄 Работает для всех источников: URL, локальные файлы, каталог
- 💡 Одна прошивка автоматически связывается со всеми совместимыми моделями
- 🚀 Прямое получение через API Ubiquiti (firmware.json недоступен по URL)
- 🔄 Автоматическое преобразование формата API → firmware.json
- 🎯 Фильтрация: только UniFi Network + стабильные релизы
- 💾 Два каталога:
firmware.ubnt.json(оригинал) +firmware.json(переписанный) - 🌐 Поддержка переписывания хостов для локальных зеркал
flowchart TD
A[🌐 UniFi Cloud] -->|firmware.json| B[📋 Catalog Parser]
B --> C{Режим работы}
C -->|Controller Mode| D[🎮 Режим контроллера]
C -->|Mirror Mode| E[🌍 Режим зеркала]
D --> F[📥 Download Manager]
E --> G[💾 Mirror Builder]
F --> H[📁 Cache Storage]
G --> I[🗄️ Mirror Storage]
H --> J[📝 firmware_meta.json]
J --> K[🖥️ UniFi Controller]
style A fill:#f9f,stroke:#333,stroke-width:4px
style K fill:#9f9,stroke:#333,stroke-width:4px
graph LR
A[/var/lib/unifi/firmware/] --> B[UAP6MP/]
A --> C[U7PG2/]
A --> D[UAL6/]
B --> B1[7.0.66.17454/]
B1 --> B2[📦 BZ.mt7622_7.0.66+17454.bin]
C --> C1[6.7.31.15618/]
C1 --> C2[📦 BZ.mt7621_6.7.31+15618.bin]
D --> D1[6.7.31.15618/]
D1 --> D2[📦 BZ.mt7621_6.7.31+15618.bin]
A --> E[📋 firmware_meta.json]
style A fill:#e1f5fe
style E fill:#fff9c4
| Компонент | Версия | Описание |
|---|---|---|
| 🐚 Bash | 4.0+ | Используются массивы и process substitution |
| 🔧 jq | 1.5+ | Парсинг JSON каталога прошивок |
| 📥 wget | 1.14+ | Загрузка файлов с поддержкой докачки |
| 🔑 md5sum | - | Проверка целостности файлов |
| 📊 coreutils | 8.0+ | stat, install для управления файлами |
| ⚙️ systemd | - | Управление службой unifi (опционально) |
| 👑 root | - | Доступ к /var/lib/unifi |
git clone https://github.com/your-account/unifi-fw-cache.git
cd unifi-fw-cache
chmod +x unifi-fw-cache.sh# 🎯 Кэшировать прошивки для конкретных устройств
sudo ./unifi-fw-cache.sh --from-catalog --codes "UAP6MP U7PG2 UAL6"
# 🔗 Скачать прошивку по прямому URL (автоматически определит совместимые устройства)
sudo ./unifi-fw-cache.sh https://dl.ui.com/unifi/firmware/U7PG2/6.7.35.15586/BZ.qca956x_6.7.35+15586.bin
# 📦 Добавить локальные файлы в кэш
sudo ./unifi-fw-cache.sh --src-dir ./firmware-files/
# 🌐 Создать полное зеркало
./unifi-fw-cache.sh --mirror-all --mirror-root /srv/unifi-mirrorРабота напрямую с кэшем UniFi Network Controller:
sequenceDiagram
participant U as 👤 User
participant S as 📜 Script
participant C as 📋 Catalog
participant W as 🌐 Web
participant F as 📁 Cache
participant M as 📝 Meta
participant UC as 🖥️ Controller
U->>S: --from-catalog --codes "UAP6MP"
S->>C: Read firmware.json
C-->>S: Device info
S->>W: wget firmware
W-->>S: Binary file
S->>F: Store in /var/lib/unifi/firmware
S->>M: Update firmware_meta.json
S->>UC: systemctl restart unifi
UC-->>U: ✅ Firmware cached
Создание локального зеркала всех прошивок:
flowchart LR
A[📋 firmware.json] -->|Parse| B[🔍 Extract URLs]
B -->|Download| C[📥 wget]
C -->|Store| D[📂 Mirror Structure]
D --> E[data/]
E --> F[unifi-firmware/]
F --> G[UAP6MP/7.0.66.17454/]
F --> H[U7PG2/6.7.31.15618/]
F --> I[UAL6/6.7.31.15618/]
style A fill:#fff9c4
style D fill:#e1f5fe
# 🏢 Офисные точки доступа
sudo ./unifi-fw-cache.sh --from-catalog \
--codes "UAP6MP UAP6LR U6MESH" \
--app-version "9.0.131"# 🌐 Переопределение хоста загрузки
sudo REWRITE_HOST=mirror.local.lan \
./unifi-fw-cache.sh --from-catalog \
--codes "U7PG2 UAL6"# 💾 Файлы уже скачаны в папку firmware/
sudo ./unifi-fw-cache.sh --src-dir ./firmware/
# 📝 С указанием исходного URL для метаданных
sudo ./unifi-fw-cache.sh \
--src-url "https://dl.ui.com/unifi/firmware/UAL6/6.7.31.15618/BZ.mt7621_6.7.31+15618.bin" \
./BZ.mt7621_6.7.31+15618.bin# 📥 Одна прошивка по прямому URL
sudo ./unifi-fw-cache.sh \
https://dl.ui.com/unifi/firmware/U7PG2/6.7.35.15586/BZ.qca956x_6.7.35+15586.251030.2141.bin \
--no-restart
# 📦 Несколько прошивок за раз
sudo ./unifi-fw-cache.sh \
https://dl.ui.com/unifi/firmware/U7PG2/6.7.35.15586/BZ.qca956x_6.7.35+15586.bin \
https://dl.ui.com/unifi/firmware/UAP6MP/6.6.77.14836/U6Mesh.qca956x.v6.6.77.bin \
https://dl.ui.com/unifi/firmware/USW/7.0.66.17440/US.bcm5334x.v7.0.66.bin \
--threads 10
# 🎯 Автоматически определятся все совместимые устройства
# Вывод покажет:
# [URL] U7PG2 6.7.35 (devices: U7PG2 U7MSH U7LR) <- BZ.qca956x_6.7.35+15586.binСкрипт автоматически находит все совместимые модели для каждой прошивки:
# При скачивании прошивки для U7PG2
sudo ./unifi-fw-cache.sh \
https://dl.ui.com/unifi/firmware/U7PG2/6.7.35.15586/BZ.qca956x_6.7.35+15586.bin
# firmware_meta.json будет содержать:
# {
# "md5": "abc123...",
# "version": "6.7.35.15586",
# "path": "U7PG2/6.7.35.15586/BZ.qca956x_6.7.35+15586.bin",
# "devices": ["U7PG2", "U7MSH", "U7LR"] ← все совместимые модели!
# }
# Поиск совместимых устройств работает по приоритетам:
# 1️⃣ По MD5 хешу (самый надёжный)
# 2️⃣ По имени файла + версии
# 3️⃣ По имени файла
# 4️⃣ Fallback к определённой модели из URL# 🌐 Рекомендуемый способ: получение каталога через API
./unifi-fw-cache.sh --fetch-catalog-api \
--mirror-all \
--mirror-root /srv/unifi-mirror \
--rewrite-catalog-host fw-mirror.example.com
# Результат:
# - firmware.ubnt.json → оригинальные ссылки (для скачивания)
# - firmware.json → переписанные хосты (для контроллера)
# - data/ → скачанные файлы
# 💿 Альтернатива: использование локального каталога
./unifi-fw-cache.sh --mirror-all \
--mirror-root /srv/unifi-mirror \
--catalog ./firmware.json# 🚀 Скачать из каталога + добавить локальные файлы
sudo ./unifi-fw-cache.sh \
--from-catalog --codes "UAP6MP" \
--src-dir ./additional-firmware/ \
https://dl.ui.com/unifi/firmware/U7PG2/special.bin# HTTP прокси
export http_proxy=http://proxy.company.com:3128
export https_proxy=http://proxy.company.com:3128
# SOCKS5 прокси (требуется tsocks/proxychains)
proxychains ./unifi-fw-cache.sh --from-catalog --codes "UAP6MP"# Использовать внутреннее зеркало
REWRITE_HOST=unifi-mirror.local.lan \
sudo -E ./unifi-fw-cache.sh --from-catalog --codes "UAP6MP"| Переменная | По умолчанию | Описание |
|---|---|---|
📁 UNIFI_FW_DIR |
/var/lib/unifi/firmware |
Директория кэша прошивок |
📋 CATALOG |
/var/lib/unifi/firmware.json |
Путь к каталогу прошивок |
🔢 APP_VERSION |
auto | Версия контроллера (auto = последняя) |
👤 UNIFI_USER |
unifi |
Владелец файлов |
👥 UNIFI_GROUP |
unifi |
Группа файлов |
♻️ RESTART |
1 |
Перезапускать службу (1/0) |
🌐 REWRITE_HOST |
- | Заменить хост при загрузке |
📂 MIRROR_ROOT |
. |
Корень для режима зеркала |
# 🔧 Кастомная директория кэша
UNIFI_FW_DIR=/opt/unifi-cache sudo ./unifi-fw-cache.sh --from-catalog --codes "UAP6MP"
# 🚫 Без перезапуска службы
RESTART=0 sudo ./unifi-fw-cache.sh --src-dir ./firmware/
# 📌 Фиксированная версия контроллера
APP_VERSION=8.5.6 sudo ./unifi-fw-cache.sh --from-catalog --codes "U7PG2"# 🔍 Логи контроллера UniFi
grep -i firmware_meta /usr/lib/unifi/logs/server.log | tail -n 50
# 📊 Статус службы
systemctl status unifi
# 🗂️ Проверка кэша
ls -la /var/lib/unifi/firmware/
cat /var/lib/unifi/firmware/firmware_meta.json | jq .# 🐞 Включить отладку bash
bash -x ./unifi-fw-cache.sh --from-catalog --codes "UAP6MP"
# 📋 Проверить содержимое каталога
jq '.["9.0.131"].release | keys' /var/lib/unifi/firmware.json# 📦 Размер кэша
du -sh /var/lib/unifi/firmware/
# 📋 Количество прошивок
find /var/lib/unifi/firmware -name "*.bin" -o -name "*.tar" | wc -l
# 🔍 Группировка по устройствам
for dir in /var/lib/unifi/firmware/*/; do
device=$(basename "$dir")
count=$(find "$dir" -name "*.bin" -o -name "*.tar" | wc -l)
echo "📱 $device: $count firmware(s)"
done# Добавить в crontab
# 🌙 Ежедневное обновление кэша в 3:00
0 3 * * * /opt/unifi-fw-cache/unifi-fw-cache.sh --from-catalog --codes "UAP6MP U7PG2 UAL6" >> /var/log/unifi-fw-cache.log 2>&1
# 📅 Еженедельное полное зеркалирование
0 2 * * 0 /opt/unifi-fw-cache/unifi-fw-cache.sh --mirror-all --mirror-root /srv/unifi-mirror >> /var/log/unifi-mirror.log 2>&1Симптомы: После выполнения скрипта прошивки не появляются в UI контроллера.
Решение:
# 1️⃣ Проверить права доступа
ls -la /var/lib/unifi/firmware/
chown -R unifi:unifi /var/lib/unifi/firmware/
# 2️⃣ Проверить формат firmware_meta.json
jq . /var/lib/unifi/firmware/firmware_meta.json
# 3️⃣ Перезапустить контроллер
systemctl restart unifi
# 4️⃣ Проверить логи
tail -f /usr/lib/unifi/logs/server.logСимптомы: Permission denied при записи файлов.
Решение:
# ✅ Запускать с sudo
sudo ./unifi-fw-cache.sh --from-catalog --codes "UAP6MP"
# 🔧 Или изменить переменные окружения
UNIFI_USER=$USER UNIFI_GROUP=$USER RESTART=0 ./unifi-fw-cache.sh ...Симптомы: wget не может скачать файлы.
Решение:
# 🔍 Проверить доступность
wget --spider https://dl.ui.com/unifi/firmware/UAP6MP/7.0.66.17454/BZ.mt7622_7.0.66+17454.240913.0102.bin
# 🌐 Использовать прокси
export https_proxy=http://proxy:3128
sudo -E ./unifi-fw-cache.sh --from-catalog --codes "UAP6MP"
# 🔀 Или внутреннее зеркало
REWRITE_HOST=mirror.local ./unifi-fw-cache.sh --from-catalog --codes "UAP6MP"Симптомы: Предупреждения о несовпадении контрольных сумм.
Решение:
# 🔄 Перекачать файл
rm /var/lib/unifi/firmware/UAP6MP/7.0.66.17454/*.bin
sudo ./unifi-fw-cache.sh --from-catalog --codes "UAP6MP"
# ✅ Проверить целостность вручную
md5sum /var/lib/unifi/firmware/UAP6MP/7.0.66.17454/*.binВопрос: Скрипт показывает несколько устройств для одной прошивки. Как это работает?
Ответ:
Скрипт автоматически определяет все совместимые модели, используя каталог /var/lib/unifi/firmware.json:
# Приоритет 1: Поиск по MD5 (самый точный)
# Находит все устройства с идентичной прошивкой по хешу
# Приоритет 2: Поиск по имени файла + версии
# Для случаев, когда MD5 ещё не вычислен
# Приоритет 3: Поиск по имени файла
# Максимальное покрытие совместимости
# Fallback: Определение из URL/имени файла
# Если каталог недоступен или устройства не найденыПример:
# Скачиваем прошивку для U7PG2
sudo ./unifi-fw-cache.sh \
https://dl.ui.com/unifi/firmware/U7PG2/6.7.35.15586/BZ.qca956x_6.7.35+15586.bin
# Вывод покажет все совместимые устройства:
[URL] U7PG2 6.7.35 (devices: U7PG2 U7MSH U7LR) <- BZ.qca956x_6.7.35+15586.bin
# firmware_meta.json будет содержать:
{
"devices": ["U7PG2", "U7MSH", "U7LR"],
"md5": "...",
"version": "6.7.35.15586",
"path": "U7PG2/6.7.35.15586/BZ.qca956x_6.7.35+15586.bin"
}Преимущества:
- ✅ Одна прошивка автоматически доступна для всех совместимых моделей
- ✅ Контроллер предлагает правильную прошивку для каждого устройства
- ✅ Не нужно скачивать дубликаты для совместимых моделей
- ✅ Данные берутся из официального каталога UniFi
Симптомы: Файл скачался, но метаданные не обновились.
Решение:
# 1️⃣ Проверить, что используется правильный режим
# Прямые URL требуют root-прав (режим контроллера)
sudo ./unifi-fw-cache.sh https://dl.ui.com/.../firmware.bin
# 2️⃣ Проверить firmware_meta.json
cat /var/lib/unifi/firmware/firmware_meta.json | jq '.cached_firmwares[] | select(.path | contains("U7PG2"))'
# 3️⃣ Проверить вывод скрипта на наличие ошибок
# Должна быть строка вида:
# [URL] U7PG2 6.7.35 (devices: U7PG2 U7MSH U7LR) <- filename.bin
# 4️⃣ Проверить права доступа
ls -la /var/lib/unifi/firmware/firmware_meta.json
chown unifi:unifi /var/lib/unifi/firmware/firmware_meta.jsonПроблема: Прямой URL https://fw-download.ubnt.com/data/firmware.json недоступен (403 Forbidden).
Решение: Используйте API Ubiquiti:
# Получение каталога через API
./unifi-fw-cache.sh --fetch-catalog-api \
--update-catalog
# Для зеркала с переписыванием хостов
./unifi-fw-cache.sh --fetch-catalog-api \
--mirror-all \
--mirror-root /srv/mirror \
--rewrite-catalog-host fw-mirror.example.comНазначение файлов:
firmware.ubnt.json - оригинальные ссылки Ubiquiti
- Используется для СКАЧИВАНИЯ файлов на бастионе
- Ссылки вида:
https://fw-download.ubnt.com/data/unifi-firmware/... - Всегда доступен для загрузки
firmware.json - переписанные хосты
- Используется контроллером для получения прошивок
- Ссылки вида:
https://fw-mirror.example.com/data/unifi-firmware/... - Указывает на ваше локальное зеркало
Пример работы:
# На бастионе (создание зеркала):
./unifi-fw-cache.sh --fetch-catalog-api --mirror-all --rewrite-catalog-host fw.local
# Результат:
# 1. firmware.ubnt.json → скачивает файлы с Ubiquiti
# 2. data/ → сохраняет файлы локально
# 3. firmware.json → для контроллера (ссылки на fw.local)
# На контроллере:
# Использует firmware.json → скачивает с fw.local (вашего зеркала)Приветствуются любые улучшения!
- 🍴 Fork репозитория
- 🌿 Создайте feature branch (
git checkout -b feature/AmazingFeature) - 💾 Commit изменений (
git commit -m 'Add some AmazingFeature') - 📤 Push в branch (
git push origin feature/AmazingFeature) - 🎯 Откройте Pull Request
Распространяется под лицензией MIT. См. LICENSE для подробностей.
- 🏢 Ubiquiti Networks за UniFi
- 👥 Сообщество UniFi за тестирование и обратную связь
- 🛠️ Разработчикам bash, jq, wget за отличные инструменты
⭐ Если проект полезен, поставьте звезду на GitHub! ⭐
Made with ❤️ for Network Engineers