Zeleza Posted June 8, 2022 Share Posted June 8, 2022 (edited) Всем доброго дня, Прошу людей умудренных опытом подсказать как связать соответствие данных по имеющимся интерфейсам в системе. Для получения данных о текущих VPN (и не только) интерфейсах используем API от keenetic: curl -s "localhost:79/rci/show/interface" Где можем получить данные по ID, типу интерфейса и его названию и пр. Скрытый текст "OpenVPN0": { "id": "OpenVPN0", "index": 0, "type": "OpenVPN", "description": "OVPN", "interface-name": "OpenVPN0", "link": "down", "connected": "no", "state": "down", "role": [ "misc" ], -- "Wireguard0": { "id": "Wireguard0", "index": 0, "type": "Wireguard", "description": "WireguardZ", "interface-name": "Wireguard0", "link": "down", "connected": "no", "state": "down", В entware получить информацию о текущих интерфейсах можно ip a ifconfig Скрытый текст 1: lo: <LOOPBACK,UP,LOWER_UP> mtu 65536 qdisc noqueue qlen 1 link/loopback 00:00:00:00:00:00 brd 00:00:00:00:00:00 inet 127.0.0.1/8 scope host lo valid_lft forever preferred_lft forever inet6 ::1/128 scope host valid_lft forever preferred_lft forever 2: tunl0@NONE: <NOARP> mtu 1480 qdisc noop qlen 1 link/ipip 0.0.0.0 brd 0.0.0.0 3: sit0@NONE: <NOARP> mtu 1480 qdisc noop qlen 1 link/sit 0.0.0.0 brd 0.0.0.0 4: dummy0: <BROADCAST,NOARP> mtu 1500 qdisc noop qlen 1000 link/ether ba:9b:92:aw:sb:cd brd ff:ff:ff:ff:ff:ff 5: ip6tnl0@NONE: <NOARP> mtu 1452 qdisc noop qlen 1 link/tunnel6 00:00:00:00:00:00:00:00:00:00:00:00:00:00:00:00 brd 00:00:00:00:00:00:00:00:00:00:00:00:00:00:00:00 6: ezcfg0: <NO-CARRIER,BROADCAST,MULTICAST,UP> mtu 1500 qdisc fq_codel qlen 1000 link/ether ea:ef:06:35:55:15 brd ff:ff:ff:ff:ff:ff inet 38.47.115.120/32 brd 38.255.255.255 scope global ezcfg0 valid_lft forever preferred_lft forever Так вот вопрос возник следующий - как связать эти данные? Как сопоставить названия интерфейсов? Например, как определить автоматически, что название tunl0 соответствует OpenVPN0 и т.п.? Edited June 8, 2022 by Zeleza Quote Link to comment Share on other sites More sharing options...
Serafim Posted June 8, 2022 Share Posted June 8, 2022 ndmc -c show interface Quote Link to comment Share on other sites More sharing options...
Zeleza Posted June 8, 2022 Author Share Posted June 8, 2022 34 минуты назад, Serafim сказал: ndmc -c show interface Доброго дня, Благодарю Вас, только не совсем Вас понял. Если речь идет о том, чтобы сопоставить mac адреса в обоих вариантах, то это возможно только для openvpn, а как быть с wireguard например? Quote Link to comment Share on other sites More sharing options...
r13 Posted June 8, 2022 Share Posted June 8, 2022 3 часа назад, Zeleza сказал: Доброго дня, Благодарю Вас, только не совсем Вас понял. Если речь идет о том, чтобы сопоставить mac адреса в обоих вариантах, то это возможно только для openvpn, а как быть с wireguard например? wireguard L3 интерфейс, у него нет mac Quote Link to comment Share on other sites More sharing options...
Zeleza Posted June 8, 2022 Author Share Posted June 8, 2022 16 минут назад, r13 сказал: wireguard L3 интерфейс, у него нет mac Простите, не понял, как Ваш комментарии может помочь в решении вопроса по теме? 10 часов назад, Zeleza сказал: Как сопоставить названия интерфейсов? Например, как определить автоматически, что название tunl0 соответствует OpenVPN0 и т.п.? Quote Link to comment Share on other sites More sharing options...
Александр Рыжов Posted June 8, 2022 Share Posted June 8, 2022 10 часов назад, Zeleza сказал: как связать соответствие данных по имеющимся интерфейсам в системе. Может будет достаточно инфы из хук-скриптов. Вместе имена интерфейсов вместе только там. Quote Link to comment Share on other sites More sharing options...
Zeleza Posted June 9, 2022 Author Share Posted June 9, 2022 (edited) 10 часов назад, Александр Рыжов сказал: Может будет достаточно инфы из хук-скриптов. Вместе имена интерфейсов вместе только там. Доброго утра, Благодарю Вас, почти то, что нужно) Скрытый текст Wireguard0|nwg0 Wireguard1|nwg1 Wireguard2|nwg2 IKE1|nikecli1 IKE0|nikecli0 OpenVPN0|ovpn_br0 Остается придумать, как в процессе установки пакета запустить сами хуки для включения интерфейсов или смены их IP, или только вручную? P.S. Пробую curl -s "localhost:79/rci/interface/connect/via/OpenVPN0" - не поднимается и хук не срабатывает. Пробую curl -s "localhost:79/rci/interface/openvpn/connect/via/OpenVPN0" - тоже самое. Как запустить? Edited June 9, 2022 by Zeleza Quote Link to comment Share on other sites More sharing options...
Zeleza Posted June 9, 2022 Author Share Posted June 9, 2022 (edited) Нашел "костыль", нужно просто перегрузить роутер, и все соединения срабатывают и получаем список Скрытый текст Wireguard0|nwg0 OpenVPN0|ovpn_br0 GigabitEthernet0|eth2 GigabitEthernet1/0|eth3 WifiMaster0|ra0 WifiMaster1|rai0 CdcEthernet0|cdc_br0 UsbLte0|lte_br0 Bridge0|br0 GigabitEthernet0/Vlan2|eth2.2 Bridge1|br1 GigabitEthernet0/0|eth2 GigabitEthernet0/1|eth2 GigabitEthernet0/Vlan3|eth2.3 Bridge2|br2 IKE0|nikecli0 IKE1|nikecli1 Wireguard1|nwg1 Wireguard2|nwg2 GigabitEthernet0/Vlan1|eth2.1 WifiMaster0/AccessPoint2|ra2 WifiMaster0/AccessPoint0|ra0 WifiMaster1/AccessPoint0|rai0 С другой стороны так же нашел вариант включения хука: curl -s -d '{"up":"true"}' "localhost:79/rci/interface/OpenVPN0" Сам скрипт для получения соответствия интерфейсов через обработку "хука":~ # cat /opt/etc/ndm/ifstatechanged.d/100-save-inface #!/bin/sh # если файла с именами нет - создаем if ! [ -f /opt/etc/infaces_names ]; then touch /opt/etc/infaces_names; fi # если интефейса еще нет в списке, то добавляем его if [ -z "$(grep "${id}" /opt/etc/infaces_names)" ]; then echo "${id}|${system_name}" >> /opt/etc/infaces_names # пишем в лог, по необходимости logger "${id} -> ${system_name}" fi exit 0 помним про права: chmod +x /opt/etc/ndm/ifstatechanged.d/100-save-inface S.P. Памяти ради, публикую скрипт для получения соответствия интерфейсов без перезагрузки роутера. Он работает в купе со скриптом по обработке "хука" выше: #!/bin/sh # очищаем файл с именами интерфейсов rm /opt/etc/infaces_names # обозначаем список типов обрабатываемых интерфейсов types_inface="openvpn|wireguard|ike|sstp|pppoe|l2tp|cdcethernet" # получаем список ID интерфейсов в наличии на роутере через пробел inface_list=$(curl -s localhost:79/rci/show/interface | grep '"id"' | grep -Ei "${types_inface}" | cut -d':' -f2 | tr -d ' ",' | tr '\n' ' ') # проходимся по каждому интерфейсу for inface in ${inface_list}; do # получаем текущее состояние инф-са для возвращения его к исходному состоянию state=$(curl -s localhost:79/rci/show/interface | grep -i "${inface}" -A7| grep -Ei 'state' | cut -d: -f2 | tr -d ' ",') # в зависимости от состояния - включем и выключаем или выключаем и включаем интерфейс # для того, чтобы сработал наш хук в файле /opt/etc/ndm/ifstatechanged.d/100-save-inface if [ "${state}" = 'up' ]; then curl -s -d '{"down":"true"}' "localhost:79/rci/interface/${inface}" &>/dev/null else curl -s -d '{"up":"true"}' "localhost:79/rci/interface/${inface}" &>/dev/null fi curl -s -d "{\"${state}\":\"true\"}" "localhost:79/rci/interface/${inface}" &>/dev/null # получаем описание интерфейса description=$(curl -s localhost:79/rci/show/interface | grep -i "${inface}" -A3 | grep -Ei 'description' | cut -d: -f2 | tr -d ' ",' | sed 's|\/|\//|g') # вставляем описание в файл /opt/etc/infaces_names sed -i 's/\('"${inface}"'.*\)/\1|'"${description}"'/' /opt/etc/infaces_names done cat /opt/etc/infaces_names На выходе получаем файл /opt/etc/infaces_names в формате: <ID интерфейса в CLI>|<ID интерфейса в entware>|<Описание интерфейса в CLI> Скрытый текст CdcEthernet0|cdc_br0|My Yota IKE0|nikecli0|L2TP/IPsec IKE1|nikecli1|ikev2_main OpenVPN0|ovpn_br0|My OVPN Wireguard0|nwg0|My Wireguard-1 Wireguard1|nwg1|My Wireguard-2 Wireguard2|nwg2|My Gate Edited June 9, 2022 by Zeleza Quote Link to comment Share on other sites More sharing options...
Zeleza Posted June 11, 2022 Author Share Posted June 11, 2022 (edited) Чуть модернизировал скрипт - преобразовал в функцию (все "в одном флаконе"). Однако при работе с включёнными уже vpn интерфейсами (у которых долгое время соединения, например openvpn), приходится ставить на паузу минимум в 2 секунды. Может кто из опыта подскажет, как побороть данный недуг? HOOK_INFACE_FILE=/opt/etc/ndm/ifstatechanged.d/100-get-entware-inface INFACE_NAMES_FILE=/opt/etc/inface_equals URL_REQUEST='localhost:79/rci/interface' # ------------------------------------------------------------------------------------------ # # Получаем список соотвествия имен интерфейсов CLI keenetic = Entware # Список забираем из /opt/etc/inface_equals в формате: # <ID интерфейса в CLI>|<ID интерфейса в entware>|<Описание интерфейса в CLI> # # ------------------------------------------------------------------------------------------ get_interface_name_list(){ # если нет файла по отлавливанию хука if ! [ -f "${HOOK_INFACE_FILE}" ]; then # создаем файл cat <<EOF > "${HOOK_INFACE_FILE}" #!/bin/sh ! [ -f "${INFACE_NAMES_FILE}" ] && touch "${INFACE_NAMES_FILE}" [ -z "\$(grep "\${id}" "${INFACE_NAMES_FILE}")" ] && echo "\${id}|\${system_name}" >> "${INFACE_NAMES_FILE}" exit 0 EOF chmod +x "${HOOK_INFACE_FILE}" fi # обозначаем список типов обрабатываемых интерфейсов types_inface="openvpn|wireguard|ike|sstp|pppoe|l2tp|cdcethernet" # получаем список ID интерфейсов в наличии на роутере через пробел inface_list=$(curl -s "${URL_REQUEST}" \ | grep '"id"' \ | grep -Ei "${types_inface}" \ | cut -d':' -f2 \ | tr -d ' ",' \ | tr '\n' ' '\ ) # проходимся по каждому интерфейсу for inface_entware in ${inface_list}; do # получаем текущее состояние инф-са для возвращения его к исходному состоянию state=$(curl -s "${URL_REQUEST}" \ | grep -i "${inface_entware}" -A7 \ | grep -Ei 'state' \ | cut -d: -f2 | tr -d ' ",'\ ) # в зависимости от состояния - включаем и выключаем или выключаем и включаем интерфейс # для того, чтобы сработал наш хук в файле /opt/etc/ndm/ifstatechanged.d/100-save-inface_entware if [ "${state}" = 'up' ]; then curl -s -d '{"down":"true"}' "${URL_REQUEST}/${inface_entware}" &>/dev/null else curl -s -d '{"up":"true"}' "${URL_REQUEST}/${inface_entware}" &>/dev/null fi # Пауза мин. в 2 сек. для получения результата в соединениях, которые не сразу подключаются (как пример OpenVPN) sleep 2 curl -s -d "{\"${state}\":\"true\"}" "${URL_REQUEST}/${inface_entware}" &>/dev/null # получаем описание интерфейса description=$(curl -s "${URL_REQUEST}" \ | grep '"id"' -A7 \ | grep -i "${inface_entware}" -A4 \ | grep -Ei 'description' \ | cut -d: -f2 | tr -d ' ",' \ | sed 's|\/|\\/|g'\ ) # вставляем описание в файл /opt/etc/infaces_names sed -i 's/\('"${inface_entware}"'.*\)/\1|'"${description}"'/' "${INFACE_NAMES_FILE}" done rm -f "${HOOK_INFACE_FILE}" cat "${INFACE_NAMES_FILE}" } Edited June 12, 2022 by Zeleza Quote Link to comment Share on other sites More sharing options...
Serafim Posted June 21, 2023 Share Posted June 21, 2023 Собираю все интернет-интерфейсы, сопоставляю названия keenetic и entware: 1. /opt/etc/ndm/ifstatechanged.d/100-netimd #!/bin/sh # # File place: /opt/etc/ndm/ifstatechanged.d # source /opt/etc/netimd/netimd.func OnIfStateChanged exit 0 2. /opt/etc/netimd/netimd.func #!/bin/sh export iface_list_entware="" NETIMD=netimd NETIMD_MOD=$NETIMD"v" NETIMD_APP=$NETIMD"con" NETIMD_APW=$NETIMD_APP" -web" CFG_FILE="-cfg -file" NETIMD_CFG_PATH="/opt/etc/"$NETIMD"/" IFACE_NAMES_FILE=$NETIMD_CFG_PATH"pub.dev" EXCL_IFACE_NAMES_FILE=$NETIMD_CFG_PATH"excl.dev" LINK_DEV=$NETIMD_CFG_PATH"link.dev" NDMC_SHOW_IFACE="ndmc -c show interface" SECURITY_LEVEL="security-level" SECURITY_LEVEL_PUBLIC=$SECURITY_LEVEL": public" # excluded_ifaces="ra tun gre ppp etho im" #stringContain() { [ -z "${2##*$1*}" ]; } iface_is_not_in_excluded_file() { if_name=$1 if grep -q "$if_name" "$EXCL_IFACE_NAMES_FILE"; then retval=0 else retval=1 fi return "$retval" } iface_needed() { if_name=$1 if [ -z "$if_name" -a "$if_name" != " " ] || \ [[ $if_name == "lo" ]]; then retval=0 else retval=1 arr=$(echo $excluded_ifaces | tr " " ) for item in $arr do #echo "$item $if_name" if [[ $if_name == $item* ]]; then retval=0 break; fi done if [ "$retval" -eq 1 ]; then iface_is_not_in_excluded_file $if_name retval=$? fi fi return "$retval" } iface_keenetic_security_level_public() { retval=0 if_name=$1 if ! [ -z "$if_name" -a "$if_name" != " " ]; then ret=$($NDMC_SHOW_IFACE "$if_name" | grep "$SECURITY_LEVEL_PUBLIC") if ! [ -z "$ret" ]; then retval=1 fi fi return "$retval" } iface_keenetic_security_level() { if_name=$1 echo $($NDMC_SHOW_IFACE "$if_name" | grep "$SECURITY_LEVEL" | awk '{print $2}') } get_entware_iface_list() { #iface_list_long=$(ifconfig | grep "Ethernet" | awk '{print $1}') iface_list_long=$(ip a | grep "mtu" | awk '{print $2}') #echo $iface_list_long for iface_name in $iface_list_long ; do iface_name=${iface_name::-1} iface_needed $iface_name retval=$? if [ "$retval" == 0 ] then #echo "iface $iface_name not needed" continue; fi bInclude=1 for iface_name2 in $iface_list_long ; do iface_name2=${iface_name2::-1} if [[ "$iface_name2" == "$iface_name" ]]; then continue; elif [[ $iface_name2 != *"@"* ]]; then continue; elif [[ $iface_name2 == *"@"* ]]; then #echo "==> $iface_name2" if [[ "$iface_name2" == *"$iface_name" ]]; then #echo "found $iface_name in $iface_name2" bInclude=0 break; fi fi done if [[ $bInclude -eq 0 ]]; then continue; fi if [[ $iface_name == *"@"* ]]; then iface_name=$(echo "$iface_name" | cut -d "@" -f1) fi #echo $iface_name iface_list_entware="$iface_list_entware$iface_name " done #echo $iface_list_entware } get_keenetic_iface_descr() { if_name=$1 #echo "$if_name" echo $($NDMC_SHOW_IFACE "$if_name" | grep "description" | cut -d ":" -f 2 | cut -c 2- ) } get_keenetic_iface_state() { if_name=$1 #echo "$if_name" echo $($NDMC_SHOW_IFACE "$if_name" | grep "state:" | cut -d ":" -f 2) } is_netimd_on_iface_exist() { if_name="im"${1:2} ! [ -z $( (ip a show $if_name | grep $if_name | \ cut -d "@" -f1 | cut -d " " -f 2) 2> /dev/null) ] #! [ -z $(ifconfig $if_name | grep $if_name | cut -d " " -f1 > /dev/null 2>&1 ) ] } CheckFile() { filename=$1 if [ -f $filename ]; then while IFS= read -r line do #echo "$line" if_linux=$(echo $line | cut -d " " -f 1) if_keenetic=$(echo $line | cut -d " " -f 2 | tr -d "\r") #echo "$if_linux $if_keenetic" if is_netimd_on_iface_exist $if_linux; then netimd_exist="Y" else netimd_exist=" " fi #if_descr="" #if_state="" if_descr=$(get_keenetic_iface_descr $if_keenetic) if_state=$(get_keenetic_iface_state $if_keenetic) echo "$if_linux $if_keenetic $if_state im=$netimd_exist $if_descr" done < $filename fi } OnIfStateChanged () { # Create file if not exist: if ! [ -f $IFACE_NAMES_FILE ]; then touch $IFACE_NAMES_FILE; fi #if ! grep -q "${id}" "$IFACE_NAMES_FILE"; then iface_needed ${system_name} retval=$? if [ "$retval" == 0 ]; then exit 0 fi #iface_descr=$(get_keenetic_iface_descr ${id}) #iface_im=$(is_netimd_on_iface_exist ${system_name}) #if [ -z "$iface_im" ]; then # status="0" #else # status="1" #fi seclevel=$(iface_keenetic_security_level ${id}) #logger "netimd: sec=$seclevel ${id} -> ${system_name}" if [ -z "$seclevel" ]; then exit 0 fi if ! [[ $seclevel == "public" ]]; then exit 0 fi if grep -q "${system_name}" "$IFACE_NAMES_FILE"; then exit 0 fi # Add record in file if not exist: echo "${system_name} ${id}" >> $IFACE_NAMES_FILE #logger "add: ${id} -> ${system_name}" } 3. Результат в /opt/etc/netimd/pub.dev: apcli0 WifiMaster0/WifiStation0 eth2.2 FastEthernet0/Vlan2 cdc_br0 CdcEthernet0 Quote Link to comment Share on other sites More sharing options...
Zeleza Posted June 21, 2023 Author Share Posted June 21, 2023 Доброго дня Подскажите пожалуйста: Какая задача стояла перед Вами при реализации данного решения? Как Вы реализовали WUI под данную задачу? Quote Link to comment Share on other sites More sharing options...
krass Posted June 21, 2023 Share Posted June 21, 2023 2 минуты назад, ANDYBOND сказал: 3. Согласны ли разработчики Кинетика с правомерностью такой модификации их проприентарного кода? @eralde Ну вообще-то на гитхабе их сдк опуликовано....думаю да... Quote Link to comment Share on other sites More sharing options...
krass Posted June 21, 2023 Share Posted June 21, 2023 1 час назад, Zeleza сказал: Как Вы реализовали WUI под данную задачу? Доброго дня. Думаю через https://github.com/keenetic/keenetic-sdk Quote Link to comment Share on other sites More sharing options...
eralde Posted June 21, 2023 Share Posted June 21, 2023 2 часа назад, ANDYBOND сказал: 3. Согласны ли разработчики Кинетика с правомерностью такой модификации их проприентарного кода? @eralde Исходный код веб-интерфейса весь доступен любому пользователю Кинетик. Правда, в минифицированном виде. Мы не можем запретить кому-либо скачать и изучить исходный код веб-интерфейса. Да и не хотим. Если кому-то удалось добавить к веб-интерфейсу то, чего ему не хватало -- это просто замечательно. Не будь у меня доступа к исходникам, разработка моего расширения требовала бы на порядок больших усилий. Наоборот, мне очень интересно посмотреть как сделано то, что представлено на скриншоте 1 Quote Link to comment Share on other sites More sharing options...
Serafim Posted July 3, 2023 Share Posted July 3, 2023 Доброго дня! Отвечаю, для чего мне это понадобилось: http://imdtech.ru/technologies/netimd_keenetic/. Задача была простая: добавить модуль симметричного шифрования и управление им. Цепочка решения : собрать модуль и приложение управления под keenetic-sdk, добавить в entware, затем приступил к интерфейсу - добавил контроллер angularjs. Могу читать и редактировать настроечный файл. Осталось научить работать с моим приложением. Видимо копаем в сторону NodeJs. Жаль что не удалось через exec в web интерфейсе получить управление своей программой. До этого момента для решения по Web интерфейсу использовал nginx встроенный . 2 Quote Link to comment Share on other sites More sharing options...
Zeleza Posted July 3, 2023 Author Share Posted July 3, 2023 1 час назад, Serafim сказал: Задача была простая: добавить модуль симметричного шифрования и управление им. Доброго дня Если, я все верно понял, то судя по коду (поправьте, если я не прав), Вы выбираете лишь часть интерфейсов, а именно - только те, которые имеют в своем имени '@', а это лишь часть решения описанной в начале этой темы задачи. Полагаю, что иного решения, чем "передергивание" интерфейсов пока не найдено для получения полного списка соответствий. Но меня, в большей степени, интересует Ваш опыт по встраиванию Вашего кода в WUI самого роутера. Буду Вам очень признателен, если сможете поделиться свои опытом в этом вопросе (можете написать в "личку"). Quote Link to comment Share on other sites More sharing options...
Serafim Posted July 3, 2023 Share Posted July 3, 2023 2 минуты назад, Zeleza сказал: Доброго дня Если, я все верно понял, то судя по коду (поправьте, если я не прав), Вы выбираете лишь часть интерфейсов, а именно - только те, которые имеют в своем имени '@', а это лишь часть решения описанной в начале этой темы задачи. Полагаю, что иного решения, чем "передергивание" интерфейсов пока не найдено для получения полного списка соответствий. Но меня, в большей степени, интересует Ваш опыт по встраиванию Вашего кода в WUI самого роутера. Буду Вам очень признателен, если сможете поделиться свои опытом в этом вопросе (можете написать в "личку"). Дело в том, что встраивания в фирваре я не производил. Запускаю параллельно с основным интерфейсом сайт на другом порту( в данном случае 81) под тем же nginx. Команда на запуск подается после запуска entware через s файл , находящийся в /opt/etc/init.d . Для размещения собственного кода в интерфейс распаковываю файл App…..Js из каталога scrips сайта и работаю с ним. Quote Link to comment Share on other sites More sharing options...
Zeleza Posted July 3, 2023 Author Share Posted July 3, 2023 2 минуты назад, Serafim сказал: Дело в том, что встраивания в фирваре я не производил. Запускаю параллельно с основным интерфейсом сайт на другом порту( в данном случае 81) под тем же nginx. Команда на запуск подается после запуска entware через s файл , находящийся в /opt/etc/init.d . Для размещения собственного кода в интерфейс распаковываю файл App…..Js из каталога scrips сайта и работаю с ним. Понял Вас, спасибо. В любом случае, отличная работа! Quote Link to comment Share on other sites More sharing options...
Recommended Posts
Join the conversation
You can post now and register later. If you have an account, sign in now to post with your account.
Note: Your post will require moderator approval before it will be visible.