Përdorimi i TSDuck për monitorimin e IP(TS)-rrjedhave

Aktualisht ekzistojnë zgjidhje të gatshme (proprietare) për monitorimin e rrjedhave IP(TS), për shembull VB dhe iQ, ato kanë një set funksionesh mjaft të pasur dhe zakonisht këto zgjidhje janë të pranishme nga operatorët e mëdhenj që kanë të bëjnë me shërbimet televizive. Artikulli që ndiqni përshkruan një zgjidhje të bazuar në projektin open source TSDuck, e cila është e destinuar për një kontroll minimal të rrjedhave IP(TS) përmes numëruesit CC (counter continuity) dhe bitrate. Një mundësi përdorimi është kontrolli i humbjes së pakove ose të rrjedhës së plotë përmes një kanali L2 të qira (për të cilin nuk ka mundësi monitorimi normal, p.sh. duke lexuar numëruesit e humbjeve në radhë).

Një përmbledhje e shkurtër mbi TSDuck

TSDuck është një program open source (licenca 2-Clause BSD) (një grup utilitarësh konsolë dhe një bibliotekë për zhvillimin e utilitarëve ose plugina të veta) për manipulimin e rrjedhave TS. Si hyrje, mund të punojë me IP (multicast/unicast), http, hls, tunera dvb, demodulatorë dektec dvb-asi, ka një gjenerues të brendshëm të rrjedhës TS dhe lexon nga skedarët. Si dalje, mund të jetë shkarkim në skedar, IP (multicast/unicast), hls, demodulatorë dektec dvb-asi dhe HiDes, lojtarë (mplayer, vlc, xine) dhe drop. Midis hyrjes dhe daljes mund të përfshihen procese të ndryshme të trafikut, për shembull, rimapimi i PID-ve, të bëhen skrambllime/jeskrambllime, analiza e numëruesve CC, llogaritja e bitrate-it dhe operacione të tjera tipike për rrjedhat TS.

Në këtë artikull si hyrje do të përdoren rrjedhat IP (multicast), procese të tilla si bitrate_monitor (siç dallohet nga emri se çfarë është) dhe continuity (analiza e regjistrave CC). Pa ndonjë problem të veçantë mund të zëvendësohet IP multicast me një lloj tjetër hyrjeje, të mbështetur nga TSDuck.

Ka paketa/ndërtime zyrtare TSDuck për shumicën e sistemeve operative aktuale. Për Debian nuk ka, por është arritur të ndërtohet pa probleme për debian 8 dhe debian 10.

PĂ«r mĂ« tepĂ«r, po pĂ«rdoret versioni TSDuck 3.19-1520, duke pĂ«rdorur Linux (pĂ«r pĂ«rgatitjen e zgjidhjes Ă«shtĂ« pĂ«rdorur debian 10, pĂ«r pĂ«rdorimin real — CentOS 7)

Përgatitja e TSDuck dhe OS

Para se tĂ« monitoronim rrjedhat reale, duhet tĂ« sigurohemi se TSDuck funksionon siç duhet dhe nuk ka humbje nĂ« nivelin e kartĂ«s rrjetore ose OS (socket). Kjo Ă«shtĂ« e nevojshme qĂ« mĂ« pas tĂ« mos shohim se ku ndodhin humbjet — nĂ« rrjet ose "brenda serverit". Kontrollimi i humbjeve nĂ« nivelin e kartĂ«s rrjetore mund tĂ« bĂ«het me komandĂ«n ethtool -S ethX, dhe tuning bĂ«het po me atĂ« ethtool (zakonisht, nevojitet tĂ« rritet buferi RX (-G) dhe ndonjĂ«herĂ« tĂ« çaktivizohen disa offloads (-K)). Si njĂ« rekomandim tĂ« pĂ«rgjithshĂ«m mund tĂ« rekomandohet pĂ«rdorimi i njĂ« porte tĂ« veçantĂ« pĂ«r marrjen e trafikut qĂ« po analizohet, nĂ«se ka njĂ« mundĂ«si tĂ« tillĂ«, kjo minimizon sinjalizimet false qĂ« lidhen me faktin se humbja ndodhi konkretisht nĂ« portin e analizatorit pĂ«r shkak tĂ« trafikut tjetĂ«r. NĂ«se njĂ« mundĂ«si e tillĂ« nuk ekziston (nĂ«se pĂ«rdoret njĂ« mini-kompjuter/NUC me njĂ« port), atĂ«herĂ« Ă«shtĂ« shumĂ« e dĂ«shirueshme tĂ« konfigurohet prioriteti i trafikut qĂ« po analizohet nĂ« raport me tĂ« tjerĂ«t nĂ« pajisjen ku Ă«shtĂ« lidhur analizatori. Sa i pĂ«rket mjediseve virtuale, kĂ«tu duhet tĂ« jemi tĂ« kujdesshĂ«m dhe tĂ« dimĂ« si tĂ« gjejmĂ« humbjet e pakove nga porta fizike deri te aplikacioni brenda makinerisĂ« virtuale.

Gjatë gjenerimit dhe marrjes së rrjedhës brenda hostit

Si një hap të parë përgatitës TSDuck, do të gjenerojmë dhe marrim trafik brenda një hosti duke përdorur netns.

Përgatitja e mjedisit:

ip netns add P #krijojmë netns P, në të cilin do të ndodhi analiza e trafik
ip link add type veth #krijojmë një çift veth - veth0 e lëmë në netns të paracaktuar (në këtë ndërfaqe do të gjenerohet trafiku)
ip link set dev veth1 netns P #veth1 - e vendosim në netns P (në këtë ndërfaqe do të ndahet trafiku)
ip netns exec P ifconfig veth1 192.0.2.1/30 up #aktivizojmë IP në veth1, nuk ka rëndësi se cila është
ip netns exec P ip ro add default via 192.0.2.2 #konfigurojmë një rregull të paracaktuar brenda netns P
sysctl net.ipv6.conf.veth0.disable_ipv6=1 #çaktivizojmë IPv6 në veth0 - kjo bëhet në mënyrë që në numëruesin TX të mos përfshihet ndonjë papastërti e huaj
ifconfig veth0 up #aktivizojmë ndërfaqen veth0
ip route add 239.0.0.1 dev veth0 #krijojmë një rregull, që OS ta drejtojë trafikun te 239.0.0.1 në drejtim te veth0

Mjedisi është i gatshëm. Aktivizojmë analizuesin e trafikut:

ip netns exec P tsp --realtime -t 
 -I ip 239.0.0.1:1234 
 -P continuity 
 -P bitrate_monitor -p 1 -t 1 
 -O drop

ku "-p 1 -t 1" do të thotë se duhet të llogaritet bitrate çdo sekondë dhe të tregojë informacion mbi bitrate çdo sekondë
Aktivizojmë gjeneratorin e trafik me shpejtësi 10Mbit/s:

tsp -I craft 
 -P regulate -b 10000000 
 -O ip -p 7 -e --local-port 6000 239.0.0.1:1234

ku "-p 7 -e" do të thotë, se duhet paketuar 7 paketa TS në 1 paketë IP dhe kjo duhet të bëhet ngushtë (-e), dmth. gjithmonë të pritet 7 paketa TS nga procesori më i fundit para dërgimit të formës IP.

Analizuesi fillon të nxjerrë mesazhet e pritura:

* 2020/01/03 14:55:44 - bitrate_monitor: 2020/01/03 14:55:44, TS bitrate: 9,970,016 bits/s
* 2020/01/03 14:55:45 - bitrate_monitor: 2020/01/03 14:55:45, TS bitrate: 10,022,656 bits/s
* 2020/01/03 14:55:46 - bitrate_monitor: 2020/01/03 14:55:46, TS bitrate: 9,980,544 bits/s

Tani tani po shtojmë disa drop-e:

ip netns exec P iptables -I INPUT -d 239.0.0.1 -m statistic --mode random --probability 0.001 -j DROP

dhe shfaqen mesazhe të tilla:

* 2020/01/03 14:57:11 - continuity: packet index: 80,745, PID: 0x0000, missing 7 packets
* 2020/01/03 14:57:11 - continuity: packet index: 83,342, PID: 0x0000, missing 7 packets 

çka Ă«shtĂ« e pritshme. Çlironi humbjen e paketave (ip netns exec P iptables -F) dhe pĂ«rpiquni tĂ« rrisni bitratĂ«n e gjeneratorit nĂ« 100Mbit/s. Analizatori raporton njĂ« sasi tĂ« madhe gabimesh CC dhe rreth 75 Mbit/s nĂ« vend tĂ« 100. KĂ«rkojmĂ« tĂ« kuptojmĂ« kush Ă«shtĂ« fajtor — a Ă«shtĂ« gjeneratori ngadalĂ«, apo problemi nuk Ă«shtĂ« te ai, prandaj nisĂ«m gjenerimin e njĂ« numri tĂ« caktuar paketash (700000 TS-paketash = 100000 IP-paketash):

# ifconfig veth0 | grep TX
       TX packets 151825460  bytes 205725459268 (191.5 GiB)
        TX errors 0  dropped 0 overruns 0  carrier 0  collisions 0
# tsp -I craft -c 700000 -P regulate -b 100000000 -P count -O ip -p 7 -e --local-port 6000 239.0.0.1:1234
* count: PID    0 (0x0000):    700,000 packets
# ifconfig veth0 | grep TX
        TX packets 151925460  bytes 205861259268 (191.7 GiB)
        TX errors 0  dropped 0 overruns 0  carrier 0  collisions 0

Siç duket, u gjeneruan saktësisht 100000 IP-pakete (151925460-151825460). Kështu që hedhim një vështrim se çfarë ndodh me analizin, duke krahasuar me numëruesin RX në veth1, e cila është e barabartë me numëruesin TX në veth0, pastaj shohim se çfarë ndodh në nivelin e soketit:

# ip netns exec P cat /proc/net/udp                                                                                                           
  sl  local_address rem_address   st tx_queue rx_queue tr tm->when retrnsmt   uid  timeout inode ref pointer drops             
  133: 010000EF:04D2 00000000:0000 07 00000000:00000000 00:00000000 00000000     0        0 72338 2 00000000e0a441df 24355 

Këtu shihet numri i drop-eve = 24355. Në TS-paketat kjo është 170485 ose 24.36% nga 700000, kështu që shohim se ato 25% të bitratës së humbur janë drop-e në soketin UDP. Drop-et në soketin UDP zakonisht ndodhin për shkak të mungesës së buffers, shohim se çfarë është madhësia e buffer-it të soketit për default dhe madhësia maksimale e buffer-it të soketit:

# sysctl net.core.rmem_default
net.core.rmem_default = 212992
# sysctl net.core.rmem_max
net.core.rmem_max = 212992

Pra, nĂ«se aplikacionet nuk kĂ«rkojnĂ« madhĂ«sinĂ« e buffer-it nĂ« mĂ«nyrĂ« tĂ« qartĂ«, soketet krijohen me njĂ« buffer tĂ« madhĂ«sisĂ« 208 Kb, por nĂ«se kĂ«rkojnĂ« mĂ« shumĂ«, sĂ«rish nuk do tĂ« marrin atĂ« qĂ« kĂ«rkojnĂ«. Duke qenĂ« se nĂ« tsp pĂ«r IP-hyrje mund tĂ« caktoni madhĂ«sinĂ« e buffer-it (—buffer-size), nuk do ta prekim madhĂ«sinĂ« e default-it tĂ« soketit, por vetĂ«m do tĂ« vendosim madhĂ«sinĂ« maksimale tĂ« soketit dhe do tĂ« caktojmĂ« madhĂ«sinĂ« e buffer-it nĂ« mĂ«nyrĂ« tĂ« qartĂ« pĂ«rmes argumenteve tsp:

sysctl net.core.rmem_max=8388608
ip netns exec P tsp --realtime -t -I ip 239.0.0.1:1234 -b 8388608 -P continuity -P bitrate_monitor -p 1 -t 1 -O drop

Me një tuning të tillë të buffer-it të soketit, tani bitrate-i i raportuar është rreth 100Mbit/s, nuk ka gabime CC.

PĂ«r konsumimin e CPU nga vetĂ« aplikacioni tsp. NĂ« lidhje me njĂ« bĂ«rthamĂ« i5-4260U CPU @ 1.40GHz, pĂ«r analizĂ«n e fluxit 10Mbit/s do tĂ« kĂ«rkohet 3-4% CPU, 100 Mbit/s — 25%, 200Mbit/s — 46%. Kur caktohet % tĂ« humbjes sĂ« paketave, ngarkesa nĂ« CPU praktikisht nuk rritet (por mund tĂ« pakĂ«sohet).

Në pajisje më produktive, është arritur të gjenerohen dhe analizohet pa probleme fluxe mbi 1Gb/s.

Testimi në karta rrjeti reale

Pas testimit në çiftin veth, duhet të merrni dy hoste ose dy porte të një hosti, t'i lidhni portet me njëra-tjetrën, të nisni gjeneratorin në njërin dhe analizin në tjetrin. Këtu nuk ndodhi asnjë befasi, por në të vërtetë gjithçka varet nga hardueri, sa më i dobët të jetë, aq më interesant do të jetë.

Përdorimi i të dhënave të marra nga sistemi i monitorimit (Zabbix)

Tsp nuk ka ndonjë API të lexueshëm nga makina si SNMP apo ndonjë gjë të ngjashme. Mesazhet CC duhet të mblidhen të paktën çdo 1 sekondë (në përqindje të lartë të humbjes së paketave, ato mund të jenë qindra/mijëra/dhjetëra mijëra në sekondë, varet nga bitrate).

Pra, për të ruajtur informacionin dhe për të vizatuar grafikët e gabimeve CC dhe bitrate, dhe për të bërë disa alarmet më tej, ndonjëra nga opsionet e mëposhtme mund të përdoren:

  1. Të parse dhe të agregoni (sipër CC) daljen e tsp, dmth ta transformoni atë në formën e nevojshme.
  2. Të përmirësoj veten tsp dhe/ose procesorët e pluginëve bitrate_monitor dhe continuity, që rezultati të jepet në formë të lexueshme nga makina, të përshtatshme për sistemin e monitorimit.
  3. Të shkruaj aplikacionin tim mbi bibliotekën tsduck.

E qartë se nga pikëpamja e shpërndarjes së punës, opsioni 1 është më i thjeshtë, veçanërisht duke marrë parasysh se vetë tsduck është shkruar në një gjuhë të nivelit të ulët (për standardet moderne) (C++)

Një prototip i thjeshtë parser+aggregator në bash tregoi se në fluxin 10Mbit/s dhe 50% humbje paketash (më e keqja), procesi bash konsumonte 3-4 herë më shumë CPU sesa vetë procesi tsp. Ky opsion për zhvillimin e ngjarjeve është i papranueshëm. Në thelb, një pjesë e këtij prototipi është më poshtë

Pjesë në bash

#!/usr/bin/env bash

missingPackets=0
ccErrorSeconds=0
regexMissPackets='^* (.+) - continuity:.*missing ([0-9]+) packets$'
missingPacketsTime=""

ip netns exec P tsp --realtime -t -I ip -b 8388608 "239.0.0.1:1234" -O drop -P bitrate_monitor -p 1 -t 1  -P continuity 2>&1 | 
while read i
do
    #line example:* 2019/12/28 23:41:14 - continuity: packet index: 6,078, PID: 0x0100, missing 5 packets
    #line example 2: * 2019/12/28 23:55:11 - bitrate_monitor: 2019/12/28 23:55:11, TS bitrate: 4,272,864 bits/s
    if [[ "$i" == *continuity:* ]] 
    then
        if [[ "$i" =~ $regexMissPackets ]]
        then
            missingPacketsTimeNew="${BASH_REMATCH[1]}" #timestamp (seconds)
            if [[ "$missingPacketsTime" != "$missingPacketsTimeNew" ]] #new second with CC error
            then
                ((ccErrorSeconds += 1))
            fi
            missingPacketsTime=$missingPacketsTimeNew
            packets=${BASH_REMATCH[2]} #TS missing packets
            ((missingPackets += packets))
        fi
    elif [[ "$i" == *bitrate_monitor:* ]]
    then
        : #...
    fi
done

Përveç faktit se kjo funksionon të papranueshëm ngadalë, në bash mungojnë fijet e duhura, punët e bash janë procese të pavarura dhe duhej të bëja regjistrimin çdo sekondë të vlerës missingPackets në efektin anësor (kur merr mesazhin për bitrate, i cili vjen çdo sekondë). Si rezultat, bash u la në hir dhe u vendos të shkruaja një mbështjellës (parser+aggregator) në golang. Konsumi i CPU i kodit të ngjashëm në golang është 4-5 herë më pak se vetë procesi tsp. Shpejtësia e mbështjellësit përmes zëvendësimit të bash me golang është rreth 16 herë dhe në përgjithësi rezultati është i pranueshëm (overhead në CPU është 25% në rastin më të keq). Skedari burimor në golang ndodhet këtu.

Nisja e mbështjellësit

Për të nisur mbështjellësin është krijuar një model i thjeshtë shërbimi për systemd (këtu). Supozohet se mbështjellësja vetë është kompiluara në një skedar binar (go build tsduck-stat.go), e vendosur në /opt/tsduck-stat/. Supozohet se përdoret golang me mbështetje për clock monotonic (>=1.9).

Për të krijuar një instancë shërbimi, duhet të ekzekutoni komandën systemctl enable tsduck-stat@239.0.0.1:1234, pastaj të nisim me systemctl start tsduck-stat@239.0.0.1:1234.

Zbulimi nga Zabbix

QĂ« Zabbix tĂ« mund tĂ« bĂ«jĂ« zbulimin e shĂ«rbimeve tĂ« nisura, Ă«shtĂ« krijuar gjeneratori i listĂ«s sĂ« grupeve (discovery.sh), nĂ« formatin e nevojshĂ«m pĂ«r zbulim nga Zabbix, supozohet se Ă«shtĂ« vendosur po atje — nĂ« /opt/tsduck-stat. PĂ«r tĂ« ekzekutuar zbulimin pĂ«rmes zabbix-agent, duhet tĂ« shtoni .conf-file nĂ« direktorinĂ« me konfigurimet e zabbix-agent’it pĂ«r tĂ« shtuar parametrin e pĂ«rdoruesit.

Shablloni Zabbix

Shablloni i krijuar (tsduck_stat_template.xml) përmban rregullin për zbulimin automatik, prototipet e elementeve të të dhënave, grafikët dhe trigger-at.

Lista e shkurtër e kontrollit (në rast se ndokush vendos të përdorë)

  1. Sigurohuni që tsp nuk hedh paketa në kushtet «të përsosura» (generatori dhe analizuesi janë lidhur drejtpërdrejt), nëse ka hedhje shih p.2 ose tekstin e artikullit për këtë çështje.
  2. Bëni optimizimin e maksimumit të tamponit të soketit (net.core.rmem_max=8388608).
  3. Kompiloni tsduck-stat.go (go build tsduck-stat.go).
  4. Vendosni shabllonin e shërbimit në /lib/systemd/system.
  5. Nisni shërbimet me sistemctl, kontrolloni që të fillojnë të shfaqen numëruese (grep «» /dev/shm/tsduck-stat/*). Numri i shërbimeve për aq sa numri i rrjedhave multicast. Këtë mund të kenë nevojë të krijoni një rrugë deri te grupi multicast, ndoshta të çaktivizoni rp_filter ose të krijoni një rrugë deri te IP e burimit.
  6. Ekzekutoni discovery.sh, sigurohuni që ai gjeneron json.
  7. Shtoni konfigurimin e zabbix-agentit, restart zabbix-agent.
  8. Ngarko shabllonin në zabbix, aplikoni atë për hostin mbi të cilin monitorohet dhe është instaluar zabbix-agent, prisni rreth 5 minuta, kontrolloni që janë shfaqur elemente të reja të dhënash, grafikë dhe trigger-a.

Rezultati

Përdorimi i TSDuck për monitorimin e IP(TS)-rrjedhave

Për detyrën e identifikimit të humbjeve të paketave, kjo është pothuajse e mjaftueshme, përndryshe është më mirë se tjetra.

Në të vërtetë, CC-«humbjet» mund të ndodhin gjatë ngjitjes së fragmenteve të videos (sa di unë, kështu bëhen inserte në qendrat televizive lokale në RF, dmth pa ri-kontabilizimin e numëruesit CC), kjo duhet mbajtur në mend. Në zgjidhjet pronësore, ky problem ndihmohet pjesërisht duke zbuluar etiketat SCTE-35 (nëse ato shtohen nga gjeneratori i rrjedhës).

Nga pikëpamja e monitorimit të cilësisë së transportit, mungon monitorimi i jitter (IAT), pasi pajisjet televizive (qoftë moduluesit apo pajisjet përfundimtare) kanë kërkesa për këtë parametër dhe nuk është gjithmonë e mundur të zgjerohet jitbuffer deri në pafundësi. Dhe jitteri mund të shkojë në mënyrë jokontrolluar kur në transit përdoren pajisje me tampona të mëdha dhe QoS për transmetimin e trafikut të tillë realtime nuk është rregulluar ose nuk është rregulluar mjaft mirë.

Burimi: habr.com

Bleni hostim tĂ« besueshĂ«m pĂ«r faqe me mbrojtje nga DDoS, serverĂ« VPS VDS đŸ”„ Bleni hostim tĂ« besueshĂ«m pĂ«r faqe me mbrojtje nga DDoS, serverĂ« VPS VDS | ProHoster