niom-turn/DEPLOYMENT_TLS_AUTH.md

3.8 KiB

TLS and Long-Term Authentication — Integration Notes

Dieses Dokument beschreibt empfohlene Schritte, Abhängigkeiten und eine kurze Roadmap zur Integration von TLS (turns) und RFC-konformer Long-Term Authentication für den niom-turn MVP.

Ziele

  • TLS (turns) auf TCP/TLS Port 5349 (tokio-rustls / rustls)
  • Long-Term Authentication (RFC 5389 / RFC 5766): Benutzerverwaltung + MESSAGE-INTEGRITY-Prüfung
  • Sichere Speicherung von Credentials (keine Klartext-Passwörter in Produktion)

Empfohlene Bibliotheken

  • rustls + tokio-rustls — TLS für Tokio-basierte Server
  • rcgen — optional für lokale self-signed certs während Tests
  • ring / argon2 / scrypt — für sichere Passwort-Hashing (statt MD5/A1 in Produktion)

Schritte (high-level)

  1. TLS Listener

    • Ergänze einen TCP-Listener auf Port 5349.
    • Wrapping der TCP-Streams mit tokio-rustls using a configured ServerConfig (cert + private key).
    • Handhabe ALPN falls nötig (z. B. webrtc client expectations).
  2. Socket Multiplexing und Protocols

    • Behalte den UDP-Listener auf 3478 für STUN/TURN (UDP). Für TLS/TCP setze eine separate Task auf.
    • Gemeinsame STUN/TURN-Nachrichtenverarbeitung (Parsing/Antworten) ist wiederverwendbar — benutze die Bibliotheks-Module (stun.rs, alloc.rs).
  3. Long-Term Auth (Credentials)

    • Implementiere ein PersistentCredentialStore-Impl der CredentialStore-Trait, welches z. B. eine SQLite/Postgres-Tabelle oder Vault/Secrets-Backend nutzt.
    • Verifiziere MESSAGE-INTEGRITY gemäß RFC: Client sendet USERNAME, REALM, NONCE und MESSAGE-INTEGRITY. Der Server berechnet die HMAC-SHA1 über den Nachrichtenteil entsprechend RFC und vergleicht.
    • Verwende sichere Passwortspeicherung: speichere gehashte Passwörter (Argon2/Scrypt) und validiere beim Anmelden. Langfristige TURN-Konten sind oft server-seitig in Klartext/A1 gesetzt; für Produktion empfiehlt sich ein server-seitiges Secret, mit dem kurzfristige Credentials erzeugt werden (REST API zum Erstellen ephemerer Creds).
  4. Nonce / Replay-Protektion

    • Implementiere Nonce-Generierung mit ausreichender Entropie und begrenzter Lebenszeit. Optional: zentrale Nonce-Store oder HMAC-gebundene Nonces.
  5. Tests und Fallbacks

    • Automatisiere Tests: Unit-Tests für MESSAGE-INTEGRITY, Integrationstests mit smoke_client gegen UDP und TCP/TLS.
    • Fallback-Mode: if TLS configs not present, start UDP-only server but clearly log the insecure state.

Code-Snippets / Hinweise

  • Beispiel (TLS-Server-Setup sketch):
// load cert/key
let certs = load_certs("/path/to/cert.pem")?;
let key = load_private_key("/path/to/key.pem")?;
let mut cfg = rustls::ServerConfig::builder()
    .with_safe_defaults()
    .with_no_client_auth()
    .with_single_cert(certs, key)?;
let tls_acceptor = tokio_rustls::TlsAcceptor::from(Arc::new(cfg));

let listener = TcpListener::bind("0.0.0.0:5349").await?;
loop {
    let (socket, peer) = listener.accept().await?;
    let acceptor = tls_acceptor.clone();
    tokio::spawn(async move {
        match acceptor.accept(socket).await {
            Ok(stream) => {
                // read STUN messages from the TLS stream, process same as UDP
            }
            Err(e) => tracing::error!("TLS accept failed: {:?}", e),
        }
    });
}

Prioritäten / Phasen

  • Phase 1: Config-driven TLS listener + integration tests (low risk)
  • Phase 2: Implement Persistent CredentialStore and nonce lifecycle
  • Phase 3: Replace MD5/A1 usage with secure KDF-backed credential workflow (Argon2, PBKDF2)
  • Phase 4: Hardening, monitoring, and deployment automation (cert renewal)

Weiteres

  • Wenn du möchtest, kann ich die TLS listener-Integration direkt als PR implementieren (schrittweise: TLS listener -> tests -> credential-store wiring). Ich kann auch Beispiel-Implementierungen für PersistentCredentialStore mit SQLite/SQLx anbieten.