Jump to content

Recommended Posts

Posted (edited)

Здраствуйте! Разрабатываю демона по типу kvas и хочу в модальном окне выбора интерфейса выводить вместо какого-нибудь UNIX'ового названия "nwg0" или же "ovpn_br0" выводить человеко-читаемое название интерфейса по типу "WireGuard [Home] (nwg0)".

К сожалению из запроса `GET http://192.168.1.1/rci/show/interface/Wireguard1` имею лишь такую структуру, где нет ни слова о UNIX'овом названии интерфейса:

{
    "id": "Wireguard1",
    "index": 1,
    "interface-name": "Wireguard1",
    "type": "Wireguard",
    "description": "Home",
    "traits": [
        "Ip",
        "Ip6",
        "Wireguard"
    ],
    "link": "down",
    "connected": "no",
    "state": "down",
    "mtu": 1324,
    "tx-queue-length": 50,
    "global": false,
    "security-level": "public",
    "ipv6": {},
    "wireguard": {},
    "summary": {
        "layer": {
            "conf": "disabled",
            "link": "disabled",
            "ipv4": "disabled",
            "ipv6": "disabled",
            "ctrl": "disabled"
        }
    }
}

Видел, что kvas решает эту проблему использованием хука iflayerchanged и перезапуском всех интерфейсов, что считаю это решение не очень то и хорошим, ибо подобная информация как по мне должна быть как и в CLI Keenetic (Telnet), так и в REST API (а по возможности, кстати, хотелось бы иметь документацию по REST API, ибо её нигде не нашел).

Где можно достать UNIX имя интерфейса без использования подобных костылей (из-за текущих ограничений Keenetic'а)?

Edited by Ponywka
  • Thanks 1
  • Upvote 1
Posted
Цитата

CLI Keenetic (Telnet), так и в REST API (а по возможности, кстати, хотелось бы иметь документацию по REST API, ибо её нигде не нашел).

На самом деле совершенно не очевидно, потому что без установки opkg системное имя никому и нигде не может потребоваться - его просто нет в командах и выводе. Именно потому его там и нет.

Мы подумаем, что можно сделать.

  • Upvote 5
Posted
1 минуту назад, Le ecureuil сказал:

На самом деле совершенно не очевидно, потому что без установки opkg системное имя никому и нигде не может потребоваться - его просто нет в командах и выводе. Именно потому его там и нет.

Мы подумаем, что можно сделать.

В параллельной теме тоже спрашивал об этом. Ждем решения....

Posted
8 hours ago, Le ecureuil said:

На самом деле совершенно не очевидно, потому что без установки opkg системное имя никому и нигде не может потребоваться - его просто нет в командах и выводе.

Хм... Ну с этой точки зрения конечно верно... Просто хотелось бы, если не иметь возможность встраивать какие-то настройки во внутрь самой веб-морды Keenetic, то хотя-бы иметь возможность дёргать с самого Keenetic какие-то данные (например тот же человеко-читаемое название интерфейса, добавленное из интерфейса самого Keenetic) и рисовать уже свой интерфейс на каком-то порту (что я и хочу сделать)

Перезапускать все интерфейсы я ну очень не хочу, ибо это долгий процесс. В таком случае уж лучше просто вывести UNIX'овое имя интерфейса, а пользователь пускай сам разбирается.

 

Вообще та штука, которую я хочу сделать реализовывается и через CLI Keenetic'а, однако это засрёт таблицу маршрутов на самом роутере, чего я делать тоже не очень хочу, ибо отслеживать изменения оттуда ещё сложнее, породит ещё больше костылей, а также будет медленно выполняться. iptables+ipset как-то быстрее с этой задачей справятся.

Posted
39 minutes ago, Le ecureuil said:

Человекочитаемое имя лежит в поле description в выводе show interface.

Я имел ввиду про софт, который я пишу, который использует iptables и работает с UNIX'овыми названиями интерфейсов, но который запущен на роутерах Keenetic.

Posted (edited)
51 минуту назад, Ponywka сказал:

Я имел ввиду про софт, который я пишу, который использует iptables и работает с UNIX'овыми названиями интерфейсов, но который запущен на роутерах Keenetic.

можно брать адреса  интерфейсов через  ip address и сравнивать с теми что вам покажет ndmc -c show interface, по этому признаку и выяснять кто есть кто

Edited by Denis P
  • Upvote 1
Posted
53 minutes ago, Denis P said:

можно брать адреса  интерфейсов через  ip address и сравнивать с теми что вам покажет ndmc -c show interface

Ну, как вариант кстати 😕

  • 4 months later...
Posted (edited)

Тоже столкнулся с похожей проблемой при разработке своей утилиты "keenetic-pbr".

Мне необходимо из Entware каким-то образом узнавать, активно ли текущее WireGuard/OpenVPN/etc соедниение. Через ip addr (и соотв. библиотеку netlink) можно узнать только состояние up=true/false (т.е. интерфейс административно включён или выключен).

Через RCI (curl localhost:79/rci/show/interface) доступно больше информации, там есть поле connected=yes/no и link=up/down

Вот это поле connected меня полностью устраивает, чтобы понять, активно ли текущее соединение (напр. для WireGuard это значит, что keepalive пакеты проходят), однако чтобы понять, что nwg1 это то же самое, что и WireGuard1, нужно их соотностить по какому-то полю.

Если бы RCI отдавал название системного интерфейса nwg1, это бы облегчило сопоставление.

---

UPD: Сопоставление по IP не очень надёжное, т.к. если интерфейс выключен в Keenetic UI, то в RCI у него не будет IP-адреса, соотв. сопоставить его будет невозможно. MAC-адрес тоже есть не у всех интерфейсов (напр. у WireGuard его нет)

Edited by maksimkurb
  • Upvote 1
Posted
В 03.01.2025 в 17:48, maksimkurb сказал:

…однако чтобы понять, что nwg1 это то же самое, что и WireGuard1, нужно их соотностить по какому-то полю.

/opt/etc/ndm/ifstatechanged.d/ отдаёт оба имени интерфейса: прошивочное и линуксовое.

~ # cat /opt/etc/ndm/ifstatechanged.d/000-gather-iflist.sh 
#!/bin/sh

list='/tmp/iflist.txt'
interface="$id: $system_name"

if [ ! -f $list ]; then
    echo $interface > $list
else
    echo $interface | cat $list - | sort -u > $list.tmp
    mv $list.tmp $list
fi
exit 0

Как вариант, можно надёргать соответствий там:

~ # cat /tmp/iflist.txt 
Bridge0: br0
Bridge1: br1
Bridge2: br2
GigabitEthernet0/0: eth2
GigabitEthernet0/1: eth2
GigabitEthernet0/2: eth2
GigabitEthernet0/3: eth2
GigabitEthernet0/4: eth2
GigabitEthernet0/5: eth2
GigabitEthernet0/6: eth2
GigabitEthernet0/7: eth2
GigabitEthernet0/8: eth2
GigabitEthernet0/Vlan1: eth2.1
GigabitEthernet0/Vlan2: eth2.2
GigabitEthernet0/Vlan3: eth2.3
GigabitEthernet0: eth2
GigabitEthernet1/0: eth3
GigabitEthernet1: eth3
Gre0: ngre0
PPTP0: ppp0
TunnelSixInFour0: tun6in4_0
UsbQmi0: qmi_br0
WifiMaster0/AccessPoint0: ra0
WifiMaster0/AccessPoint1: ra1
WifiMaster0: ra0
WifiMaster1/AccessPoint0: rai0
WifiMaster1/AccessPoint1: rai1
WifiMaster1: rai0
Wireguard0: nwg0
Wireguard4: nwg4

 

  • 2 weeks later...
Posted

Капец какой-то куда не кинь всюду клин.
ifstatechanged.d или  ifcreate как по скорости так и по реализации вынимания имени из них иначе чем "костыль" не назовешь. Как в принципе и остальные варианты имеющиеся в руках у сообщества.
 

В 26.08.2024 в 18:40, Le ecureuil сказал:

Мы подумаем, что можно сделать.

Жуть как нужно.
Хоть что-то, пусть даже кучей вроде

Bridge2: br2
GigabitEthernet0/0: eth2

разберем как нибудь, главное возможность быстро получить актуальные данные.

Очень ждем.

  • 2 weeks later...
Posted
В 26.08.2024 в 06:34, Ponywka сказал:

kvas решает эту проблему использованием хука iflayerchanged и перезапуском всех интерфейсов, что считаю это решение не очень то и хорошим

Сейчас вводится новая схема на сопоставлениях по IP (функция nets__set_common). Но, как уже указали

В 03.01.2025 в 17:48, maksimkurb сказал:

если интерфейс выключен в Keenetic UI, то в RCI у него не будет IP-адреса, соотв. сопоставить его будет невозможно

Опять же, если пользователь отключил интерфейс в админке; то не очень-то и хочет, чтобы его использовали в утилите.

 

Но к означенному есть ещё проблема. Если Вам нужны ещё некоторые гостевые VPN (PPTP, SSTP, OpenConnect, L2TP, IKEv2); то ни этот код не поможет, ни новое поле в API. В терминах Linux у них есть сетевые интерфейсы (можно рулить в iptables через, как пример, pptp+, sstp+, oc+, l2tp+ и xfrms+ начиная с 4.2), но в терминах API у них отдельного сетевого интерфейса нет (упоминаний в /rci/show/interface). Даже чтобы посмотреть их диапазон IP (pool-start, как пример), нужно скакать по разным разделам API. При этом если проверять этот раздел API на наличие (чтобы узнать включен ли сервер), то при его отсутствии в логе роутера будут ошибки. Чтобы предположить, можно ли обращаться к этому разделу API, я использую теги (127.0.0.1:79/rci/show/tags/). В итоге картина получается такой:

  1. есть тег ipsec-xauth, можно обращаться к 127.0.0.1:79/rci/crypto/virtual-ip-server-ikev2 (для pool-start, как пример);
  2. для ipsec-l2tp crypto/l2tp-server;
  3. для vpn-oc просто oc-server;
  4. для sstp sstp-server.

Ужасная не консистентность; но, видимо, «так исторически сложилось». Итоговый код для гостевых без своего API-интерфейса примерно такой

# замена Singleton, чтобы скан был лишь при первом вызове
NETS_INCOMING=''
nets__set_incoming() {
    if [ -n "${NETS_INCOMING}" ]; then
        return
    fi
    local api_tags api_info
    # Запрос конкретного раздела может оставить ошибки в логе роутера, если он отключен.
    # Поэтому проверять включенность будем через тэги.
    api_tags=$(curl -s '127.0.0.1:79/rci/show/tags/')

    # IPsec в crypto
    if echo "${api_tags}" | grep -qF 'ipsec-xauth' ; then
        api_info=$(curl -s '127.0.0.1:79/rci/crypto/virtual-ip-server-ikev2')
        if [ -n "${api_info}" ] ; then
            NETS_INCOMING="${NETS_INCOMING}"'xfrms+|'$(echo "${api_info}" \
              | jq -r '."pool-start" // empty')'|crypto/virtual-ip-server-ikev2|"VPN-сервер IKEv2/IPsec"'$'\n'
        fi
    fi
    if echo "${api_tags}" | grep -qF 'ipsec-l2tp' ; then
        api_info=$(curl -s '127.0.0.1:79/rci/crypto/l2tp-server')
        if [ -n "${api_info}" ] ; then
            NETS_INCOMING="${NETS_INCOMING}"'l2tp+|'$(echo "${api_info}" \
              | jq -r '."pool-start" // empty')'|crypto/l2tp-server|"VPN-сервер L2TP/IPsec"'$'\n'
        fi
    fi

    # остальные в глобальном
    if echo "${api_tags}" | grep -qF 'vpn-oc' ; then
        api_info=$(curl -s '127.0.0.1:79/rci/oc-server')
        if [ -n "${api_info}" ] ; then
            NETS_INCOMING="${NETS_INCOMING}"'oc+|'$(echo "${api_info}" \
              | jq -r '.config."pool-start" // empty')'|oc-server|"VPN-сервер OpenConnect"'$'\n'
        fi
    fi
    if echo "${api_tags}" | grep -qF 'sstp' ; then
        api_info=$(curl -s '127.0.0.1:79/rci/sstp-server')
        if [ -n "${api_info}" ] ; then
            NETS_INCOMING="${NETS_INCOMING}"'sstp+|'$(echo "${api_info}" \
              | jq -r '.config."pool-start" // empty')'|sstp-server|"VPN-сервер SSTP"'$'\n'
        fi
    fi

    # чтобы не сканировало повторно, если ничего не найдено
    if [ -z "${NETS_INCOMING}" ]; then
        NETS_INCOMING=$'\n'
    fi
}

nets__set_incoming
echo "${NETS_INCOMING}"

 

Posted (edited)
В 12.01.2025 в 01:40, Александр Рыжов сказал:

/opt/etc/ndm/ifstatechanged.d/

@Александр Рыжов

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

 

~ # cat /opt/etc/ndm/ifstatechanged.d/000-gather-iflist.sh

#!/bin/sh

mem_dir="/dev/int"
interface="$id"
list="$system_name"

mkdir -p "$mem_dir"
echo "$list" > "$mem_dir/$interface"
exit

После перезагрузки имеем полный обновляемый список соответствий прошивочного имени системному в RAM.
 

~ # ls /dev/int/
Bridge0           GigabitEthernet0  GigabitEthernet1  WifiMaster0       WifiMaster1       Wireguard0

Вызвать можно из любого места, мгновенно получив системное имя из прошивочного:
 

~ # cat /dev/int/GigabitEthernet0
eth2
~ # cat /dev/int/Wireguard0
nwg0

@Ponywka
 

Edited by Ground_Zerro
Posted

@ground_zerro, а можно поподробнее для чайников?

Надо создать файл 000-gather-iflist.sh с содержимым:

#!/bin/sh

mem_dir="/dev/int"
interface="$id"
list="$system_name"

mkdir -p "$mem_dir"
echo "$list" > "$mem_dir/$interface"
exit 0~ #

Так? Потом сделать его исполняемым? И перезагрузиться?

  • Upvote 1
Posted

В следующей версии 4.03 появится скрытая команда
> show interface system-name

которая по ID интерфейса показывает его системное имя

  • Thanks 4
  • Upvote 2
Posted (edited)
On 1/11/2025 at 5:40 PM, Александр Рыжов said:

/opt/etc/ndm/*.d/

Это очень странно юзать Bash скрипты чтобы ловить те или иные состояния. Так например когда я пишу нативное ПО я могу вытворять все что угодно в фоне, но почему-то для того, чтобы получать какие-то эвенты - пришлось использовать UNIX сокет и перенаправлять поля из этих эвентов в этот UNIX сокет.

Пример:

#!/bin/sh
SOCKET_PATH="/opt/var/run/kvas2-go.sock"
if [ ! -S "$SOCKET_PATH" ]; then
    exit
fi
echo -n "netfilter.d:${type}:${table}" | socat - UNIX-CONNECT:"${SOCKET_PATH}"

 

Edited by Ponywka

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.

Guest
Reply to this topic...

×   Pasted as rich text.   Paste as plain text instead

  Only 75 emoji are allowed.

×   Your link has been automatically embedded.   Display as a link instead

×   Your previous content has been restored.   Clear editor

×   You cannot paste images directly. Upload or insert images from URL.

  • Recently Browsing   0 members

    • No registered users viewing this page.
×
×
  • Create New...

Important Information

This site uses cookies. By clicking "I accept" or continuing to browse the site, you authorize their use in accordance with the Privacy Policy.