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

Sotërim sot janë zgjidhje të gatshme (proprietare) për monitorimin e rrjedhave IP(TS), për shembull VB dhe iQ, ato disponojnë një set të pasur funksionesh dhe zakonisht zgjidhjet e tilla janë në dispozicion nga operatorët e mëdhenj që merret me shërbimet TV. Ky artikull përshkruan një zgjidhje të bazuar në projektin open source TSDuck, i cili është i destinuar për kontrollin minimal të rrjedhave IP(TS) përmes numërtarit CC (continuity counter) dhe bit rate-it. Një variant i mundshëm aplikimi është kontrollimi i humbjes së paketave ose tërë rrjedhës përmes një kanali L2 të marrë me qira (së cilës nuk është e mundur të monitorohet normalisht, për shembull duke lexuar numëruesit e humbjes në radhë).

Shumë shkurt rreth TSDuck

TSDuck është një software open source (licenca 2-Clause BSD) (grup utilitësh konsolë dhe bibliotekë për zhvillimin e utilitëve ose plugin-eve të tij) për manipulimin me rrjedhat TS. Si hyrje, mund të punojë me IP (multicast/unicast), http, hls, tunerë dvb, demodulatorin dektec dvb-asi, ka një gjenerues të brendshëm TS dhe lexon nga skedarët. Si dalje, mund të regjistrojë në skedar, IP (multicast/unicast), hls, demodulatorët dektec dvb-asi dhe HiDes, lojtarë (mplayer, vlc, xine) dhe drop. Ndërmjet hyrjes dhe daljes, mund të përfshihen procesorë të ndryshëm të trafikut, për shembull, rimapimi i PID-eve, skremblimi/deskremblimi, analiza e numëruesve CC, llogaritja e bit rate-it dhe operacione të tjera tipike për rrjedhat TS.

Në këtë artikull, si hyrje do të përdoren rrjedhat IP (multicast), procesorët bitrate_monitor (nga emri është e qartë se çfarë është) dhe continuity (analiza e numëruesve 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 ndërtime/paketa zyrtare TSDuck për shumicën e sistemeve operuese aktuale. Për Debian nuk ka, por u arrit të ndihmohej lehtësisht për debian 8 dhe debian 10.

Më pas, përdoret versioni TSDuck 3.19-1520, sistemi operativ është Linux (për përgatitjen e zgjidhjes u përdor debian 10, për përdorim real — CentOS 7)

Përgatitja e TSDuck dhe OS

Para të monitoroni flukset reale, duhet të siguroheni që TSDuck funksionon siç duhet dhe të mos ketë rënie në nivelin e kartelës rrjetore ose OS (socket). Kjo është e nevojshme në mënyrë që më vonë të mos spekulojmë se ku ndodhi rënia - në rrjet ose "brenda serverit". Përdorni komandën ethtool -S ethX për të kontrolluar rëniet në nivelin e kartelës rrjetore; rregullimi bëhet gjithashtu me ethtool (zakonisht, nevojitet rritja e RX-buffer (-G) dhe ndonjëherë çaktivizimi i disa offloads (-K)). Si një rekomandim të përgjithshëm, mund të sugjerohet përdorimi i një porte të veçantë për marrjen e trafikut të analizuar, nëse ka një mundësi të tillë, kjo minimizon ndjeshmeritë e gabuara që lidhen me rëniet që ndodhin direkt në portin e analizuesit për shkak të trafikut tjetër. Nëse nuk ka një mundësi të tillë (përdoret një mini-kompjuter/NUC me një port), atëherë është shumë e dëshirueshme të konfigurohet prioritizimi i trafikut të analizuar në krahasim me trafikun e tjerë në pajisjen e lidhur me analizuesin. Në lidhje me ambientet virtuale, këtu duhet të jeni të kujdesshëm dhe të dini si të gjeni rëniet e paketave duke filluar nga porta fizike dhe duke përfunduar me aplikacionin brenda makinës virtuale.

Gjene dhe pranimi i fluksit brenda hostit

Si hapin e parë në përgatitjen e TSDuck, do të gjenerojmë dhe marrim trafik brenda një hosti duke përdorur netns.

Përgatitja e ambientit:

ip netns add P #krijojmë netns P, në të cilin do të kryhet analiza e trafikut
ip link add type veth #krijojmë një çift veth - veth0 e lëmë në netns-në e paracaktuar (në këtë ndërfaqe do të gjenerohet trafik)
ip link set dev veth1 netns P #veth1 - vendosim në netns P (në këtë ndërfaqe do të pranohet trafiku)
ip netns exec P ifconfig veth1 192.0.2.1/30 up #ngre IP-në në veth1, nuk ka rëndësi se cila është saktësisht
ip netns exec P ip ro add default via 192.0.2.2 #konfigurojmë rrugën e 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 futen mbeturina të huaja
ifconfig veth0 up #ngre ndërfaqen veth0
ip route add 239.0.0.1 dev veth0 #krijojmë një rrugë në mënyrë që OS të drejtojë trafikun në 239.0.0.1 në drejtim të veth0

Ambientet janë gati. Nisim 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ë jepet informacion mbi bitrate në çdo sekondë
Nisim gjeneruesin e trafikut 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 të paketohen 7 paketa TS në 1 paketë IP dhe të bëhet kjo me fortësi (-e), pra të pritet gjithmonë 7 paketa TS nga procesori i fundit përpara se të dërgohet formimi i paketës IP.

Analizatori fillon të shfaqë 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 shtojmë pak droga:

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, mungojnë 7 paketa
* 2020/01/03 14:57:11 - continuity: packet index: 83,342, PID: 0x0000, mungojnë 7 paketa 

që është e pritur. Çdoimë humbjen e paketave (ip netns exec P iptables -F) dhe përpiqemi të rrisim bitrate-in e gjeneratorit në 100Mbit/s. Analizatori raporton shumë gabime CC dhe rreth 75 Mbit/s në vend të 100. Po përpiqemi të kuptojmë kush është fajtori — a është gjeneratori që nuk arrin ose problemi nuk është te ai, ndaj aktivizojmë gjenerimin e një sasi fikse paketash (700000 paketa TS = 100000 paketa IP):

# 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 paketa IP (151925460-151825460). Pra, po shqyrtojmë se çfarë ndodh me analizanin, për këtë krahasoni me numëruesin RX në veth1, ai është saktësisht i barabartë me numëruesin TX në veth0, pastaj shikoni se çfarë ndodh në nivelin e soketëve:

# 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 drogave = 24355. Në paketat TS, kjo është 170485 ose 24.36% nga 700000, kështu që shohim se ato 25% të humbjes së bitrate-it janë droga në soket-in udp. Droga në soketin UDP zakonisht ndodhin për shkak të mungesës së buffer-it, shikoni se çfarë është madhësia e buffer-it të soketëve sipas parazgjedhjes dhe madhësia maksimale e buffer-it të soketëve:

# 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 të qartë, soketët krijohen me një buffer prej 208 KB, por nëse kërkojnë më shumë, përsëri nuk do të marrin atë që kërkojnë. Duke qenë se në tsp për IP-hyrjen mund të caktohet madhësia e buffer-it (—buffer-size), atëherë nuk do ta prekëm madhësinë e soketëve sipas parazgjedhjes, por thjesht do të caktojmë madhësinë maksimale të buffer-it të soketëve dhe do të specifikojmë madhësinë e buffer-it 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 këtë rregullim të buffer-it të soketëve tani bitrate-i i raportuar është rreth 100Mbit/s, nuk ka gabime CC.

Për konsumimin e CPU nga vetë aplikacioni tsp. Për një bërthamë i5-4260U CPU @ 1.40GHz, për analizën e një rrjedhe 10Mbit/s do të nevojiten 3-4% CPU, për 100 Mbit/s — 25%, 200Mbit/s — 46%. Duke caktuar % të humbjeve të pakot, ngarkesa në CPU praktikisht nuk rritet (por mund të zvogëlohet).

Me hardware më të fuqishëm, arritëm të gjeneronim dhe analizojmë rrjedha mbi 1Gb/s pa probleme.

Testimi në kartat rrjetike reale

Pas testimit në çiftin veth, nevojitet të marrë dy hoste ose dy porta të një hosti, të lidhim portat midis tyre, në një të nisnim gjeneratorin, në tjetrin analizuesin. Këtu nuk ndodhi ndonjë papritur, por në të vërtetë gjithçka varet nga hardware-i; sa më i dobët të jetë, aq më interesante do të jetë.

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

Tsp nuk ka ndonjë API machine-readable si SNMP ose të ngjashme. Mesazhet CC duhet të mblidhen të paktën çdo 1 sekondë (në rast të një përqindjeje të lartë të humbjes së pakove, ato mund të arrijnë në qindra/mijëra/dhjetëra mijëra çdo sekondë, në varësi të bitrates).

Kështu, për të ruajtur informacionin dhe për të vizatuar grafike për gabimet CC dhe bitrate-in dhe për të bërë ndonjë katastrofë më tutje, mund të ketë këto opsione:

  1. Të parse dhe të agregojmë (sipëro CC) daljen e tsp, domethënë, ta tërheqim atë në formatin e nevojshëm.
  2. Të modifikojmë veten tsp dhe/ose pluginët procesorë bitrate_monitor dhe continuity, për të siguruar që rezultati jepet në formë machine-readable, e përshtatshme për sistemin e monitorimit.
  3. Të shkruajmë aplikacionin tonë mbi bibliotekën tsduck.

Qartë është se nga pikëpamja e kostos së punës, opsioni 1 është më i lehti, sidomos duke marrë parasysh se vetë tsduck është shkruar në një gjuhë të nivelit të ulët (në standartet moderne) (C++)

Një prototip i thjeshtë i parser-it + agregatorit në bash tregoi se në një rrjedhë 10Mbit/s dhe 50% humbje pakosh (variantet më të këqija), procesi bash konsumonte 3-4 herë më shumë CPU se vetë procesi tsp. Ky variant i situatës është i papranueshëm. Në thelb pjesa e këtij prototipi është më poshtë.

Makarona 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 funksionon tepër ngadalë, bash-i nuk ka thurje normale; punët e bash-it janë procese të pavarur dhe duhet të shkruajmë një herë në sekondë vlerën e missingPackets në efektin anësor (në marrjen e mesazheve për bitratin, të cilat vijnë çdo sekondë). Si përfundim, bash-i u la në paqe dhe u vendos të shkruhet një mbështjellës (parser + agregator) në golang. Konsumi i CPU-t të kodit të ngjashëm në golang është 4-5 herë më i ulët se ai i procesit tsp. Shpejtësia e mbështjellësit, për shkak të zëvendësimit të bash-it me golang, rezultoi të ishte rreth 16 herë më e mirë dhe në përgjithësi rezultati është i pranueshëm (overhead në CPU në 25% në rastin më të keq). Skedari origjinal në golang ndodhet këtu.

Fillimi i mbështjellësit

Për të filluar mbështjellësin është bërë një model i thjeshtë shërbimi për systemd (këtu). Supozohet se mbështjellësi vetë është kompiluar në një skedhë binare (go build tsduck-stat.go) dhe është vendosur në /opt/tsduck-stat/. Supozohet se përdoret golang me mbështetje për orën monotone (>=1.9).

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

Zbulimi nga Zabbix

Për të bërë që zabbix të mund të zbulojë shërbimet e nisura, është krijuar një gjenerator liste grupesh (discovery.sh), në formatin e nevojshëm për zbulimin e Zabbix-it, supozohet se është vendosur po aty — në /opt/tsduck-stat. Për të ekzekutuar zbulimin përmes zabbix-agentit, duhet të shtoni .conf-file në direktorinë e konfigurimeve të zabbix-agentit për të shtuar parametrin e përdoruesit.

Shabloni Zabbix

Shabloni i krijuar (tsduck_stat_template.xml) përmban rregullin e autodiskovrimit, prototipat e elementeve të të dhënave, grafikët dhe triggerët.

Kontrolli i shpejtë (në rast se ndokush do të vendosë ta përdorë)

  1. Sigurohuni që tsp nuk hedh paketa në kushte "ideale" (gjeneratori dhe analizatori janë të lidhur drejtpërdrejt), nëse ka hedhje, shihni p.2 ose tekstin e artikullit për këtë.
  2. Bëni optimizimin e tamponit maksimal të soketeve (net.core.rmem_max=8388608).
  3. Kompiloni tsduck-stat.go (go build tsduck-stat.go).
  4. Vendosni shablonin e shërbimit në /lib/systemd/system.
  5. Filloni shërbimet përmes systemctl, kontrolloni se kanë filluar të shfaqen në numërues (grep "" /dev/shm/tsduck-stat/*). Numri i shërbimeve është në përputhje me numrin e rrjedhave multicast. Këtu mund të jetë e nevojshme të krijoni një rrugë deri te grupi multicast, ndoshta të çaktivizoni rp_filter ose të krijoni një rrugë deri te ip burim.
  6. Ekzekutoni discovery.sh, sigurohuni që ai gjeneron json.
  7. Vendosni configurimin e zabbix-agentit, ri-startoni zabbix-agentin.
  8. Ngarko një template në Zabbix, aplikoni atë në hostin ku monitorohet dhe është instaluar zabbix-agent, prisni rreth 5 minuta dhe shikoni që elementët e rinj të të dhënave, grafiket dhe trigjerët kanë dalë.

Rezultati

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

Për detyrën e identifikimit të humbjes së paketimeve, është pothuajse e mjaftueshme, përveç që është më mirë se mosmonitorimi.

Në të vërtetë, CC-«humbjet» mund të ndodhin gjatë bashkimit të fragmenteve të videos (sipas asaj që di, kështu bëhen inserte në qendrat lokale të televizionit në RF, dmth pa llogaritur numëruesin CC), duhet ta mbani mend këtë. Në zgjidhjet proprietare kjo problematikë kalojë pjesërisht përmes zbulimit të etiketave SCTE-35 (nëse ato shtohen nga gjeneratori i fluxit).

Nga pikëpamja e monitorimit të cilësisë së transportit, mungon monitorimi i jitter (IAT), pasi pajisjet televizive (qoftë modulatorë ose pajisje përfundimtare) kanë kërkesa për këtë parameter dhe nuk është gjithmonë e mundur të rritet jitbuffer deri në pafundësi. Dhe jitteri mund të ndryshojë kur gjatë tranzitit përdoren pajisje me buferë të mëdhenj dhe QoS për transmetimin e tillë të trafikut realtime nuk është konfiguruar ose nuk është mjaft mirë i konfiguruar.

Burimi: habr.com

Blini hostim të besueshëm për faqe interneti me mbrojtje DDoS, serverë VPS VDS 🔥 Blini hostim të besueshëm për faqe interneti me mbrojtje DDoS, serverë VPS VDS - ProHoster