Iperf(at)Work

Iperf(at)Work / Teknisk beskrivelse

Iperf(at)Work

Arkitektur, komponenter, sikkerhet, pakking og drift for Iperf(at)Work

Versjon 2.1.0Revidert 2026-10-04Klient og server

Iperf(at)Work er et nettleserbasert grensesnitt for nettverksytelsestester med iperf3. Dokumentet beskriver arkitekturen, komponentene, API-et, sikkerhetsmekanismene, pakke- og installasjonsmodellen og driften, og er skrevet for drift, sikkerhetsgjennomgang og videreutvikling.

1. Formål og omfang

Produkt

Iperf(at)Work 2.1.0

Komponenter

Caddy 2.11.4 (web-server og omvendt proxy), iperf-api (Python, standardbibliotek), iperf3 3.21 (statisk), web-GUI (HTML/CSS/JS), iperf-by-web-ctl, installasjonsskript

Bruksområde

Måling av båndbredde, retransmisjoner, jitter og pakketap mellom to maskiner; feilsøking og akseptansetest av nett, VPN, WAN og virtuelle svitsjer

Ikke formål

Kontinuerlig overvåking, måling fra mange agenter, lagring av måleserier over lang tid

Målplattformer

Rocky Linux 9 / RHEL 9 / AlmaLinux 9 og VMware Photon OS 4/5, på fysisk server, VMware-VM/appliance og Proxmox VE-VM (x86_64)

Kjøremodell

Vanlige Linux-prosesser styrt av systemd, installert fra tre RPM-pakker uten pakkebrønner eller internett

Språk

Engelsk og norsk (bokmål) i web-GUI, API-meldinger, manualer, lisenssider og skript

2. Arkitektur

2.1. Oversikt

 Nettleser
   │ HTTP :80 (valgfritt HTTP Basic-passord)
   ▼
 ┌────────────────────────── caddy.service (bruker caddy) ───────────────────────────┐
 │  /api/*  ──► reverse_proxy 127.0.0.1:9000 (flush_interval -1 for SSE)              │
 │  /*      ──► file_server /usr/share/iperf-by-web/html                               │
 │              index.html, ui.css, i18n.js, app.js, manual(.no).html, licenses(.no)  │
 │  sikkerhetshoder (CSP, X-Frame-Options, nosniff, Referrer-Policy)                  │
 └────────────────────────────────────────────────────────────────────────────────────┘
   │
   ▼ 127.0.0.1:9000
 ┌────────────────────────── iperf-api.service (bruker iperf-by-web) ─────────────────┐
 │  ThreadingHTTPServer ─► /api/start ─► subprocess iperf3 -c … (ny prosessgruppe)    │
 │                        watcher-tråd ─► tests/test-<id>.log + .meta.json            │
 │                       /api/output  ─► Server-Sent Events (følger loggfilen)         │
 │                       /api/server/status ─► systemctl is-active, ss, server-logg   │
 └────────────────────────────────────────────────────────────────────────────────────┘

 iperf3-server@5201.service, iperf3-server@5202.service (bruker iperf-by-web, server/both)
   iperf3 --server --port N --forceflush --timestamps --logfile /var/lib/iperf-by-web/server-N.log

2.2. Komponenter

Komponent Språk Ansvar

Caddy 2.11.4 (/usr/bin/caddy)

Go

Lytter på port 80, leverer de statiske sidene, proxyer /api/* til API-et uten bufring (sanntidsstrøm), legger på sikkerhetshoder, valgfri HTTP Basic-autentisering (/etc/caddy/iperf-by-web.d/auth.caddy), tilgangslogg med rullering

iperf-api (/usr/libexec/iperf-by-web/iperf-api)

Python 3

JSON-API: validerer testparametere, starter og stopper iperf3 uten skall, lagrer logg og metadata per test, tolker sammendraget, strømmer utdata med Server-Sent Events, leser serverstatus

iperf3 3.21 (/usr/bin/iperf3)

C

Selve målingen, som klient (startet av API-et) og som server (iperf3-server@<port>)

Web-GUI (index.html, ui.css, i18n.js, app.js)

HTML/CSS/JS

Skjema, sanntidsgraf (canvas), resultatfliser, sammendrag, historikk med CSV-eksport, serverstatus, EN/NO

iperf-by-web-ctl

bash

Tar konfigurasjonen i bruk (tjenester, brannmur), status, rollebytte, språk, passord, selvtest

install.sh, check-prereqs.sh, uninstall.sh, lib/common.sh

bash

Offline-installasjon, kontroll av forutsetninger, avinstallering – på engelsk og norsk

2.3. Prosess- og trådmodell

API-et bruker ThreadingHTTPServer med én tråd per forespørsel. Hver test startes som en egen prosess i en ny prosessgruppe (start_new_session=True), med stdout og stderr til loggfilen. En watcher-tråd venter på prosessen, skriver sluttstatus og tolket resultat til metadatafilen og frigir «pågående test». Bare én klienttest kan kjøre om gangen (lås + sjekk av prosessen). SSE-forespørsler holder en tråd hver mens testen pågår og sender en keep-alive-kommentar hvert ~10. sekund.

Ved stopp sendes SIGINT til prosessgruppen, slik at iperf3 skriver sammendrag; etter 3 sekunder sendes SIGKILL. Når API-et startes, merkes tester som fortsatt står som running (avbrutt av omstart) som failed med en merknad.

3. Måling

3.1. Kommandoen

API-et bygger argumentlisten (aldri en skallstreng):

iperf3 -c <server> -p <port> -t <varighet> -i <intervall> -P <strømmer> --forceflush -f m
       [-O <hopp over>] [-u -b <båndbredde|1G>] [-b <båndbredde>] [-w <vindu>] [-l <lengde>]
       [-R | --bidir] [-B <kildeadresse>] [-4 | -6]

--forceflush gjør at hver intervall-linje skrives med en gang (sanntidsvisning), og -f m gir alle hastigheter i Mbit/s.

3.2. Validering

Felt Regel iperf3

server

^[A-Za-z0-9]([A-Za-z0-9.\-:]{0,251}[A-Za-z0-9])?$ (vertsnavn, IPv4, IPv6)

-c

port

1–65535

-p

duration

1–MAX_DURATION (3600)

-t

parallel

1–128

-P

interval

1–60

-i

omit

0–60 og mindre enn varigheten

-O

protocol

tcp / udp

-u

direction

normal / reverse / bidir

-R / --bidir

bandwidth

^[0-9]{1,6}(\.[0-9]{1,3})?[KkMmGg]?$

-b

window, length

^[0-9]{1,7}[KkMm]?$

-w, -l

bind

^[0-9A-Fa-f.:]{2,45}$ (lokal adresse)

-B

ipversion

auto / 4 / 6

-4 / -6

3.3. Tolking av resultatet

Sammendragslinjene (som slutter med sender eller receiver) tolkes med et regulært uttrykk som håndterer [ 5], [SUM], [ 5][TX-C] og [SUM][RX-C]. Finnes [SUM]-linjer (flere strømmer), brukes bare de. For hver linje lagres retning (up = TX-C, down = RX-C, ellers ingen), målested, hastighet omregnet til Mbit/s, overført mengde og enten retransmisjoner (TCP, sender) eller jitter, tapte/totale datagrammer og tap i prosent (UDP). Feilmeldingen iperf3: error - … lagres for feilede tester.

Web-GUI-et tolker intervall-linjene fortløpende på samme måte for grafen og flisene; linjer merket (omitted) hoppes over.

3.4. Lagring

Fil

Innhold

/var/lib/iperf-by-web/tests/test-<id>.log

Kommando og fullstendig utdata fra iperf3

/var/lib/iperf-by-web/tests/test-<id>.meta.json

Parametere, status (running, done, failed, stopped), tider, avslutningskode, sammendragslinjer, tolket resultat, feilmelding

/var/lib/iperf-by-web/server-<port>.log

Serverens logg med tidsstempel (logrotate: ukentlig, 8 uker, komprimert)

ID-en er starttidspunktet ÅÅÅÅMMDD-TTMMSS (med -n ved kollisjon). Metadata skrives atomisk (midlertidig fil + os.replace). Når antallet passerer KEEP_TESTS, slettes de eldste.

4. Web-grensesnitt

4.1. Oppbygning

Siden følger stilen i SYSLOG-Tools(at)Work og SNMP-Trap-Tools(at)Work: mørkegrønn topplinje med ikon, navn, statusmerke og vertsnavn; ? Brukermanual og EN | NO til høyre; faner; Bootstrap-lignende skjemaelementer; bunnlinje med Lisenser · Tredjepartsmerknader · Brukermanual. Alt er skrevet for prosjektet – ingen eksterne skript, stilark, skrifttyper eller bilder – så sidene virker uten internett.

Fane

Innhold

Kjør test

Nettverksoppsett, testparametere, avanserte valg, start/stopp, kommandolinje, fire fliser (siste intervall, snitt, maks, fremdrift), graf (to linjer ved --bidir), sammendragstabell, utdata

Historikk

Filtrerbar tabell over de 50 nyeste testene, utvidbare rader med kommando og sammendrag, nedlasting av logg, CSV-eksport (UTF-8 med BOM)

Server

Status per port (systemd + lyttende socket), antall forbindelser og motparter (ss), oppetid, serverlogg per port; oppdateres hvert 3. sekund

Fanene vises ut fra rollen (client: Kjør test og Historikk, server: Server, both: alle). Valgt fane huskes i adressen (#tab=). Lukkes nettleseren under en test, kobler siden seg til den pågående testen igjen ved neste besøk.

4.2. Språk (i18n)

Engelsk er kildespråket. i18n.js inneholder ordlisten engelsk → norsk og en motor som ved oppstart registrerer alle tekstnoder, placeholder, title og aria-label som finnes i ordlisten, og bytter dem når brukeren trykker EN eller NO. Tekster som lages av skript, bruker t('English text', {var}). Valget lagres i localStorage og en informasjonskapsel (iperf_by_web_lang). Uten lagret valg brukes UI_LANG fra konfigurasjonen (via /api/status).

API-et velger språk for feilmeldinger fra hodet X-UI-Lang (sendt av siden), ellers UI_LANG. Manualene og lisenssidene finnes som egne filer per språk (manual.html / manual.no.html, licenses.html / licenses.no.html); knappen ? Brukermanual åpner riktig språk og kapitlet for fanen (#s3, #s4, #s5). Utdata fra iperf3 oversettes ikke.

4.3. HTTP-API

Metode

Sti

Beskrivelse

GET

/api/status

Modus, vertsnavn, IP, versjoner (API, iperf3, Caddy), pågående test, standardverdier, ui_lang, oppetid

POST

/api/start

Starter en test (JSON, se validering). 200 started, 400 ugyldig, 409 opptatt eller servermodus

POST

/api/stop

Stopper pågående test (SIGINT, deretter SIGKILL)

GET

/api/output?id=

SSE: data: per linje, til slutt event: done med metadata

GET

/api/tests

De 50 siste testene (uten PID)

GET

/api/log?id=

Loggen som text/plain-vedlegg

GET

/api/server/status

Porter, systemd-status, lytter, forbindelser, motparter, loggutdrag (80 linjer)

5. Sikkerhet

5.1. Trusselbilde

Iperf(at)Work er et administrasjonsverktøy for et lukket nett. Den viktigste risikoen er at noen uten tillatelse bruker web-GUI-et til å sende store mengder trafikk (fylle linjer) mot vilkårlige mål. Tiltakene under begrenser dette; web-GUI-et bør likevel bare være tilgjengelig fra et betrodd administrasjonsnett.

5.2. Tiltak i web-laget

Tiltak

Beskrivelse

Tilgang

Valgfritt HTTP Basic-passord (bcrypt, kostnad 14) for hele nettstedet inkludert API-et (iperf-by-web-ctl password set). Valgfri begrensning av web-porten til ett nett i firewalld (ADMIN_NET).

CSRF

Alle POST-forespørsler må ha X-Requested-With: iperf-by-web-ui. Et slikt hode kan ikke settes av andre nettsteder uten CORS-forhåndsforespørsel, som aldri godkjennes. Forespørselskroppen leses alltid før avvisning, slik at keep-alive-forbindelser fra Caddy ikke kommer ut av takt.

Injeksjon

iperf3 startes med argumentliste (ingen skall); alle felt valideres med hvitelister (se 3.2). Test-ID-er valideres (^[0-9]{8}-[0-9]{6}(-[0-9]{1,3})?$) før de brukes i filstier.

XSS

All tekst fra serveren settes inn med textContent eller escapes (esc()) før innerHTML.

Hoder

Content-Security-Policy (bare egne ressurser, frame-ancestors 'none'), X-Frame-Options: DENY, X-Content-Type-Options: nosniff, Referrer-Policy: no-referrer; Server-hodet fjernes.

Ressurser

Én test om gangen, varighet maks MAX_DURATION, maks 128 strømmer, forespørselskropp maks 64 KiB, historikk begrenset til KEEP_TESTS.

API-binding

API-et lytter bare på 127.0.0.1:9000 og nås bare gjennom Caddy. Caddys admin-API lytter bare på localhost:2019.

5.3. Prosessisolasjon (systemd)

Tjeneste

Herding

caddy

Bruker caddy, bare CAP_NET_BIND_SERVICE (også som grense), NoNewPrivileges, ProtectSystem=full, PrivateTmp

iperf-api

Bruker iperf-by-web, NoNewPrivileges, ProtectSystem=strict (skriver bare /var/lib/iperf-by-web), ProtectHome, PrivateTmp, PrivateDevices, ProtectKernelTunables/Modules, ProtectControlGroups, RestrictSUIDSGID, LockPersonality, RestrictAddressFamilies=AF_INET AF_INET6 AF_UNIX AF_NETLINK, UMask=0027

iperf3-server@

Bruker iperf-by-web, NoNewPrivileges, ProtectSystem=strict, ProtectHome, PrivateTmp, PrivateDevices, ProtectKernelModules, ProtectControlGroups, RestrictSUIDSGID

SELinux: tjenestene kjører som unconfined_service_t; installasjonen setter merking med restorecon.

5.4. Kjente begrensninger

  • Web-GUI-et bruker vanlig HTTP. Passordet (hvis brukt) sendes base64-kodet. Bruk et betrodd nett og ADMIN_NET. HTTPS kan settes opp i Caddyfile med egne sertifikater (tls /sti/cert.pem /sti/key.pem).

  • iperf3 er bygget uten OpenSSL, så iperf3s egen autentisering (--username, --rsa-public-key-path) finnes ikke. iperf3-serveren tar imot tester fra alle som når portene; begrens med brannmuren.

  • Én iperf3-server kan bare kjøre én test om gangen per port.

  • Med -B over loopback-aliaser feiler UDP-tester i iperf3 (gjelder bare testmiljøer, ikke ekte nettkort).

  • Ingen brukerroller: alle som slipper inn, kan starte og stoppe tester.

6. Pakking og installasjon

6.1. RPM-pakkene

Pakke

Arkitektur

Innhold og avhengigheter

iperf3-3.21-2.static.el9

x86_64

/usr/bin/iperf3 (statisk, musl), man-side, lisenser (iperf3 + musl). Ingen avhengigheter.

caddy-2.11.4-2.el9

x86_64

/usr/bin/caddy (offisiell binær, SHA-512 kontrollert), caddy.service, lisens + lisensene til 144 Go-moduler. Krever systemd, (shadow-utils or shadow).

iperf-by-web-2.1.0-1.el9

noarch

API, web-GUI, manualer, lisenssider, Caddyfile, konfigurasjon, systemd-enheter, iperf-by-web-ctl, uninstall.sh, dokumentasjon. Krever caddy >= 2.7, iperf3 >= 3.9, python3, (iproute or iproute2), util-linux, systemd.

Avhengighetene er skrevet slik at de løses både på Rocky/RHEL 9 og på Photon OS (boolske avhengigheter, rpm ≥ 4.13). Konfigurasjonsfiler er %config(noreplace).

6.2. Installert struktur

/etc/caddy/Caddyfile                       %config(noreplace)
/etc/caddy/iperf-by-web.d/                  0750 root:caddy  (auth.caddy når passord er satt)
/etc/iperf-by-web/iperf-by-web.conf          %config(noreplace)
/etc/logrotate.d/iperf-by-web
/usr/bin/caddy, /usr/bin/iperf3
/usr/libexec/iperf-by-web/iperf-api
/usr/sbin/iperf-by-web-ctl
/usr/share/iperf-by-web/html/               web-GUI, manual(.no).html, licenses(.no).html
/usr/share/iperf-by-web/uninstall.sh, lib/common.sh
/usr/share/doc/iperf-by-web/                dokumenter (no + en/ + img/)
/usr/share/licenses/{iperf-by-web,caddy,iperf3}/
/usr/lib/systemd/system/{caddy,iperf-api,iperf3-server@}.service
/var/lib/iperf-by-web/                      0750 iperf-by-web (tests/, server-<port>.log)
/var/lib/caddy, /var/log/caddy             0750 caddy

6.3. Installasjonsprogrammet

install.sh går gjennom sju steg: forutsetninger (arkitektur, plattform, systemd, rpm, Python ≥ 3.7, ss, useradd, runuser, sjekksummer, ledige porter), pakker (dnf --disablerepo='*' install eller rpm -Uvh; pakker med riktig versjon hoppes over), konfigurasjon (nye nøkler legges til i en eldre fil), passord, SELinux, iperf-by-web-ctl apply og verifisering (tjenester, selvtest, nåbarhet til standardserveren). Alle meldinger finnes på engelsk og norsk (--lang).

iperf-by-web-ctl apply validerer Caddyfile som brukeren caddy, stopper alle iperf3-server@-instanser og starter bare dem rollen krever, starter/laster API-et og Caddy på nytt og oppdaterer firewalld (fjerner gamle iperf-porter 5200–5299, åpner web-porten – eventuelt som rich rule for ADMIN_NET – og serverportene for tcp og udp).

7. Konfigurasjon

/etc/iperf-by-web/iperf-by-web.conf leses av API-et (systemd EnvironmentFile) og av iperf-by-web-ctl.

Nøkkel

Standard

Betydning

IPERF_MODE

client

client, server, both

IPERF_SERVER_PORTS

"5201 5202"

Porter for iperf3-server@

DEFAULT_SERVER, DEFAULT_PORT

172.16.101.61, 5201

Forhåndsutfylt i GUI-et

UI_LANG

en

Standardspråk for GUI, API-meldinger og iperf-by-web-ctl

HOST_IP

tom

Vist IP-adresse (tom: adressen som brukes mot DEFAULT_SERVER, funnet med en UDP-socket uten å sende pakker)

MAX_DURATION

3600

Lengste test

KEEP_TESTS

200

Tester i historikken

API_BIND, API_PORT

127.0.0.1, 9000

API-adresse (også i Caddyfile)

WEB_PORT

80

Web-port (brannmur; også i Caddyfile)

MANAGE_FIREWALL

yes

firewalld styres av iperf-by-web-ctl

ADMIN_NET

tom

Web-porten åpnes bare for dette nettet

OUTPUT_DIR, IPERF_BIN

/var/lib/iperf-by-web, /usr/bin/iperf3

Stier

8. Drift

Oppgave

Kommando

Status

iperf-by-web-ctl status

Logg

iperf-by-web-ctl logs, journalctl -u iperf-api -f, /var/log/caddy/iperf-by-web-access.log

Rollebytte

iperf-by-web-ctl mode client|server|both

Passord

iperf-by-web-ctl password set [bruker] / off / status

Selvtest

iperf-by-web-ctl selftest (lokal iperf3-test på 127.0.0.1:5299, API og web-GUI)

Omstart

systemctl restart iperf-api caddy

Avinstallering

/usr/share/iperf-by-web/uninstall.sh [--all] [--purge]

Diskbruk: én test tar typisk 2–20 KB (logg + metadata); 200 tester under 5 MB. Serverloggene rulleres ukentlig.

9. Bygging og kvalitetssikring

9.1. Bygging

Verktøy

Gjør

tools/build-iperf3-static.sh

Bygger iperf3 fra sources/iperf-3.21.tar.gz med musl-gcc (statisk, uten OpenSSL/SCTP). Resultatet er byte-identisk med binærfilen i 2.0.0.

tools/fetch-go-licenses.py

Leser modullisten i caddy (go version -m) og henter lisens- og NOTICE-filene for hver modul (trenger internett)

tools/build-licenses.py

Lager THIRD_PARTY_NOTICES.txt, third_party_inventory.json, licenses/caddy/THIRD-PARTY-GO-MODULES.txt og lisenssidene (offline)

tools/build-manuals.py

Lager manual.html og manual.no.html fra Markdown med pandoc (bilder innebygd)

tools/make-screenshots.py

Starter hele stakken lokalt, kjører ekte tester og tar skjermbilder på begge språk (Playwright)

tools/build-rpms.sh

Bygger de tre RPM-ene (reproduserbart tidsstempel)

tools/build-package.sh

Alt over + selvtest + SHA256SUMS + Iperf-by-web-2.1.0-offline.tar.gz (+ .sha256)

9.2. Selvtest

python3 tools/selftest.py kjører statiske kontroller (Python- og bash-syntaks, ShellCheck, versjonsnumre, oversettelsesdekning, ingen eksterne ressurser, dokumenter), enhetstester av sammendragstolkingen, integrasjonstester mot et ekte API og en ekte iperf3-server (TCP, UDP, --bidir, SSE, stopp, feilet test, validering, CSRF, keep-alive, språk, historikk) og pakketester (navn, versjoner, avhengigheter, filer). Se Revisjonsrapport.md for resultatene.

Skjermbilder, installasjon og hvordan klient og server brukes sammen: Tilbake til forsiden