Multicast(at)Work er et web-grensesnitt for iperf 2 og ping. Det kontrollerer at et nettverk fører unicast og multicast riktig, og finner største pakkestørrelse (MTU) på en vei gjennom nettet. Programmet installeres offline på Rocky Linux 9, i VMware og i Proxmox VE, og kjører som én systemd-tjeneste uten Docker. Dokumentet beskriver arkitekturen, hvordan testene kjøres, sikkerhetsmekanismene, installasjonsmodellen og grensesnittene, og er skrevet for drift, sikkerhetsgjennomgang og videreutvikling.
1. Formål og omfang
Produkt |
Multicast(at)Work 3.0.0 |
Komponenter |
Web-GUI ( |
Bruksområde |
Kontroll av multicast i og mellom VLAN (IGMP-join, snooping, querier, PIM og TTL), unicast-gjennomstrømning som grunnlinje, og MTU for en sti (jumborammer, tunneler, PPPoE) |
Ikke formål |
Kontinuerlig overvåking, lastgenerering i produksjonsnett eller måling over IPv6 |
Målplattformer |
Rocky Linux 9 / RHEL 9 / AlmaLinux 9 / Oracle Linux 9 (primær) og VMware Photon OS, på fysisk maskin, som VM i VMware eller Proxmox VE, eller som LXC-container i Proxmox VE. x86_64 og aarch64. |
Kjøremodell |
Én Flask-applikasjon under waitress, styrt av systemd, som starter iperf og ping som egne prosesser. Ingen containere, ingen pip, ingen EPEL, ingen internettilgang. |
Språk |
Engelsk og norsk (bokmål) i web-grensesnitt, logglinjer, feilmeldinger, brukermanual og installasjonsskript |
Lisens |
MIT |
2. Arkitektur
2.1. Oversikt
Nettleser (administrator) │ HTTP :5152, innloggingsside (signert sesjonskapsel) eller Basic Auth, │ X-Requested-With: mct på alle POST ▼ waitress 3.0 + Flask 3.1 (app.py, i18n.py) bruker mct (ikke root) │ CAP_NET_RAW, CAP_NET_ADMIN │ økter i minnet: id → prosesser, logg, status │ hver kommando i egen prosessgruppe, uten skall ├─ /opt/multicast-tester/bin/iperf -s … mottaker (TCP og/eller UDP-gruppe) ├─ /opt/multicast-tester/bin/iperf -c … sender (TCP / UDP-multicast) ├─ ping -M do|want -s N … ping og MTU-test └─ ip -4 -o addr adresser til nettkortlista ▼ Nettkort ── IGMP join/leave, UDP-strøm, TCP, ICMP ──▶ testnettet ◀── andre installasjoner / iperf 2
2.2. Kodemoduler
| Fil | Innhold |
|---|---|
|
Flask-applikasjonen: ruter, autentisering, CSRF-kontroll, sikkerhetshoder, validering, øktstyring, kjøring av iperf og ping, MTU-testen, språkvalg, lisens- og manualsider |
|
Norske oversettelser (engelsk er nøkkelen) og tekstene som sendes til JavaScript |
|
|
|
Bootstrap 5.3.8 (bare CSS), |
|
Brukermanualen som HTML, bygget fra |
|
iperf 2.2.1 for x86_64 og aarch64, lisenstekster og |
|
Felles skallfunksjoner: språk, utskrift, plattformgjenkjenning, valg av iperf for CPU-en |
|
Selvtest mot en installert server (bare standardbiblioteket) |
2.3. Prosessmodell og rettigheter
| Prosess | Bruker | Rettigheter |
|---|---|---|
|
|
|
|
|
Arver de to rettighetene. |
Hver kommando startes med start_new_session=True, altså i sin egen prosessgruppe. Stopp sender SIGTERM til gruppa og SIGKILL etter to sekunder. Når tjenesten stoppes, gjør KillMode=control-group det samme for alle prosessene.
3. Testverktøyene
3.1. Mottaker
| Modus | Kommandoer (parallelt) |
|---|---|
Begge |
|
Bare TCP |
|
UDP / multicast |
|
-B gruppe%nettkort får iperf til å melde seg inn i gruppa (IGMP join) på det valgte nettkortet. Uten nettkort brukes nettkortet til standardruta. Mottakeren kjører til den stoppes. -i 1 gir én linje per sekund med båndbredde, jitter og tapte/mottatte datagrammer.
3.2. Sender
Stegene kjøres etter hverandre. Et steg som feiler, stopper ikke de neste.
-
ping -n -c 5 [-I IF] U -
iperf -c U -p P -t T -i 1 -
iperf -u -c G[%IF] -p P -t T -T TTL -b B -i 1
TTL (1–255) bestemmer hvor mange rutere multicast kan passere. Båndbredden -b er tall med valgfri k, M eller G.
3.3. MTU-test
-
En vanlig ping (
-c 2 -W 2). Svarer ikke målet, stopper testen med en forklaring. -
For hver størrelse S (29–9216 byte, maks 1000 størrelser, sortert og uten duplikater):
ping -n -c 1 -W 2 -M do|want -s S-28 [-I IF] mål. 28 byte er IP- og ICMP-hodet. -
Utdata tolkes: svar (✓ med rtt),
message too long, mtu=N(større enn eget nettkort),frag needed(for stor for stien), ingen svar, tidsavbrudd, ukjent vert. -
Med DF på er den største størrelsen som fikk svar, MTU for stien. Med DF av står det tydelig at resultatet ikke er MTU-en. Feiler mindre størrelser enn den største som virket, varsles det om inkonsistente resultater.
3.4. Økter og logger
-
En økt er en mottaker, en sender eller en MTU-test. Den har en UUID, type, etikett, språk, prosessliste, logg og status.
-
Hver logglinje får tidsstempel. Loggen begrenses til
MCT_MAX_LOG_LINESlinjer; de eldste fjernes, og forskyvningen i API-et tar hensyn til det, så nettleseren aldri mister eller dobler linjer. -
Ferdige økter slettes etter
MCT_SESSION_TTLsekunder. Er detMCT_MAX_SESSIONSøkter, slettes de eldste ferdige først. Er alle i gang, svarer API-et 429. -
Nettleseren spør etter nye linjer hvert 0,8 sekund (
/api/log/<id>?offset=N). Når forsiden åpnes, henter den/api/sessionsog kobler seg til den nyeste kjørende økta av hver type./api/sessionshentes deretter hvert 3. sekund for fanen Historikk og statusmerket i topplinjen.
4. Web-grensesnitt
4.1. Sider og HTTP-API
| Sti | Metode | Innhold |
|---|---|---|
|
GET, POST |
Innloggingssiden. Skjema: |
|
POST |
Logger ut. Skjema: |
|
GET |
Forsiden med fanene Mottaker, Sender, MTU-test, Historikk og Nettkort |
|
GET |
Brukermanualen på valgt språk |
|
GET |
|
|
GET |
Maskinlesbar liste over tredjepartskomponenter |
|
GET |
Lagrer språkvalget i informasjonskapselen |
|
POST |
Starter en mottaker. JSON: |
|
POST |
Starter en sender. JSON: |
|
POST |
Starter en MTU-test. JSON: |
|
GET |
Nye logglinjer, |
|
POST |
Stopper økta og alle prosessene |
|
GET |
Hele loggen som |
|
GET |
Alle økter med id, type, etikett, |
|
GET |
Nettkort med MTU, IPv4-adresser, standardrute og flaggene |
|
GET |
|
4.2. Språk (i18n)
-
Engelsk tekst er nøkkelen, og
i18n.NOhar den norske oversettelsen.tests/test_i18n.pykontrollerer at alle tekster i maler,app.pyogapp.jser oversatt, og at plassholderne er like. -
Språket velges med informasjonskapselen
mct_lang, ellersMCT_LANG. Malene bruker_(),app.pybrukertr(), og JavaScript får sine tekster som JSON i<body data-i18n>. -
Logglinjene programmet selv skriver (overskrifter, MTU-resultater, «avsluttet (kode N)»), oversettes til språket økta ble startet med. Utdata fra iperf og ping vises uendret.
-
Feilmeldinger fra API-et kommer på språket i informasjonskapselen.
4.3. Lisenser og manual
-
Bunnlinja på alle sider: Multicast(at)Work 3.0.0 · Lisenser · Tredjepartsmerknader · Brukermanual.
-
/licensesviserLICENSE.txtogTHIRD_PARTY_NOTICES.txtfraMCT_DOC_DIR(/opt/multicast-tester). -
Brukermanualen lages fra
docs/Brukermanual.mdogdocs/en/User-Manual.mdmed pandoc når pakken bygges. Innholdslista legges i sidefeltet.
5. Sikkerhet
5.1. Tilgangskontroll
-
Innlogging kreves for alt unntatt
/login,/lang,/licenses,/healthzog/static. Sider sendes videre til/login, og API-kall får401med JSON (utenWWW-Authenticate, så nettleseren ikke viser sin egen dialog). -
Innloggingssiden setter en signert sesjonskapsel
mct_session(Flask,HttpOnly,SameSite=Strict, gyldig iMCT_SESSION_HOURS, standard 12 timer). Nøkkelen erMCT_SECRET_KEY, sominstall.shlager (secrets.token_hex(32)) og beholder ved ny installasjon. Sesjonen tømmes ved innlogging (ingen fiksering) og inneholder et merke avledet av passordet, så et nytt passord logger ut alle. -
Etter 5 feil passord fra samme adresse må den vente 60 sekunder. Feil forsøk logges i journalen.
-
Skript kan bruke HTTP Basic Auth med samme brukernavn og passord. Brukernavn og passord sammenlignes med
hmac.compare_digest.install.shlager et tilfeldig passord (secrets.token_urlsafe(12)) hvis det ikke finnes. -
Logg ut er et POST-skjema med et CSRF-token fra sesjonen.
-
CSRF: alle POST må ha
X-Requested-With: mct. En annen nettside kan ikke sende det hodet uten en CORS-forespørsel, som programmet aldri godtar.Sec-Fetch-Site: cross-siteavvises også. -
Sikkerhetshoder på alle svar:
Content-Security-Policy: default-src 'self'; style-src 'self'; script-src 'self'; img-src 'self' data:; frame-ancestors 'none'; form-action 'self'; base-uri 'none',X-Frame-Options: DENY,X-Content-Type-Options: nosniff,Referrer-Policy: same-origin,Cache-Control: no-store. -
Språkbyttet og innloggingen godtar bare lokale stier i
next(ingen åpen videresending).
5.2. Validering
| Felt | Kontroll |
|---|---|
IP-adresser |
|
Vertsnavn (MTU-mål) |
Regulært uttrykk etter RFC 1123. Kan ikke begynne med |
Port, varighet, TTL |
Heltall: 1–65535, 1–300, 1–255 |
Båndbredde |
|
Nettkort |
|
MTU-størrelser |
Liste med maks 1000 tall, avgrenset til 29–9216 |
JSON |
Kroppen må være et JSON-objekt, ellers HTTP 400 |
Alle kommandoer er argumentlister (subprocess.Popen([…])), aldri en skallstreng.
5.3. Kjente begrensninger
-
GUI-et går over HTTP, så passordet og sesjonskapselen sendes ukryptert. Bruk et administrasjonsnett,
--admin-neteller en SSH-tunnel. -
En innlogget bruker kan sende trafikk med valgfri hastighet til valgfrie adresser. Det er formålet med verktøyet.
-
Én felles innlogging, ingen roller.
-
Øktene holdes i minnet og forsvinner ved omstart.
-
click8.1.8 har en kjent sårbarhet som ikke kan nås fra programmet (seRevisjonsrapport.md).
6. Installasjon og filstruktur
6.1. Installasjonsprogrammet
install.sh kjører disse trinnene: kontroll av pakken (SHA256SUMS) → plattform (OS, arkitektur, systemd-detect-virt) → krav (python3 ≥ 3.9, ping, ip; prøver dnf/tdnf bare hvis noe mangler) → valg og kontroll av iperf → bruker mct → filer → Python-pakker → innstillinger → rp_filter → tjeneste (med container-tillegg i LXC) → brannmur → plattformmerknader → selvtest → sammendrag. Avslutningskoden er 0 (OK), 1 (feil) eller 2 (installert, men selvtesten fant noe).
Alle skriptene finnes på engelsk og norsk (--lang, ellers $LANG).
6.2. Installert struktur
| Sti | Innhold |
|---|---|
|
|
|
iperf 2.2.1 for maskinens CPU (eller kopi av systemets iperf med |
|
Python-pakkene (utpakkede hjul) |
|
Til |
|
Dokumentene, og lisenstekster og byggeinformasjon for iperf |
|
Vises også i GUI-et |
|
Avinstallering og selvtest |
|
Innstillinger og passord (0640 root:mct) |
|
Tjenesten |
|
Bare i containere |
|
|
Programmet byttes ut i sin helhet ved oppgradering (app.new → app), så filer som er fjernet i en ny versjon, forsvinner.
6.3. Python-pakker
Hjulene i vendor/wheels pakkes ut direkte med python3 -m zipfile til /opt/multicast-tester/lib/python, som tjenesten finner gjennom PYTHONPATH. pip og virtualenv brukes ikke. MarkupSafe velges etter Python-versjon og CPU (cp39, cp311 og cp312, x86_64 og aarch64). Finnes ikke riktig hjul, brukes et annet, og MarkupSafe faller da tilbake til sin rene Python-utgave. Til slutt kontrolleres det at flask, waitress, jinja2 og markupsafe kan importeres.
6.4. iperf
-
Bygget av
tools/build-iperf.shfra iperf 2.2.1 (iperf_2.2.1+dfsg.orig.tar.xz, SHA-256 kontrollert) medzig cc -target <arch>-linux-musl -static. Resultatet er en statisk fil uten avhengigheter, som virker på alle vanlige Linux-distribusjoner. -
gnu_getopt(LGPL) er byttet ut medgetopt_longfra musl, slik at fila ikke inneholder copyleft-kode (seLisensrapport.md). Resten av kildekoden er uendret. -
Byggingen er reproduserbar: samme kildekode og kompilator gir samme SHA-256, som står i
vendor/iperf/BUILD-INFO.txt.
6.5. Oppgradering fra 2.x
Versjon 2 lå direkte i /opt/multicast-tester med .venv og hadde innstillingene i /etc/multicast-tester.env. install.sh gjenkjenner det, henter port, bruker og passord fra den gamle fila, flytter den til .v2-migrated, bytter eksempelpassordet change-me og fjerner de gamle filene.
7. Nettverk og eksterne ressurser
7.1. Porter
| Port | Protokoll | Bruk |
|---|---|---|
5152 ( |
TCP |
Web-GUI-et. Kan begrenses til |
5001–5010 ( |
TCP og UDP |
iperf-testene (standard i GUI-et: 5001) |
– |
IGMP (protokoll 2) |
Innmelding i grupper og svar til querier |
– |
ICMP |
Ping og MTU-test (utgående, med svar) |
rp_filter = 2 (løs kontroll) hindrer at kjernen forkaster multicast som kommer inn på et annet nettkort enn ruta tilbake til avsenderen.
7.2. Eksterne ressurser
Ingen. Programmet laster ikke ned noe ved installasjon eller kjøring, og web-sidene henter bare filer fra serveren selv. Navneoppslag brukes bare hvis MTU-målet oppgis som vertsnavn.
8. Drift
| Oppgave | Kommando |
|---|---|
Status |
|
Logg fra tjenesten |
|
Selvtest |
|
Endre passord, port eller språk |
|
Start på nytt |
|
Avinstaller |
|
Tjenesten bruker lite ressurser når ingen test kjører (omtrent 40 MB minne). Under en test bestemmer båndbredden CPU-bruken til iperf.
9. Kvalitetssikring
-
42 enhetstester (pytest) for innlogging og utlogging, validering, sikkerhet, språk, økter, Stopp og MTU-tolkning. iperf og ping erstattes av små skript, så testene ikke trenger nettverk.
-
shellcheckpå alle skall-skript,pyflakesogbanditpå Python-koden,pip-auditpå avhengighetene. -
Copyleft-skanning av alle filene i pakken (
tools/gen-third-party.py --scan). -
Selvtesten (19 kontroller, også innlogging og utlogging med skjemaet) kjøres av hver installasjon, med en ekte multicast-strøm fra senderen til mottakeren på samme maskin.
-
Nettlesertester i Chromium på begge språk, i alle fem fanene, på innloggingssiden og på mobilbredde.
-
Detaljer og akseptansetest for målplattformene står i
Revisjonsrapport.md.