Система UCI
Див. також: UCI за замовчуванням, Мережеве скриптування
Абревіатура UCI розшифровується як Unified Configuration Interface — уніфікований інтерфейс конфігурації. Це система централізованого керування налаштуваннями сервісів у OpenWrt.
UCI прийшла на зміну конфігурації на основі NVRAM, яка використовувалася в серії прошивок White Russian. Це основний інтерфейс для налаштування ключових параметрів системи: мережі, бездротового зв’язку, журналювання, віддаленого доступу тощо.
Багато програм у репозиторії OpenWrt сумісні з UCI.
Програми роблять сумісними з UCI шляхом автоматичної генерації конфігураційного файлу (який читає програма) на основі значень з відповідного UCI-файлу при запуску ініціалізаційного скрипта з директорії /etc/init.d/.
Докладніше — Ініціалізаційні скрипти.
Отже, при запуску демонів через UCI-сумісний скрипт, оригінальний конфігураційний файл програми буде перезаписано.
Наприклад, у випадку Samba/CIFS файл /etc/samba/smb.conf буде перезаписано значеннями з файлу /etc/config/samba після запуску /etc/init.d/samba start.
Більше того, такі файли часто зберігаються в RAM, а не у флеш-пам’яті, оскільки вони постійно оновлюються і не потребують зберігання в постійній пам’яті.
Якщо потрібно зберегти ручне керування оригінальними конфігураціями, які не доступні через UCI, можна вимкнути UCI для окремих сервісів. Приклад — в cifs.server описано, як це зробити для Samba.
Для програм, які не підтримують UCI, існує окремий список таких конфігураційних файлів. Зверніть увагу: більшість сторонніх програм мають власну документацію, до якої варто звертатися.
Основні принципи
Централізовані конфігураційні файли OpenWrt розташовані в директорії /etc/config/.
Кожен файл відповідає певному розділу системи.
Редагувати конфігурацію можна:
- вручну через текстовий редактор (наприклад, vi),
- через командний інтерфейс
uci, - або через API (Shell, Lua, C), що використовується також у веб-інтерфейсах (наприклад, LuCI).
Після змін у файлах UCI, щоб ці зміни набули чинності, сервіси потрібно перезапустити (або, у деяких випадках, просто перезавантажити) за допомогою скриптів з /etc/init.d/.
Багато програм сумісні з UCI завдяки тому, що їхні скрипти init.d:
- беруть значення з
/etc/config/…, - генерують стандартний конфігураційний файл,
- запускають відповідну програму.
‼️ Якщо ви просто перезапустите виконуваний файл напряму, минаючи скрипт init.d, зміни в UCI не застосуються.
Приклад:
Щоб змінити IP-адресу пристрою з 192.168.1.1 на 192.168.2.1, змініть у файлі /etc/config/network:
option ipaddr 192.168.1.1
на
option ipaddr 192.168.2.1
Після цього застосуйте зміни:
/etc/init.d/network restart
Увага: після цього IP-адреса пристрою зміниться, тому для нового SSH-з’єднання використовуйте адресу 192.168.2.1.
Конфігураційні файли
Конфігураційні файли
| Файл | Опис |
|---|---|
| Основні настройки | |
| /etc/config/dhcp | Налаштування Dnsmasq та odhcpd: DNS, DHCP, DHCPv6 |
| /etc/config/dropbear | Опції SSH-сервера |
| /etc/config/firewall | NAT, фільтрація пакетів, переадресація портів |
| /etc/config/network | Налаштування комутаторів, інтерфейсів і маршрутів: Загальне, IPv4, IPv6, Маршрути, Правила, WAN, Аліаси, VLAN, IPv6/IPv4, Тунелі |
| /etc/config/system | Системні параметри, NTP, RNG, Watchcat |
| /etc/config/wireless | Налаштування Wi-Fi |
| IPv6 | |
| /etc/config/ahcpd | Налаштування AHCP (Ad-Hoc Configuration Protocol) |
| /etc/config/dhcp6c | DHCPv6-клієнт WIDE |
| /etc/config/dhcp6s | DHCPv6-сервер WIDE |
| /etc/config/gw6c | Налаштування GW6c |
| Інші файли | |
| /etc/config/acme | Випуск TLS-сертифікатів через ACME |
| /etc/config/babeld | babeld – маршрутизатор протоколу Babel |
| /etc/config/bbstored | Конфігурація BoxBackup |
| /etc/config/cloudflared | Тунель Cloudflare |
| /etc/config/ddns | Динамічний DNS (ddns-scripts) |
| /etc/config/dnscrypt-proxy | DNSCrypt-проксі |
| /etc/config/dockerd | Демон Docker |
| /etc/config/emailrelay | E-MailRelay: SMTP-сервер і проксі з POP. Пакет: emailrelay |
| /etc/config/etherwake | Wake-on-Lan: etherwake |
| /etc/config/freifunk_p2pblock | Блокує p2p через iptables (layer7, ipp2p, recent) |
| /etc/config/fstab | Точки монтування та swap |
| /etc/config/hd-idle | Демон простою жорстких дисків |
| /etc/config/httpd | Параметри вебсервера Busybox (застарілий) |
| /etc/config/ipset-dns | Налаштування ipset-dns |
| /etc/config/kadnode | p2p DNS KadNode |
| /etc/config/luci | Базова конфігурація LuCI |
| /etc/config/luci_statistics | Збір статистики |
| /etc/config/mini_snmpd | Налаштування mini_snmpd |
| /etc/config/minidlna | Параметри MiniDLNA |
| /etc/config/mjpg-streamer | Стрімінг для сумісних вебкамер Linux-UVC |
| /etc/config/mountd | Демон автоматичного монтування |
| /etc/config/mroute | Маршрути для декількох WAN |
| /etc/config/multiwan | Просте мульти-WAN рішення |
| /etc/config/mwan3 | Паралельний Multi-WAN з балансуванням і відмовостійкістю |
| /etc/config/nodogsplash | Налаштування nodogsplash |
| /etc/config/ntpclient | Отримання точного часу |
| /etc/config/nut_server | Керування джерелом безперебійного живлення (UPS) |
| /etc/config/nut_monitor | Моніторинг UPS віддалено або локально |
| /etc/config/nut_cgi | Вебінтерфейс NUT (лише перегляд) |
| /etc/config/p910nd | Безспулінговий принтер-демон p910nd.server |
| /etc/config/pure-ftpd | Налаштування Pure-FTPd |
| /etc/config/qos | Quality of Service (QoS) для вихідного трафіку |
| /etc/config/racoon | Демон IPsec racoon |
| /etc/config/samba | Файловий і друкарський сервер Microsoft (Samba) |
| /etc/config/snmpd | Налаштування SNMPd |
| /etc/config/sqm | Налаштування Smart Queue Management |
| /etc/config/sshtunnel | Параметри пакету sshtunnel |
| /etc/config/stund | STUN-сервер |
| /etc/config/tinc | Конфігурація VPN tinc |
| /etc/config/tor | Налаштування Tor |
| /etc/config/tor-hs | Приховані сервіси Tor |
| /etc/config/transmission | BitTorrent клієнт |
| /etc/config/uhttpd | Вебсервер uHTTPd |
| /etc/config/upnpd | Налаштування miniUPnP |
| /etc/config/users | База даних користувачів |
| /etc/config/ushare | Налаштування uShare (UPnP) |
| /etc/config/vblade | Користувацький AOE-таргет vblade |
| /etc/config/vnstat | Налаштування vnstat |
| /etc/config/wifitoggle | Вмикання/вимикання Wi-Fi кнопкою |
| /etc/config/wol | Wake-on-LAN: wol |
| /etc/config/znc | Конфігурація IRC-проксі ZNC |
Синтаксис конфігураційних файлів
Конфігураційні файли UCI зазвичай складаються з одного або кількох блоків config — так званих секцій, які містять одну або більше інструкцій option, що визначають конкретні значення.
Символ # використовується для коментарів.
Якщо рядок містить # поза межами рядка в лапках, все після нього буде проігноровано.
Нижче приклад простого конфігураційного файлу (див. також uci_dataobject_model):
package 'example' config 'example' 'test' option 'string' 'some value' option 'boolean' '1' list 'collection' 'first item' list 'collection' 'second item'
Пояснення:
- Інструкція
config 'example' 'test' відкриває секцію типуexampleз ідентифікаторомtest. Секція може бути також анонімною (тобто без назви), але тип обов’язковий — він визначає, як програма має обробляти цю секцію. - Рядки
option 'string' 'some value' іoption 'boolean' '1' задають прості значення в межах секції. В синтаксисі немає різниці між рядковими й булевими значеннями. Згідно конвенції, булеві значення можуть бути такими:- false:
0,no,off,false,disabled - true:
1,yes,on,true,enabled
- Інструкції
listзадають опцію з декількома значеннями. Усі рядки з однаковим ім'ям (наприклад,collection) будуть зібрані в один список у заданому порядку. - Відступи в інструкціях
optionіlist— лише для зручності читання, вони не є обов’язковими. - Якщо опція відсутня, але не обов’язкова — буде використано значення за замовчуванням. Якщо опція обов’язкова, але відсутня — це може викликати помилки в роботі програми.
- Якщо секцію потрібно вимкнути, але вона не має параметра
enabled— змініть її тип (наприклад, зexampleнаdisabled_identifier). UCI-скрипти не розпізнають такий тип, і секція буде проігнорована.
Ідентифікатори й значення зазвичай не потребують лапок. Але якщо значення містить пробіли або табуляцію, лапки обов’язкові. Дозволено використовувати як одинарні (''), так і подвійні ("") лапки.
Усі наведені нижче приклади — валідний UCI-синтаксис:
option example value option example "value" option 'example' value option 'example' "value" option "example" 'value'
Неправильний синтаксис:
# значення містить пробіли, але без лапок option example v_a l u-e # незбалансовані лапки option 'example" "value'
Увага:
Ідентифікатори (назви опцій, секцій, файлів) можуть містити лише символи: a-z, 0-9 та _.
Символи - (дефіси) не допускаються.
Значення опцій можуть містити будь-які символи (якщо вони належно обгорнуті в лапки).
Плагіни для редакторів
Підсвічування синтаксису в Vim: vim-uci
Добре працює разом із sshfs (потрібен openssh-sftp-server).
Утиліта командного рядка
Для зміни налаштувань зазвичай редагують UCI-конфігураційні файли напряму. Однак для скриптів вся конфігурація UCI може бути також прочитана й змінена за допомогою утиліти командного рядка uci.
Для розробників, яким потрібно автоматично аналізувати UCI-конфігурацію, використання інструментів типу awk або grep — зайве, неефективне й помилкове. Утиліта uci надає повну функціональність для читання, зміни та обробки UCI.
Нижче наведено синтаксис і приклади використання цієї потужної утиліти.
Під час запису файлів через утиліту uci, файли повністю перезаписуються, а всі незрозумілі (невідомі) команди пропускаються. Це означає, що додаткові рядки (наприклад, коментарі) буде видалено. Якщо ви раніше редагували конфігураційні файли вручну та хочете зберегти власні коментарі або порожні рядки — не використовуйте утиліту uci для запису, а редагуйте файли напряму.
Зверніть увагу, що деякі конфігураційні файли, наприклад, конфіг уHTTPd, містять багато коментарів одразу після встановлення пакета. Також пам’ятайте, що деякі програми, наприклад LuCI, також використовують утиліту uci і можуть перезаписати файли.
Коли в конфігурації є кілька секцій одного типу, UCI підтримує масивоподібну адресацію.
Наприклад, якщо у файлі /etc/config/system задано 8 NTP-серверів, ви можете звертатися до них так:
- system.@timeserver[0] — перший - system.@timeserver[7] — останній
Також можна використовувати негативні індекси:
- -1 — останній
- -2 — передостанній
Це дуже зручно при додаванні нових правил у кінець списку.
Дивіться приклади нижче.
Множинні секції:
UCI дозволяє використовувати “масивний” синтаксис, якщо у файлі кілька секцій одного типу.
Наприклад, якщо у файлі /etc/config/system вказано 8 серверів часу NTP, ви можете звернутися до них так:
- system.@timeserver[0] — перший
- system.@timeserver[7] — останній
- system.@timeserver[-1] — також останній
- system.@timeserver[-2] — передостанній
Цей синтаксис дуже зручний, особливо для додавання нових записів у кінець списку.
Використання
# uci Використання: uci [<опції>] <команда> [<аргументи>] Команди: batch export [<config>] import [<config>] changes [<config>] commit [<config>] add <config> <section-type> add_list <config>.<section>.<option>=<string> del_list <config>.<section>.<option>=<string> show [<config>[.<section>[.<option>]]] get <config>.<section>[.<option>] set <config>.<section>[.<option>]=<value> delete <config>.<section>[.<option>] rename <config>.<section>[.<option>]=<name> revert <config>[.<section>[.<option>]] reorder <config>.<section>=<position> Опції: -c <path> вказати шлях до конфігураційних файлів (типово: /etc/config) -d <str> задати роздільник для спискових значень у команді uci show -f <file> використовувати вхідні дані з <file>, а не з stdin -m при імпорті — об'єднувати дані з наявним пакетом -n називати безіменні секції при експорті (типово) -N не називати безіменні секції -p <path> додати шлях пошуку для файлів змін конфігурацій -P <path> додати шлях і встановити його як типовий -q тихий режим (не виводити помилки) -s увімкнути строгий режим (зупинка при помилках синтаксису, типовий) -S вимкнути строгий режим -X не використовувати розширений синтаксис у 'show'
| Команда | Ціль | Опис |
|---|---|---|
commit | [<config>] | Записує зміни вказаного конфігураційного файлу (або всіх, якщо не вказано) у файлову систему. Команди uci set, add, rename, delete спочатку записуються у тимчасове сховище й застосовуються командою commit. |
batch | - | Виконує багато-рядковий скрипт UCI, зазвичай у форматі here document. |
export | [<config>] | Експортує конфігурацію у форматі, придатному для машинного аналізу. |
import | [<config>] | Імпортує конфігураційні файли у синтаксисі UCI. |
changes | [<config>] | Показує незастосовані зміни до файлів конфігурацій. |
add | <config> <section-type> | Додає анонімну секцію вказаного типу до конфігурації. |
add_list | <config>.<section>.<option>=<string> | Додає значення до спискової опції. |
del_list | <config>.<section>.<option>=<string> | Видаляє значення зі спискової опції. |
show | [<config>[.<section>[.<option>]]] | Показує конфігурацію у компактному вигляді. |
get | <config>.<section>[.<option>] | Отримує значення опції або тип секції. |
set | <config>.<section>[.<option>]=<value> | Задає значення опції або додає секцію. |
delete | <config>.<section>[.<option>] | Видаляє вказану опцію або секцію. |
rename | <config>.<section>[.<option>]=<name> | Перейменовує опцію або секцію. |
revert | <config>[.<section>[.<option>]] | Повертає конфігурацію до попереднього стану. |
reorder | <config>.<section>=<position> | Переміщує секцію на нову позицію. |
⚠️ Примітка:
Ви не можете повністю видалити конфігураційний файл командою uci delete, наприклад, uci delete umdns — не спрацює.
Щоб повністю очистити конфігурацію, використайте такий скрипт:
while uci -q delete umdns.@umdns[0]; do :; done
Модель даних/об'єктів UCI
Елементи
UCI-модель складається з таких частин:
- config — основна група конфігурації (наприклад:
network,system,firewall). Відповідає одному файлу в/etc/config. - sections — кожна конфігурація розбита на секції (розділи), які можуть бути іменованими або безіменними.
- types — кожна секція має тип, який визначає її роль. Наприклад, у файлі
networkчасто є секції типуinterfaceз іменамиlan,wan,loopback,wan6. - options — параметри в секції, які визначають конкретні значення.
- values — значення опцій.
Іменування секцій
Секції можуть бути:
- іменованими — з фіксованим ім’ям (наприклад,
wan) - безіменними — з автоматично згенерованим ID (наприклад,
cfg073777)
Безіменні секції:
- Відображаються як @тип[індекс] (наприклад,
@switch[0]) - Ідентифікатори типу
cfgxxxxx(наприклад,cfg073777) призначаються автоматично.
🔍 Приклад (анонімна секція):
# uci show network network.@switch[0]=switch network.@switch[0].name='switch0' network.@switch[0].reset='1' network.@switch[0].enable_vlan='1'
🔍 Той самий запис із CFGID:
# uci show network.@switch[0] network.cfg073777=switch network.cfg073777.name='switch0' network.cfg073777.reset='1' network.cfg073777.enable_vlan='1'
Різні подання однієї секції
Секції UCI можуть бути подані в різних виглядах:
- Зручно для людини — так, як у файлах або команді:
uci export <config>
- Програмно — командою:
uci show <config>, з доступом до:
- іменованої секції
- безіменної секції за
@тип[індекс] - безіменної секції за
cfgID
| Тип подання | ||
|---|---|---|
Зрозуміле для людини, іменована секція (uci export network) | Зрозуміле для людини, безіменна секція (uci export network) | |
| | |
Програмне, іменована секція (uci show network.wan) | Програмне, безіменна секція (uci show network) | Програмне, через CFGID (uci show network.@switch[0]) |
| | |
Приклади
Зміна значення опції
Якщо потрібно змінити порт прослуховування вебсервера uHTTPd з 80 на 8080, змініть конфігурацію в /etc/config/uhttpd так:
uci set uhttpd.main.listen_http='8080' uci commit uhttpd /etc/init.d/uhttpd restart
Готово — конфігураційний файл оновлено, і uHTTPd тепер слухає порт 8080.
Експорт усієї конфігурації
uci export назва_конфігурації
Приклади доступних конфігурацій: defaults, dnsmasq, dropbear, firewall, fstab, net, qos, samba, system, wireless.
Перегляд конфігурації
uci show назва_конфігурації
Приклад:
# uci show system system.@system[0]=system system.@system[0].hostname='OpenWrt' system.@system[0].timezone='UTC' system.ntp=timeserver system.ntp.server='0.openwrt.pool.ntp.org' '1.openwrt.pool.ntp.org' '2.openwrt.pool.ntp.org' '3.openwrt.pool.ntp.org' system.ntp.enabled='1' system.ntp.enable_server='0'
Показ лише значення конкретної опції
uci get httpd.@httpd[0].port
Додавання елемента до списку
uci add_list system.ntp.server='0.de.pool.ntp.org'
Повна заміна списку
uci delete system.ntp.server uci add_list system.ntp.server='0.de.pool.ntp.org' uci add_list system.ntp.server='1.de.pool.ntp.org' uci add_list system.ntp.server='2.de.pool.ntp.org'
Додавання нової безіменної секції до конфігурації
uci add назва_конфігурації тип_секції
Це створить нову безіменну секцію заданого типу всередині вказаного файлу конфігурації. Після цього до секції можна додавати опції як зазвичай. Команда поверне автоматично згенеровану назву секції (наприклад, cfg03ab1d), яку можна використати для подальших змін.
Приклад — додавання секції rule до firewall з посиланням через індекс:
uci add firewall rule uci set firewall.@rule[-1].src='wan'
Те саме, але з використанням збереженого ідентифікатора:
sid=$(uci add firewall rule) uci set firewall.$sid.src='wan'
Додавання іменованої секції до конфігурації
Щоб додати іменовану секцію певного типу, використовуйте скорочену форму команди uci set — без ключового слова option:
touch /etc/config/example uci set example.this_name=blah uci set example.this_name.xxx=yyy uci set example.other_name=blah uci set example.other_name.yyy=zzz uci commit example
Перевірка:
uci show example
example.this_name=blah example.this_name.xxx=yyy example.other_name=blah example.other_name.yyy=zzz
Файл конфігурації після цього:
cat /etc/config/example
config blah 'this_name'
option xxx 'yyy'
config blah 'other_name'
option yyy 'zzz'
Показ незбережених змін
Щоб побачити всі зміни, які ще не були збережені:
uci changes
Збереження змін лише для однієї конфігурації
uci commit назва_конфігурації reload_config
Збереження всіх змін одразу
uci commit reload_config
Генерація повної секції UCI з копіпастою
Цей приклад зберігає ID новоствореної секції, повернутий командою uci add, і використовує його для подальшого додавання опцій до цієї секції.
Таким чином, не потрібно вручну вписувати ідентифікатор — зручно і для інтерактивної роботи, і для скриптів.
🔧 Універсальний шаблон:
section_id=$(uci add <config> <section-type>) uci batch << EOI set <config>.$section_id.<option1>='value' set <config>.$section_id.<option2>='value' set <config>.$section_id.<option3>='value' ... EOI uci commit
📌 Приклад для фаєрволу:
rule_id=$(uci add firewall rule) uci batch << EOI set firewall.$rule_id.enabled='1' set firewall.$rule_id.target='ACCEPT' set firewall.$rule_id.src='wan' set firewall.$rule_id.proto='tcp udp' set firewall.$rule_id.dest_port='111' set firewall.$rule_id.name='NFS_share' EOI uci commit
Шляхи в UCI
Уявімо такий приклад конфігураційного файлу:
config bar 'first' option name 'Mr. First' config bar option name 'Mr. Second' config bar 'third' option name 'Mr. Third'
Тоді всі ці шляхи звертаються до одних і тих самих записів:
# Mr. First uci get foo.@bar[0].name uci get foo.@bar[-0].name uci get foo.@bar[-3].name uci get foo.first.name # Mr. Second uci get foo.@bar[1].name uci get foo.@bar[-2].name # uci get foo.second.name — не працює, оскільки 'second' не має імені # Mr. Third uci get foo.@bar[2].name uci get foo.@bar[-1].name uci get foo.third.name
🔍 Команда `uci show foo` покаже:
foo.first=bar foo.first.name='Mr. First' foo.@bar[0]=bar foo.@bar[0].name='Mr. Second' foo.third=bar foo.third.name='Mr. Third'
А команда `uci show foo.@bar[0]` покаже лише:
foo.first=bar
foo.first.name='Mr. First'
💡 Це може збивати з пантелику, але пояснюється особливостями внутрішнього мапінгу імен у UCI.
Додавання правила фаєрволу
Це гарний приклад як додати правило фаєрволу для переспрямування TCP-порту SSH, а також приклад використання негативного індексу (-1) у синтаксисі `uci`.
uci add firewall rule uci set firewall.@rule[-1].src='wan' uci set firewall.@rule[-1].target='ACCEPT' uci set firewall.@rule[-1].proto='tcp' uci set firewall.@rule[-1].dest_port='22' uci commit firewall /etc/init.d/firewall restart
Отримати SSID
uci get wireless.@wifi-iface[0].ssid
Порт UCI для інших дистрибутивів Linux
Пошкоджені конфігурації
Див. також: UCI extras
Якщо ви вручну редагували файли в /etc/config, можливо, деякі з них містять помилки синтаксису, які можуть спричинити їх пошкодження.
Приклад помилки парсингу:
# uci show fstab uci: Parse error (invalid command) at line 20, byte 0