EM-129

Материал из noname.com.ua
Перейти к навигацииПерейти к поиску


EM-129

В связи с нестабильностью питания решил наконец поставить хоть какое-то защитное реле что б не спалить технику
(в последний раз броски напряжения не пережил свитч Catalyst 3550 и я остался без PoE для все своих железок чем был сильно расстроен)


По EM-129 есть практически исчерпывающий обзор от Андрея, которому нет причин не доверять:

Однако в обзоре не упоминается ничего про программную часть устройства

Зачем?

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

Пару слов об устройстве

Я не могу сказать ничего хорошего про реализацию безопастности EM-129

  • Поддержка HTTPS отсутвует
  • Кабельного подключения нет

Этих 2 факторов вполне достаточно что бы при желании можно было взломать сеть и отснифить пароль - в качестве "защиты" могу скаазть только что надо подойти достаточно близко что бы сниффить траффик.


Сигнал достаточно слабый хотя расстяние от места установки до точки доступа - примерно 5 метров и одна бетонная стена

/interface/wireless/registration-table/print
Columns: INTERFACE, MAC-ADDRESS, AP, SIGNAL-STRENGTH, TX-RATE, UPTIME
2  wlan-2.4Ghz-ssid-infra-1  CC:50:E3:FA:83:55  no  -81dBm@1Mbps     18Mbps                  1d1h13m32s


Получение данных

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


Из минусов - авторизация сделана максимально плохо

  • Используется только пароль, без логина
  • При авторизации создается Session ID (далее SID) который может быть только один и который по сути представляет собой префикс в URL для получения данных
  • Прямое следствие этого - на устройство можно зайходить и смотреть только одному пользователю одновременно. При подключении второго SID меняется и первого "отлогинивает"
  • BasicAuth был бы лучше в разы


Для того что бы понять как происходит авторизация пришлось немного покопаться в коде JS (что замечу говорит о "удачности" решения)

Авторизация происходит следующим образом

  • Пользователь вводит пароль
  • Браузер отправляет на устройство запрос что бы получить "соль" (случайное число) и тип устройства (похоже что аналогичный код используется не только в EM-129 но и других реле)
  • На оснвани полученой соли, имени устройства и пользовательского пароля формируется "секретная строка" и отправляется на сервер (основое время было потрачено на то что б найти как формируется эта секретная строка, и я не пишу на JavaScript. Думаю у web-разработчика это заняло бы единицы минут а не пол часа как у меня)
  • Если строка верна то сервер возвращает SID
  • ВСЕ!

Код скрипта

27 строк на bash

  • IP - адрес реле
  • SALT_URL - адрес куда посылать запрос на "соль"
  • TOKEN_URL - адрес куда послылать запрос на SID
  • ALL_DATA_URI - суффикс запроса данных

Секретная строка формируется следующим образом:

  • sha1 от строки состоящей из 3 частей
- имя устройства
- Пользовательский пароль закодированный в base64
- "соль"

По шагам

  • A__EM_129_SALT="$(curl ${SALT_URL} | jq -r '.SALT')" - послать запрос на соль и взять поле с именем "SALT" из полученного json
  • S=$(printf ${EM_129_PASSWORD} | base64) - закодировать пароль
  • SUM="${E__EM_129_DEVNAME}${S}${A__EM_129_SALT}" - склеять строки
  • LOGIN="$(printf "${SUM}" | sha1sum | awk '{ print $1}')" - взять sha1 от склейки строк
  • SID="$(curl "${TOKEN_URL}${LOGIN}"| jq -r '.SID')" - отправить запрос на SID и взять из ответа значение поля SID

Получение данных дальше

  • ALL_DATA_URL="http://${IP}/${SID}/${ALL_DATA_URI}" - сформировать адрес куда слать запрос с учетом SID
  • D=$(curl ${ALL_DATA_URL} | jq -r .) получить данные

Данные получаются в виде json

{
  "volt_msr": 2302,
  "freq_msr": 5000,
  "cur_msr": 321,
  "pows_msr": 740,
  "enrga_msr": 32,.
  "enrga_d_msr": 0,
  "enrga_w_msr": 0,
  "enrga_m_msr": 0,
  "enrgs_msr": 39,
  "sys_flag": 1409482896,
  "faul_flag": 0,
  "ar_time": 0,
  "cost_energy": 1700,
  "cost_unit": 16,
  "STATUS": "OK"
}

Код скрипта

#!/bin/bash

set -eu${DEBUG:+x}

IP="192.168.31.250"
SALT_URL="http://${IP}/api/login?salt"
TOKEN_URL="http://${IP}/api/login?login="
ALL_DATA_URI="api/all/get?volt_msr&freq_msr&cur_msr&pows_msr&enrga_msr&enrga_d_msr&enrga_w_msr&enrga_m_msr&enrgs_msr&sys_flag&faul_flag&ar_time&cost_energy&cost_unit"

A__EM_129_SALT="$(curl ${SALT_URL} | jq -r '.SALT')"
E__EM_129_DEVNAME="EM-129"
EM_129_PASSWORD="12345678"

S=$(printf ${EM_129_PASSWORD} | base64)
SUM="${E__EM_129_DEVNAME}${S}${A__EM_129_SALT}"
LOGIN="$(printf "${SUM}" |  sha1sum | awk '{ print $1}')"
SID="$(curl "${TOKEN_URL}${LOGIN}"| jq -r '.SID')"


ALL_DATA_URL="http://${IP}/${SID}/${ALL_DATA_URI}"
D=$(curl ${ALL_DATA_URL} | jq -r .)
if [ "${D}X" != "X" ];
then
    echo "${D}"
else
    echo "{}"
    exit 1
fi
exit 0


Интеграция с мониторингом

Имя возможность получать данные с устройства не составит труда сделать интеграцию за заббиксом или прометеем
В моем случае все максимально просто и практически полностью соответвует статье https://serveradmin.ru/parsing-i-peredacha-json-dannyih-v-zabbix/

  • Добавить скрипт в агента (не забыть дать возможность агенту ходить на устройство если они в разных VLAN и между ними есть фильтрация)
cat /etc/zabbix/zabbix_agentd.d/UserParameter-ElectricCounter.conf
UserParameter=electricCounter,/etc/zabbix/scripts/counter.sh

Далее сделать зависимые Items как описано выше по сслыке. Готовый темплейт для особо ленивых ниже =)

Zabbix template

<?xml version="1.0" encoding="UTF-8"?>
<zabbix_export>
    <version>5.0</version>
    <date>2022-08-14T12:27:09Z</date>
    <groups>
        <group>
            <name>Electric Counter</name>
        </group>
    </groups>
    <templates>
        <template>
            <template>Template Electric Counter</template>
            <name>Template Electric Counter</name>
            <groups>
                <group>
                    <name>Electric Counter</name>
                </group>
            </groups>
            <applications>
                <application>
                    <name>electricCounter</name>
                </application>
            </applications>
            <items>
                <item>
                    <name>electricCounter</name>
                    <key>electricCounter</key>
                    <history>0</history>
                    <trends>0</trends>
                    <value_type>TEXT</value_type>
                    <applications>
                        <application>
                            <name>electricCounter</name>
                        </application>
                    </applications>
                </item>
                <item>
                    <name>electricCounter.current</name>
                    <type>DEPENDENT</type>
                    <key>electricCounter.current</key>
                    <delay>0</delay>
                    <value_type>FLOAT</value_type>
                    <units>A</units>
                    <applications>
                        <application>
                            <name>electricCounter</name>
                        </application>
                    </applications>
                    <preprocessing>
                        <step>
                            <type>JSONPATH</type>
                            <params>$.cur_msr</params>
                        </step>
                        <step>
                            <type>MULTIPLIER</type>
                            <params>0.01</params>
                        </step>
                    </preprocessing>
                    <master_item>
                        <key>electricCounter</key>
                    </master_item>
                </item>
                <item>
                    <name>electricCounter.power</name>
                    <type>DEPENDENT</type>
                    <key>electricCounter.powerVA</key>
                    <delay>0</delay>
                    <value_type>FLOAT</value_type>
                    <units>VA</units>
                    <applications>
                        <application>
                            <name>electricCounter</name>
                        </application>
                    </applications>
                    <preprocessing>
                        <step>
                            <type>JSONPATH</type>
                            <params>$.pows_msr</params>
                        </step>
                    </preprocessing>
                    <master_item>
                        <key>electricCounter</key>
                    </master_item>
                </item>
                <item>
                    <name>electricCounter.freq</name>
                    <type>DEPENDENT</type>
                    <key>electricCounter.vfreq</key>
                    <delay>0</delay>
                    <value_type>FLOAT</value_type>
                    <units>Hz</units>
                    <applications>
                        <application>
                            <name>electricCounter</name>
                        </application>
                    </applications>
                    <preprocessing>
                        <step>
                            <type>JSONPATH</type>
                            <params>$.freq_msr</params>
                        </step>
                        <step>
                            <type>MULTIPLIER</type>
                            <params>0.01</params>
                        </step>
                    </preprocessing>
                    <master_item>
                        <key>electricCounter</key>
                    </master_item>
                </item>
                <item>
                    <name>electricCounter.volt</name>
                    <type>DEPENDENT</type>
                    <key>electricCounter.volt</key>
                    <delay>0</delay>
                    <value_type>FLOAT</value_type>
                    <units>V</units>
                    <applications>
                        <application>
                            <name>electricCounter</name>
                        </application>
                    </applications>
                    <preprocessing>
                        <step>
                            <type>JSONPATH</type>
                            <params>$.volt_msr</params>
                        </step>
                        <step>
                            <type>MULTIPLIER</type>
                            <params>0.1</params>
                        </step>
                    </preprocessing>
                    <master_item>
                        <key>electricCounter</key>
                    </master_item>
                </item>
            </items>
            <screens>
                <screen>
                    <name>Counters</name>
                    <hsize>1</hsize>
                    <vsize>3</vsize>
                    <screen_items>
                        <screen_item>
                            <resourcetype>0</resourcetype>
                            <style>0</style>
                            <resource>
                                <name>Volts/Ampers</name>
                                <host>Template Electric Counter</host>
                            </resource>
                            <width>1500</width>
                            <height>200</height>
                            <x>0</x>
                            <y>0</y>
                            <colspan>1</colspan>
                            <rowspan>1</rowspan>
                            <elements>0</elements>
                            <valign>0</valign>
                            <halign>0</halign>
                            <dynamic>0</dynamic>
                            <sort_triggers>0</sort_triggers>
                            <url/>
                            <application/>
                            <max_columns>3</max_columns>
                        </screen_item>
                        <screen_item>
                            <resourcetype>0</resourcetype>
                            <style>0</style>
                            <resource>
                                <name>Power</name>
                                <host>Template Electric Counter</host>
                            </resource>
                            <width>1500</width>
                            <height>200</height>
                            <x>0</x>
                            <y>1</y>
                            <colspan>1</colspan>
                            <rowspan>1</rowspan>
                            <elements>0</elements>
                            <valign>0</valign>
                            <halign>0</halign>
                            <dynamic>0</dynamic>
                            <sort_triggers>0</sort_triggers>
                            <url/>
                            <application/>
                            <max_columns>3</max_columns>
                        </screen_item>
                        <screen_item>
                            <resourcetype>0</resourcetype>
                            <style>0</style>
                            <resource>
                                <name>Freq</name>
                                <host>Template Electric Counter</host>
                            </resource>
                            <width>1500</width>
                            <height>200</height>
                            <x>0</x>
                            <y>2</y>
                            <colspan>1</colspan>
                            <rowspan>1</rowspan>
                            <elements>0</elements>
                            <valign>0</valign>
                            <halign>0</halign>
                            <dynamic>0</dynamic>
                            <sort_triggers>0</sort_triggers>
                            <url/>
                            <application/>
                            <max_columns>3</max_columns>
                        </screen_item>
                    </screen_items>
                </screen>
            </screens>
        </template>
    </templates>
    <graphs>
        <graph>
            <name>Freq</name>
            <graph_items>
                <graph_item>
                    <sortorder>1</sortorder>
                    <color>1A7C11</color>
                    <item>
                        <host>Template Electric Counter</host>
                        <key>electricCounter.vfreq</key>
                    </item>
                </graph_item>
            </graph_items>
        </graph>
        <graph>
            <name>Power</name>
            <graph_items>
                <graph_item>
                    <sortorder>1</sortorder>
                    <color>1A7C11</color>
                    <item>
                        <host>Template Electric Counter</host>
                        <key>electricCounter.powerVA</key>
                    </item>
                </graph_item>
            </graph_items>
        </graph>
        <graph>
            <name>Volts/Ampers</name>
            <graph_items>
                <graph_item>
                    <sortorder>1</sortorder>
                    <color>F63100</color>
                    <yaxisside>RIGHT</yaxisside>
                    <item>
                        <host>Template Electric Counter</host>
                        <key>electricCounter.volt</key>
                    </item>
                </graph_item>
                <graph_item>
                    <sortorder>2</sortorder>
                    <color>2774A4</color>
                    <item>
                        <host>Template Electric Counter</host>
                        <key>electricCounter.current</key>
                    </item>
                </graph_item>
            </graph_items>
        </graph>
    </graphs>
</zabbix_export>