SDS v síti: tipy, příklady, nastavení

SDS v síti

Moduly SDS jsou samy o sobě velmi schopné, a lze je dále rozšiřovat i vhodnými aplikacemi v rámci počítačové sítě.


Zabezpečení

Základní zabezpečení je umístit SDS za firewall a router.

Doporučená sestava:

 ISP ---- pfSense (NetGate) ----  Router  
          (firewall)                  | 
                                      |---- SDS
                                      |
                                      +---- počítač
                                            atd.

Doporučený firewall je stroj s pfSense, ale samozřejmě není to nikde předepsáno. Pokud jste spokojeni se svou, jinou, volbou, držte se ji. Existuje celá řada identických, nebo i lepších alternativ. Toto doporučení je zde pro ty, kteří neví a chtějí si nechat do začátku poradit. Kritické je vždy především firewall správně nastavit.

Router obvykle obsahuje (další) firewall v sobě. Rozdíl zde však je - samostatný firewall typu pfSense umí celou řadu věcí (např. pfBlocker-NG, nebo pokročilý filtr firewallu atd.), zatímco typicky základní firewall v routeru má jen typicky základní funkčnosti filtru.

Zcela určitě nepřipojujte SDS přímo do Internetu, nebo do DMZ portu atd. - SDS musí být "skryto" za firewallem.


Vzdálený přístup k SDS z Internetu

SDS je typicky "skryto" za NATem v routeru. Pro přístup "z venku" je pak potřeba ručně nastavit průchod skrz NAT pro potřebné TCP a UDP porty.

Bavíme se o přístupu "z venku", tedy že se někdo z internetu chce dostat k službám, které SDS poskytuje. Nejedná se teď tedy o případ, kdy SDS naopak komunikuje samo (ven) se servery, ale čistě o případ kdy klient sám od sebe chce komunikovat (otevřít spojení) do SDS.

Další záležitost k řešení je IP adresa. Pokud nemáte pevnou veřejnou adresu (ke které si eventuálně umíte i udělat svůj veřejný DNS záznam), lze s výhodou využít funkci Dynamic IP (DynDns, No-IP, a řada dalších služeb, některé zdarma, některé placené).

Pokud s tímto chcete poradit, primárně se musíte domluvit se svým ISP.

Obecně není doporučeno vystavovat HTTP rozhraní modulu SDS veřejně ven na Internet (neplatí pro HTTPS rozhraní u modulů SDS). Typicky se tato potřeba objeví, pokud chcete prezentovat data z SDS - to je však vhodnější řešit přes nějakého prostředníka, viz dále (např. Grafana).


ePortál

SDS umí, prostřednictvím HTTP protokolu, samo pravidelně odesílat data na "portál". Není pak potřeba, aby se na SDS musel někdo "z venku" z Internetu dostávat = SDS může být schováno hluboce za firewallem a nepotřebuje reverzní tunel v NATu.

"Portál" je typicky serverová služba, která běží na serveru (v datacentru nebo i u vás doma...) s připojením do Internetu. Portál sám neobvolává jednotlivá SDS, ale naopak SDS (s vhodným programem a konfigurací) posílá na portál svá naměřená data a stavy. Současně, při každé takové aktualizaci, si SDS může stáhnout nový příkaz či požadavek na změnu, a to vykonat.

Podle potřeby se interval nastavuje typicky na 15 minut, ale není důvod (pokud to server zvládne) posílat data i s odstupem jen několika sekund.

Výrobce SDS provozuje, pro všechny majitele SDS, takový portál, s názvem "ePortál", dostupný na www.merenidat.cz. Zde si své SDS zaregistrujete, a stáhne si následně vygenerovaný program (který obsahuje identifikační a šifrovací údaje). Tento program nahrajete do svého SDS, a od té chvíle SDS posílá data na tento portál, kde si je můžete archivovat a prohlížet, nebo zpětně SDS ovládat (např. relé). Tato služba je v základu nabízena trvale zdarma, jako součást původní prodejní ceny při nákupu SDS.

Samozřejmě můžete své SDS naprogramovat, aby odesílalo data na jakoukoliv službu, resp. libovolný portál - pokud se s ním budete umět domluvit. Naše fórum je plné příkladů a dotazů na toto téma, doporučím začít tam.

Dále není nutné používat jen právě HTTP protokol pro tyto účely. Stejně dobře lze použít protokol MQTT, který SDS plně interně zvládá.


Odesílání emailu z SDS

SDS pracuje s protokolem SMTP na portu 25. Dnes už je problém sehnat veřejnou službu, která na tomto portu pracuje. Proto je standardní řešení spustit si lokální SMTP RELAY.

Příklad: máme účet (a veřejný SMTP server) na službě HOSTING, která podporuje jen SSL/TLS a chceme tam odeslat email z SDS (který ale komunikuje jen přes port TCP 25).

HOSTING === (port 456 ) ===  SMTP RELAY === (port 25) === SDS

Pak musíme nainstalovat a správně nastavit SMTP RELAY. To je specifický SW, který běží na lokálním serveru, přičemž tento server má přístup jak do Internetu, tak se na něj "dostane" i váš modul SDS. Typicky je takový server umístěn ve stejné (nebo blízké lokální) síti, jako právě ono SDS.

Dále musíme mít účet u SMTP SERVERu, který běží na službě HOSTING. Pak známe jeho celé doménové jméno (nebo IP adresu) a port, a dále uživatelské jméno a heslo.


Příklad: instalace SMTP RELAY na rPI

rPI je nejsnazší příklad, a tento postup je obecně replikovatelný na jiném Linux-based systému.

1. instalace postfix a balíčku pro SASL identifikaci (bez toho nefunguje přihlášení na vzdálený smtp server)

sudo apt-get install postfix
sudo apt-get install libsasl2-modules

2. editujte konfiguraci

sudo nano /etc/postfix/main.cf

3. zapište přístupové údaje k vzdálenému SMTP SERVERu

sudo nano /etc/postfix/relay_passwd
sudo /usr/sbin/postmap /etc/postfix/relay_passwd

3. restartujte postfix

sudo service postfix restart

4. (volitelný krok) kdykoliv sledujte jak postfix funguje (nebo nefunguje - a pak zde budou informace proč)

sudo tail -f /var/log/postfix.log

V případě že postfix nefunguje, pak je vhodné upravit nastavení (soubor master.cf), kde přidáte k jednotlivým aplikacím parametr -v (příklad: "snmp -v" místo jen "snmp"). V logu pak bude velmi detailní výpis, který jednoznačně ukáže, kde je chyba. Typicky bývá špatně nesprávná konfigurace v main.cf, dále špatné jméno a heslo na snmp server, nebo také často špatná doméná a TCP port serveru (pokud jich uvádí více, musíte vyzkoušet který podporuje SSL/TLS a SASL).

Kritické je správně nakonfigurovat funkci SNMP RELAY a SSL/TLS, v souboru main.cf - výchozí obsah je nutné upravit, jinak to z principu nebude fungovat. Viz příklad dále.

Vzorový obsah /etc/postfix/relay_passwd souboru, pro tento příklad:

wes1-smtp.wedos.net user@domena.cz:heslo
wes1-smtp.wedos.net:465 user@domena.cz:heslo

A dále obsah /etc/postfix/main.cg souboru, pro tento příklad:

# See /usr/share/postfix/main.cf.dist for a commented, more complete version
# Debian specific:  Specifying a file name will cause the first
# line of that file to be used as the name.  The Debian default
# is /etc/mailname.
#myorigin = /etc/mailname
smtpd_banner = $myhostname ESMTP $mail_name (Raspbian)
biff = no
# appending .domain is the MUA's job.
append_dot_mydomain = no
# Uncomment the next line to generate "delayed mail" warnings
#delay_warning_time = 4h
readme_directory = no
# See http://www.postfix.org/COMPATIBILITY_README.html -- default to 2 on
# fresh installs.
compatibility_level = 2
# TLS parameters
smtpd_tls_cert_file=/etc/ssl/certs/ssl-cert-snakeoil.pem
smtpd_tls_key_file=/etc/ssl/private/ssl-cert-snakeoil.key
smtpd_use_tls=yes
smtpd_tls_session_cache_database = btree:${data_directory}/smtpd_scache
smtp_tls_session_cache_database = btree:${data_directory}/smtp_scache
# See /usr/share/doc/postfix/TLS_README.gz in the postfix-doc package for
# information on enabling SSL in the smtp client.
#smtpd_relay_restrictions = permit_mynetworks permit_sasl_authenticated permit
myhostname = domain.cz
alias_maps = hash:/etc/aliases
alias_database = hash:/etc/aliases
myorigin = /etc/mailname
#pozor nedavat domeny do mydestination - co je zde konci na tomto stroji a nejde do relay !!!
mydestination = pi, localhost.localdomain, localhost
mynetworks = 127.0.0.0/8, 192.168.0.0/16, [::ffff:127.0.0.0]/104, [::1]/128
mailbox_size_limit = 0
recipient_delimiter = +
inet_interfaces = all
inet_protocols = ipv4
# SSL 465 nebo TLS 587
relayhost = wes1-smtp.wedos.net:465
smtp_tls_wrappermode = yes
smtp_tls_security_level = encrypt
smtp_sasl_auth_enable = yes
smtp_sasl_password_maps = hash:/etc/postfix/relay_passwd
smtp_sasl_security_options = noanonymous
#smtp_always_send_ehlo = yes
smtp_use_tls = yes
# POZOR WEDOS VYZADUJE SASL - musi se udelat apt-get libsasl2-modules  !!!
maillog_file = /var/log/postfix.log
# POZOR - zmena obsahu relay_passwd (plain text username:pwd) vyzaduje zavolat sudo postmap aby se vytvoril .db soubor

Kritické místa v main.cf pro konfiguraci

  • myhostname - podle poskytovatele SNMP SERVERu resp. doména odesílaného mailu ("FROM")
  • mynetworks - všimněte si přidaného subnetu 192.168.0.0/16 - kde v něm máme i naše SDS, které chceme aby s tímto postfixem komunikovalo (jinak by to postfix odmítnul)
  • mydestination - místo nejčastějšího důvodu "nefunkčnosti" - co je zde tak končí na tomto stroji a nejde do relay !
  • smtpd_relay_restrictions - toto je zakomentováno, aby nebyl klient (např. SDS) odmítnut, ale určitě by to šlo poladit tak jak to má být správně - do toho
  • relayhost - dle poskytovatele SNMP SERVERu
  • smtp_sasl_password_maps - pozor na správný odkaz na správný soubor (musí k němu navíc být vytvořen i soubor .db)
  • maillog_file - sem se bude zapisovat log, ale např. pozor na systémech s R/O FILESYSTEM (pak ať je to tam v RAMFS atd.).

Samozřejmě musíte si to upravit sami dle svého poskytovatele SMTP serveru !


Archivace a zobrazování dat

Dnešní jednoznačný trend je použití MQTT protokolu a zobrazení pomocí Grafana služby. Toto vše se instaluje bokem na vlastní lokální server, a SDS tyto služby "krmí" (a naopak, SDS lze odsud i ovládat).

Zásadní výhoda je oddělení přístupu k archivaci a prezentaci všech dat, od SDS samotného, takže uživatelé se k SDS prakticky nedostanou, a to v klidu dělá svou práci (řízení a dohled). Toto je zejména kritické, pokud mají být data prezentovány na Internetu.

Samozřejmě MQTT a Grafana není jediný způsob. Vše lze řešit i "ručně", např. vlastní databází na serveru, která se plní přes HTTP GET/POST protokol (základní funkčnost SDS), a zobrazení webovým serverem s vlastními stránkami, viz skvělý příklad: www.nesvara.cz.

Základní princip:

  SDS
+-----------------+
| SDS             |                server 
| FULL-C program  |              +-----------------------------------------------------------------------+
|  <->            |              |                                                                       |
| SDS MQTT CLIENT ------+----------   MQTT SERVER  ------  BRIDGE  ------ InfluxDB  ------ Grafana GUI .....----- uživatel (PC, Internet)
+-----------------+    /         |                                                                       |
                      /          +-----------------------------------------------------------------------+
  další SDS ---------+
  ...

Prakticky neomezený počet SDS a jiných MQTT klientů se připojí k jednomu MQTT serveru. Z druhé strany k tomuto serveru přistupuje (jako další klient, tam není rozdíl) služba BRIDGE, tedy služba, která ze MQTT serveru odebírá aktuální datový stav, a krmí jej do databáze. To je důležité, protože databáze má všechny záznamy v čase (archiv), kdežto MQTT server má vždy jen aktuální poslední stav a nic jiného. Z databáze se pak data čtou a zobrazují, např. prostřednictvím služby Grafana, která je to co pak připojení uživatelé vidí a používají (pro grafickou a surovou prezentaci dat).


  • Co je to MQTT

MQTT je komunikační protokol, který za vás, SDS plně řeší - vy to už jen používáte. Tímto protokolem můžete posílat data z SDS na server, nebo naopak SDS může ze serveru data dostávat (při jejich změně).

MQTT pracuje na principu položek - vždy máte "název položky" a její datový obsah. Příklad: "teplota_venku" a obsah "25".

Server udržuje jen poslední aktuální stav předávaných položek. Pokud chceme hodnoty průběžně archivovat, např. abychom je mohli i zobrazit a procházet, potřebujeme je uchovávat v databázi.

Typický, doporučený, MQTT server (odzkoušený i na rPI) je "Mosquitto".

Vzorová instalace Mosquitto na rPI (určitě to jde i snáze, nechám na vás, toto je příklad):

sudo wget http://repo.mosquitto.org/debian/mosquitto-repo.gpg.key
sudo apt-key add mosquitto-repo.gpg.key
cd /etc/apt/sources.list.d/
sudo wget http://repo.mosquitto.org/debian/mosquitto-stretch.list
sudo apt-get update
sudo apt-get install mosquitto mosquitto-clients
sudo apt-get install python-pip
sudo pip install paho-mqtt
cd /etc/mosquitto
sudo cp mosquitto.conf mosquitto.conf.original

A následně je potřeba editovat "/etc/mosquitto/mosquitto.conf" ať to celé správně funguje.

# Place your local configuration in /etc/mosquitto/conf.d/
#
# A full description of the configuration file is at
# /usr/share/doc/mosquitto/examples/mosquitto.conf.example
pid_file /var/run/mosquitto.pid
#persistence true
#persistence_location /var/lib/mosquitto/
persistence false
log_dest none
log_dest file /var/log/mosquitto/mosquitto.log
include_dir /etc/mosquitto/conf.d
allow_anonymous true
listener 1883

Výše uvedený příklad je zcela základní holá konfigurace. Umožňuje, aby se k serveru připojil jakýkoliv MQTT klient, bez ověření uživatelského jména a hesla.

Pro ostrý provoz je nezbytné doplnit možnost přihlášení pouze pro akceptované klienty. Ovšem při vývoji se dočasně možnost libovolného přihlášení hodí... ale nezapomeňte to pak správně dořešit.

MQTT SERVER udržuje všechny položky a jejich hodnoty. Tyto položky se zakládají tím, že se do serveru pošle datová informace (např. SDS tam zapíše novou hodnotu). Pokud daná položka v serveru ještě není, tak ten ji automaticky v tu chvíli založí.

Pokud si chceme položky prohlédnout (a jejich obsah), což je kritické při odlaďování celého systému (např. kontrola zda SDS odesílá co má a kdy má), je potřeba se připojit jiným klientem k tomuto MQTT serveru - vhodný je např. "MQTT EXPLORER", viz http://mqtt-explorer.com/ .

Popis MQTT v rámci programování SDS je na stránce MQTT.


  • Databáze

Zde je velmi vhodná databáze "InfluxDB". Zejména protože ji lze vhodně "krmit" a protože ji lze přímo připojit do Grafany, bez dalších složitostí.

Krmení databáze je jediný obtížný oříšek. Lze to provést službou "Telegraf" nebo si napsat malý skript, nebo to nakonec může dělat i přímo SDS (přes HTTP). Nejvhodnější je vlastní skript (většina lidí si je píše na rPI v Pythonu), nebo pak ten Telegraf. Obě metody berou aktuální data z MQTT serveru a krmí daty databázi, a uživatel se už nemusí o nic starat.

Instalace influxDB je jednoduchá a přímá - to podstatné je konfigurace.

Konfigurace je v souboru /etc/influxdb/influxdb.conf , který je ale velmi dlouhý, a proto zde ukážeme jen ty podstatné body, které umístí databázi do /var/lib (kterou lze s výhodou provozovat jako RAMFS a neopotřebovávat si tak pevné úložiště, jako je např. SD karta v rPI apod.)

### Welcome to the InfluxDB configuration file.
...
[meta]
 # Where the metadata/raft database is stored
 dir = "/var/lib/influxdb/meta"
...
[data]
 # The directory where the TSM storage engine stores TSM files.
 dir = "/var/lib/influxdb/data"

 # The directory where the TSM storage engine stores WAL files.
 wal-dir = "/var/lib/influxdb/wal"
...
[http]
 # Determines whether HTTP endpoint is enabled.
 enabled = true
...
atd.

Samozřejmě prvků v konfiguračním souboru je mnoho, podstatné je vśak [data] a pak jednotlivé vstupní mechanismy např. [http] [udp] atd. - povolit musíte ty, kterými chcete influxDB plni (např. z Telegrafu, vlastního skriptu atd.).

Dalším krokem je vytvoření databází. Po nové instalaci InfluxDB nejsou v systému jakékoliv databáze vytvořeny - to musíte udělat vy. Např. přes příkazy v CLI. Pro náš příklad založíme databázi s názvem "sds".


  • BRIDGE: automatický trvalý přesun dat z MQTT SERVERu do Influx DB databáze

Lze to provádět vhodnou službou, typicky aplikací Telegraf. Ovšem Telegraf je poměrně složitý na správnou konfiguraci, a je to také celkem moloch.

Lze využít i následující Python skript, který si můžete libovolně upravit (má v základu omezenou funkci, přenáší jen omezeně číselné položky jako float) - ale jako základ pro vlastní další tvorbu je to i celkem vhodné.

Podstatná konfigurace je MQTT_TOPIC a MQTT_REGEX - toto určuje, jaké položky (topics) bude tento skript z MQTT serveru brát a dávat do databáze. V tomto příkladu vezme všechny (libovolně hluboce vnořené) položky, které jsou pod základní položkou "sds" (protože v tomto příkladu posílá SDS vše do pod-položek pod názvem /sds/). Dále je podstatné INFLUXDB_DATABASE - určuje to, do jaké specifické databáze se data ukládají. Samozřejmě toto si musíte editovat podle vaší potřeby !

import re
from typing import NamedTuple

import paho.mqtt.client as mqtt
from influxdb import InfluxDBClient

INFLUXDB_ADDRESS = '127.0.0.1'
INFLUXDB_USER = 'mqtt'
INFLUXDB_PASSWORD = 'mqtt'
INFLUXDB_DATABASE = 'sds'

MQTT_ADDRESS = '127.0.0.1'
MQTT_USER = 'mqtt'
MQTT_PASSWORD = 'mqtt'
MQTT_TOPIC = 'sds/+/+'
MQTT_REGEX = 'sds/([^/]+)/([^/]+)'
MQTT_CLIENT_ID = 'MQTTInfluxDBBridge'

influxdb_client = InfluxDBClient(INFLUXDB_ADDRESS, 8086, INFLUXDB_USER, INFLUXDB_PASSWORD, None)

class SensorData(NamedTuple):
    location: str
    measurement: str
    value: float

def on_connect(client, userdata, flags, rc):
    """ The callback for when the client receives a CONNACK response from the server."""
    print('Connected with result code ' + str(rc))
    client.subscribe(MQTT_TOPIC)

def _parse_mqtt_message(topic, payload):
    match = re.match(MQTT_REGEX, topic)
    if match:
        location = match.group(1)
        measurement = match.group(2)
        if measurement == 'status':
            return None
        try:
         return SensorData(location, measurement, float(payload))
        except:
         return None
    else:
        return None

def _send_sensor_data_to_influxdb(sensor_data):
    json_body = [
        {
            'measurement': sensor_data.measurement,
            'tags': {
                'location': sensor_data.location
            },
            'fields': {
                'value': sensor_data.value
            }
        }
    ]
    influxdb_client.write_points(json_body)

def on_message(client, userdata, msg):
    """The callback for when a PUBLISH message is received from the server."""
#    print(msg.topic + ' ' + str(msg.payload))
    sensor_data = _parse_mqtt_message(msg.topic, msg.payload.decode('utf-8'))
    if sensor_data is not None:
        _send_sensor_data_to_influxdb(sensor_data)

def _init_influxdb_database():
    databases = influxdb_client.get_list_database()
    if len(list(filter(lambda x: x['name'] == INFLUXDB_DATABASE, databases))) == 0:
        influxdb_client.create_database(INFLUXDB_DATABASE)
    influxdb_client.switch_database(INFLUXDB_DATABASE)

def main():
    _init_influxdb_database()

    mqtt_client = mqtt.Client(MQTT_CLIENT_ID)
    mqtt_client.username_pw_set(MQTT_USER, MQTT_PASSWORD)
    mqtt_client.on_connect = on_connect
    mqtt_client.on_message = on_message

    mqtt_client.connect(MQTT_ADDRESS, 1883)
    mqtt_client.loop_forever()


if __name__ == '__main__':
    print('MQTT to InfluxDB bridge... SDS OnlineTechnology.cz , AN-D.cz')
    main()


  • Zobrazení

Typicky požadujeme webové, interaktivní zobrazení hodnot a jejich průběhů. Dostupné z místní sítě i z Internetu. Zabezpečené.

To vše nabízí Grafana. Lze ji jednoduše instalovat na server, nakonfigurovat (propojit s databází) a pak si vytvořit zobrazovací obrazovky (Dashboard).

Grafana se konfiguruje především přes vlastní GUI. Zde se držte návodů od autorů Grafana. Podstatné je provést propojení na Influx DB, a pak si vytvořit Dashboardy a do nich jednotlivé grafy.


Home Assistant

SDS lze integrovat (připojit) do systému Home Assistant. Je potřeba do HA nainstalovat vhodnou šablonu, typicky je potřeba si ji vytvořit na míru - příklady jsou na našem fóru.


Další možnosti

Kontaktujte nás s tím, co vás zajímá, a informace sem doplníme.