niom-turn ========= Minimal TURN server scaffold for the niom project (MVP). Goals - Provide a TURN server with long-term authentication and TLS (turns) for WebRTC clients. - Start with a minimal, well-tested parsing/utility layer and an in-memory credential store interface that can be replaced later. Current status - UDP listener on 0.0.0.0:3478 (STUN/TURN) implemented. - STUN message parser + builder in `src/stun.rs`. - CredentialStore trait + in-memory implementation in `src/auth.rs`. - Minimal logic: on any STUN request, server replies with a 401 challenge (REALM + NONCE). Design - Modules - `stun.rs` - STUN/TURN message parsing and builders. - `auth.rs` - CredentialStore trait and an `InMemoryStore` impl. Use the trait to swap for DB-backed stores later. - `main.rs` - Bootstraps UDP listener, parses requests, and emits challenges for auth. CredentialStore interface - `CredentialStore` is an async trait with `get_password(username) -> Option`. - The default `InMemoryStore` is provided for tests and local dev. Swap in a production store by implementing the trait. How to build ```bash cd niom-turn cargo build ``` How to test (quick local smoke) - Start the server in one terminal (it listens on UDP/3478): ```bash cd niom-turn cargo run ``` - From another machine or container, use a STUN client or `sipsak`/custom script to send a minimal STUN Binding request and observe the 401 reply. Next steps - Implement full STUN attribute parsing (MESSAGE-INTEGRITY, FINGERPRINT). - Implement long-term auth validation using MESSAGE-INTEGRITY. - Implement Allocate + relayed sockets and permission handling. - Add TLS listener (port 5349) using `tokio-rustls` and support `turns:`. Security / Deployment - For production, run behind properly provisioned TLS certs (Let's Encrypt or mounted certs) and secure credential storage. - Ensure UDP and TCP/TLS ports (3478/5349) are reachable from the internet when used as a public TURN server. Auth caveat - The current in-repo long-term auth implementation is intentionally minimal for the MVP and uses legacy constructs (A1/MD5 derivation + HMAC-SHA1 MESSAGE-INTEGRITY). MD5 is not recommended for new secure systems — this is present for RFC compatibility and testing only. We will replace this with a secure credential workflow (ephemeral/REST credentials, PBKDF/KDF storage, or mTLS) before any production deployment. See `src/auth.rs` for the current simple store and helpers. License: MIT Smoke-Test (End-to-End) ----------------------- Diese Anleitung beschreibt, wie du lokal den laufenden TURN/STUN-Server prüfst und welche Ergebnisse zu erwarten sind. 1) Server starten Starte den Server im Projektverzeichnis; die Ausgabe wird normal in stdout geschrieben. In meinen Tests habe ich den Server im Hintergrund gestartet und die Logs in `/tmp/niom-turn-server.log` umgeleitet: ```bash cd niom-turn # Im Vordergrund (für Entwicklung) cargo run --bin niom-turn # Oder im Hintergrund mit Log-Redirect cargo run --bin niom-turn &>/tmp/niom-turn-server.log & ``` 2) Smoke-Client ausführen Das Repo enthält ein kleines Test-Binary `smoke_client`, das eine STUN Binding-Request mit `USERNAME` und `MESSAGE-INTEGRITY` an `127.0.0.1:3478` sendet. ```bash # Build (falls noch nicht gebaut) cargo build --bin smoke_client # Ausführen ./target/debug/smoke_client ``` 3) Erwartetes Ergebnis Der Smoke-Client gibt die erhaltenen Bytes aus. Bei einer erfolgreichen MESSAGE-INTEGRITY-Prüfung sendet der Server eine STUN Success Response (Message Type 0x0101). Beispielsweise habe ich folgende Rückgabe gesehen: ``` got 20 bytes from 127.0.0.1:3478 [01, 01, 00, 00, 21, 12, a4, 42, 07, 07, 07, 07, 07, 07, 07, 07, 07, 07, 07, 07] ``` Erklärung: - `01 01` → STUN Success Response (0x0101) - `21 12 a4 42` → Magic Cookie (0x2112A442) - die folgenden 12 Bytes sind die Transaction ID (in diesem Test `07` wiederholt) Das bedeutet: Der Server hat die MESSAGE-INTEGRITY des Requests akzeptiert und eine 200-Antwort gesendet. Wenn stattdessen eine 401-Antwort (Challenge) ausgegeben wird, sieht man im Hex typischerweise einen Fehler-Response-Typ und REALM/NONCE-Attribute im Payload; das zeigt, dass die Authentifizierung nicht erfolgt ist und der Client die Challenge verarbeiten muss. Hinweis - Die derzeitige Auth-Implementierung ist minimal und für Tests gedacht. Für Produktion bitte die README-Abschnitte "Auth caveat" beachten: sichere Credentials, TLS, und ggf. ephemeral credentials verwenden.