LINUX.ORG.RU

Как завести pbr в OpenWRT 24.10.4

 ,


0

1

Пытаюсь завести pbr в OpenWRT 24.10.4 для DNS Based Routing.

Ставлю пакет luci-app-pbr, одна из зависимостей которого - пакет pbr. При установке pbr получаю такую ошибку

Installing pbr (1.2.2-r6) to root...
Downloading https://downloads.openwrt.org/releases/24.10.4/packages/mipsel_24kc/packages/pbr_1.2.2-r6_all.ipk
Configuring pbr.
//usr/lib/opkg/info/pbr.postinst: /etc/init.d/pbr: line 1888: syntax error: unexpected "fi" (expecting "done")
//usr/lib/opkg/info/pbr.postinst: /etc/init.d/pbr: line 1888: syntax error: unexpected "fi" (expecting "done")
Installing rc.d symlink for pbr... /etc/rc.common: /etc/init.d/pbr: line 1888: syntax error: unexpected "fi" (expecting "done")
FAIL
/etc/rc.common: /etc/init.d/pbr: line 1888: syntax error: unexpected "fi" (expecting "done")
/etc/rc.common: /etc/init.d/pbr: line 1888: syntax error: unexpected "fi" (expecting "done")

Смотрю содержимое скрипта около строки 1888:

        if is_supported_interface "$dest_dns_interface"; then
                local d
                for d in $(uci -q get network."$dest_dns_interface".dns); do
                                if ! is_family_mismatch "$src_addr" "$d"; then
                                        if is_ipv4 "$d"; then
                                                dest_dns_ipv4="${dest_dns_ipv4:-${d}}"
                                        elif is_ipv6 "$d"; then
                                                dest_dns_ipv6="${dest_dns_ipv6:-${d}}"
                                        fi
                                fi
                        fi # <-- лишний fi, который воткнули из-за поехавшей разметки
                done
        fi

Удалил лишний fi, попытался запустить pbr вручную:

root@OpenWrt:~# uci set pbr.config.enabled='1'; uci commit pbr;
root@OpenWrt:~# /etc/init.d/pbr start
Using uplink interface (on_start): wan [✓]
Found uplink gateway (on_start): xxx.xxx.xxx.xxx [✓]
Processing environment (on_start) ERROR: Uplink/WAN interface is still down, increase value of 'procd_boot_trigger_delay' option!
Setting interface trigger for wan [✓]
pbr 1.2.2-r6 FAILED TO START!!!
Check the output of nft -c -f /var/run/pbr.nft
ERROR: The pbr 1.2.2-r6 service failed to discover WAN gateway!
ERROR: Errors encountered, please check https://docs.openwrt.melmac.ca/pbr/1.2.2/#error-messages-details!

При этом wan интерфейс в системе есть и поднят:

wan: <BROADCAST,MULTICAST,UP,LOWER_UP> mtu 1500 qdisc mq state UP group default qlen 1000

В конфиге pbr wan интерфейс имеет стандартное название: option uplink_interface 'wan'.

Начал дебажить глубже - оказалось, что в коде используется переменная wanGW, но она нигде не инициализируется, вместо нее есть wanGW4 и wanGW6. Правлю название переменной - начинает ругаться, что функций типа cleanup_main_chains нет и так далее. Кажется, что я что-то делаю не так, может каких-то зависимостей не хватает, может версия pbr не та (хотя в репе OpenWRT я не нашел другой версии).

У меня 2 вопроса:

  1. нормально ли, что в стабильной ветке OpenWRT отваливается pbr?
  2. есть ли какой-то мануал как завести pbr в OpenWRT?
1873: 	local dest_dns_interface dest_dns_ipv4 dest_dns_ipv6
1874: 	dest_dns_interface="$(str_first_value_interface "$dest_dns")"
1875: 	dest_dns_ipv4="$(str_first_value_ipv4 "$dest_dns")"
1876: 	dest_dns_ipv6="$(str_first_value_ipv6 "$dest_dns")"
1877: 	if is_supported_interface "$dest_dns_interface"; then
1878: 		local d
1879: 		for d in $(uci -q get network."$dest_dns_interface".dns); do
1880: 				if ! is_family_mismatch 1881: "$src_addr" "$d"; then
1882: 					if is_ipv4 "$d"; then
1883: 						dest_dns_ipv4="${dest_dns_ipv4:-${d}}"
1884: 					elif is_ipv6 "$d"; then
1885: 						dest_dns_ipv6="${dest_dns_ipv6:-${d}}"
1886: 					fi
1887: 				fi
1888: 			fi
1889: 		done
1890: 	fi

Судя по всем в /etc/init.d/pbr (init.d скрипте) действительно ошибка. Лишний fi в 1888.

Исправь в пакете или пробуй ставить другой, без этой ошибки.

Это /etc/init.d/pbr - это /bin/sh сценарий:

#!/bin/sh /etc/rc.common
# Copyright 2020-2024 MOSSDeF, Stan Grishin (stangri@melmac.ca)
# shellcheck disable=SC2018,SC2019,SC2034,SC3043,SC3057,SC3060

# sysctl net.ipv4.conf.default.rp_filter=1
# sysctl net.ipv4.conf.all.rp_filter=1

# shellcheck disable=SC2034
START=20
# shellcheck disable=SC2034
USE_PROCD=1

...

В postinst-pkg вызывается как раз этот init скрипт:

#!/bin/sh
# check if we are on real system
if [ -z "${IPKG_INSTROOT}" ]; then
	chmod -x /etc/init.d/pbr || true
	fw4 -q reload || true
	chmod +x /etc/init.d/pbr || true
	echo -n "Installing rc.d symlink for pbr... "
	/etc/init.d/pbr enable && echo "OK" || echo "FAIL"
fi

UPD: вижу уже попробовал. Тут хз, пробуй другую версию, если есть. В этой точно косяк и она в принципе нерабочая.

kostik87 ★★★★★
()
Последнее исправление: kostik87 (всего исправлений: 2)

Обкакаться с sh скриптом это норма для openwrt. В pbr eщё нерабочий pbr-prefetch, из-за святого sh. Все проблемы можно решить, переписав на нативный для openwrt lua, но дедовская привычка лепить нерабочие поделя на sh у мантейнеров в крови.

mamina_radost
()

может каких-то зависимостей не хватает

Я сам pbr отдельно не ставил, я сразу компилю под себя всё, что нужно. Для компиляции для pbr обязателен dnsmasq-full, по дефолту openwrt собирают просто с dnsmasq.

mamina_radost
()
Ответ на: комментарий от kostik87

Стартовые сценарии на lua можно написать?

Стартовый сценарий должен быть простым, его sh скрипт должен запускать готовые lua скрипты, а не тонны дополнительного мусорного шела.

В синтаксисе lua точно так же можно ошибиться.

Дело не в синтаксисе, когда идет работа с процессами, различными переменными, которые меняются, оболчка ash и бизибокс ломаются. Этих проблем нет на языках программирования. В теме pbr они сломали его в нескольких местах из-за sh.

mamina_radost
()
Ответ на: удаленный комментарий

Логика pbr есть в ядре Linux и внешних утилитах iproute2 ( ip rule )

Речь шла о доп скрипте, идущим, как часть pbr пакета, который обновляет nfset записи вначале запуска, что ускоряет доступ к ресурсам, которые завернули с помощью pbr.

Почему они не пишут скрипты на lua, который нативен в openwrt и напрямую завязан на их же ubus и другие модули, это загадка.

mamina_radost
()
Последнее исправление: mamina_radost (всего исправлений: 1)
Ответ на: комментарий от mamina_radost

По факту если система инициализации поддерживает pre сценарии - функции из общего сценарий должны быть вынесены в отдельные скрипты.

Иначе простой скрипт запускать, в котором в начале вызываются внешние скрипты для создания наборов, а далее сам pbr, если там что-то ещё есть. Кроме наборов. Не разбирал дальше.

Хоть на lua, хоть на sh. Посмотрел там функцию nfset(), которая собственно и создаёт наборы nftables, ну такое, держать всё в монолите.

kostik87 ★★★★★
()
Последнее исправление: kostik87 (всего исправлений: 1)
Ответ на: комментарий от kostik87

функции из общего сценарий должны быть вынесены в отдельные скрипты.

Мне так и пришлось переделывать, только не на sh. Хотя может я вру, и я вообще делал отделный сервис. В общем пришлось менять.

Но ты верно заметил, там говнокод сразу на нескольких уровнях, sh это только вишенка на торте.

mamina_radost
()
Последнее исправление: mamina_radost (всего исправлений: 1)
Ответ на: комментарий от mamina_radost

Я бы не сказал, что sh сам по себе проблема. Проблема в том, что всё свалено в одну кучу. И когда дописывают синтаксис может ползти.

Это как условно писать всё на куче вложенных циклов и if / else, вместо ООП и функций.

Хоть ООП и не применимо к скриптам.

kostik87 ★★★★★
()
Последнее исправление: kostik87 (всего исправлений: 1)