Ziel dieser Anleitung
Moblin, OBS oder eine IRL-Kamera sendet per RTMP an deinen Linux-Server. Nginx akzeptiert den Stream nur mit einem langen geheimen Stream-Key. Ein interner HTTP-Endpunkt prüft den Key über on_publish; er ist ausschließlich unter 127.0.0.1:8080 erreichbar.
on_publish geprüft. Port 8080 bleibt intern; die Statusseite läuft getrennt auf Port 8081.Moblin / OBS → RTMP :1935 → Nginx-RTMP → OBS / Weiterverarbeitung
│
└→ interne Key-Prüfung 127.0.0.1:8080
Inhalt
- 1. Server vorbereiten
- 2. Stream-Key erstellen
- 3. Konfiguration sichern
- 4. Nginx konfigurieren
- 4a. Statusseite installieren
- 5. Konfiguration testen
- 6. Firewall absichern
- 7. Ports kontrollieren
- 8. OBS konfigurieren
- 9. Moblin konfigurieren
- 10. Stream empfangen
- 11. Authentifizierung testen
- 12. Logs prüfen
- 13. Autostart
- 14. Sicherheitsübersicht
1. Linux-Server vorbereiten
Die Befehle passen für Ubuntu Server und Debian. Aktualisiere zuerst das System und installiere Nginx samt RTMP-Modul, die deutschen Sprach- und Ländereinstellungen sowie Fail2Ban:
sudo apt update
sudo apt upgrade -y
sudo apt install nginx libnginx-mod-rtmp locales fail2ban -y
sudo systemctl enable --now nginx
sudo systemctl status nginx
Der Nginx-Status sollte active (running) anzeigen.
Deutsche Sprache, UTF-8 und Ländereinstellungen aktivieren
de_DE.UTF-8 stellt die Standardsprache und landestypische Formate auf Deutsch (Deutschland) um. Dazu gehören beispielsweise Datums-, Zahlen-, Währungs- und Sortierformate. UTF-8 sorgt dafür, dass Umlaute und Sonderzeichen korrekt verarbeitet werden.
sudo sed -i '/de_DE.UTF-8/s/^# *//' /etc/locale.gen
sudo locale-gen
sudo update-locale LANG=de_DE.UTF-8 LANGUAGE=de_DE:de
sudo timedatectl set-timezone Europe/Berlin
Melde dich danach einmal ab und wieder an. Kontrolliere anschließend die Spracheinstellungen und die Zeitzone:
locale
timedatectl
LANG sollte de_DE.UTF-8 stehen und als Zeitzone Europe/Berlin angezeigt werden. Bereits geöffnete Terminals übernehmen die neue Sprache erst nach einer erneuten Anmeldung.Fail2Ban für SSH aktivieren
Fail2Ban beobachtet fehlgeschlagene SSH-Anmeldungen und sperrt auffällige IP-Adressen vorübergehend. Die folgende kleine Zusatzkonfiguration erlaubt fünf Fehlversuche innerhalb von zehn Minuten und sperrt die betreffende Adresse danach für eine Stunde:
sudo tee /etc/fail2ban/jail.d/sshd.local > /dev/null <<'EOF'
[sshd]
enabled = true
port = ssh
maxretry = 5
findtime = 10m
bantime = 1h
EOF
sudo systemctl enable --now fail2ban
sudo systemctl restart fail2ban
sudo fail2ban-client status sshd
Die Statusausgabe zeigt unter anderem die Anzahl fehlgeschlagener Versuche und aktuell gesperrte IP-Adressen. Fail2Ban ist ein zusätzlicher Schutz; am sichersten bleibt SSH mit Schlüsselanmeldung statt Passwort.
2. Sicheren Stream-Key erstellen
Erzeuge einen zufälligen 64-stelligen Schlüssel. Verwende keine einfachen Werte wie test, stream oder 12345.
openssl rand -hex 32
Beispiel: 8e71c20a29593b84f31ed8c4ae365318bd720490114565168c526f018847162a
3. Original-Konfiguration sichern
sudo cp /etc/nginx/nginx.conf /etc/nginx/nginx.conf.backup
Bei Bedarf stellst du sie so wieder her:
sudo cp /etc/nginx/nginx.conf.backup /etc/nginx/nginx.conf4. Nginx mit Publish-Authentifizierung konfigurieren
Öffne /etc/nginx/nginx.conf und ersetze den Platzhalter durch deinen eigenen Key:
Fertige nginx.conf herunterladen
sudo nano /etc/nginx/nginx.conf
user www-data;
worker_processes 1;
pid /run/nginx.pid;
include /etc/nginx/modules-enabled/*.conf;
events {
worker_connections 1024;
}
http {
include /etc/nginx/mime.types;
default_type application/octet-stream;
sendfile on;
keepalive_timeout 65;
map $arg_name $rtmp_publish_allowed {
default 0;
"HIER_DEINEN_STREAM_KEY_EINTRAGEN" 1;
}
server {
listen 127.0.0.1:8080;
server_name localhost;
access_log /var/log/nginx/rtmp-auth-access.log;
error_log /var/log/nginx/rtmp-auth-error.log;
location = /publish-auth {
if ($rtmp_publish_allowed = 0) {
return 403;
}
return 200;
}
}
server {
listen 8081;
server_name _;
access_log /var/log/nginx/rtmp-stat-access.log;
error_log /var/log/nginx/rtmp-stat-error.log;
location = / { return 302 /stat; }
location = /stat {
rtmp_stat all;
rtmp_stat_stylesheet stat.xsl;
add_header Cache-Control "no-store" always;
}
location = /stat.xml {
rtmp_stat all;
add_header Cache-Control "no-store" always;
}
location = /stat.xsl {
root /usr/share/nginx/html;
}
}
}
rtmp {
server {
listen 1935;
chunk_size 4096;
application live {
live on;
record off;
notify_method get;
on_publish http://127.0.0.1:8080/publish-auth;
allow publish all;
allow play all;
}
}
}
on_publish übergibt den Streamnamen als Parameter name. Die map erlaubt nur den eingetragenen Key; alle anderen Werte erhalten 403 Forbidden. worker_processes 1; ist für diesen Aufbau entscheidend: Bei mehreren Workern können Publisher, OBS und Statistik in unterschiedlichen Prozessen landen und den aktiven Stream nicht finden.
In Nano speicherst du mit Strg+O, Enter und beendest mit Strg+X.
4a. Formatierte RTMP-Statusseite installieren
Die Statusseite zeigt Server-Uptime, Bandbreite, Bytes In/Out, Streamname, Publisher, Clients, Video- und Audiodaten sowie die Stream-Laufzeit.
Fertige stat.xsl herunterladen
sudo cp stat.xsl /usr/share/nginx/html/stat.xsl
sudo chmod 644 /usr/share/nginx/html/stat.xsl
sudo nginx -t
sudo systemctl restart nginx
Formatierte Übersicht: http://DEINE-SERVER-IP:8081/stat
Rohe XML-Daten für NOALBS: http://DEINE-SERVER-IP:8081/stat.xml
5. Konfiguration prüfen und Nginx neu starten
sudo nginx -tStarte Nginx nur neu, wenn syntax is ok und test is successful erscheinen:
sudo systemctl restart nginx
sudo systemctl status nginx6. Firewall absichern
sudo apt install ufw -y
sudo ufw default deny incoming
sudo ufw default allow outgoing
sudo ufw allow OpenSSH
sudo ufw allow 1935/tcp
sudo ufw allow 8081/tcp
sudo ufw enable
sudo ufw status
Öffne Port 8080 nicht. Port 8081 wird mit dieser Regel dagegen für alle Quelladressen freigegeben, damit die Statistik extern erreichbar ist. Weitere Schutzmaßnahmen können später ergänzt werden.
7. Listener und Bindings kontrollieren
sudo ss -tulpn | grep 1935
sudo ss -tulpn | grep 8080
sudo ss -tulpn | grep 8081
RTMP darf auf 0.0.0.0:1935 lauschen. Für die Authentifizierung muss ausdrücklich 127.0.0.1:8080 erscheinen. Die Statusseite lauscht öffentlich auf Port 8081.
8. OBS als Sender konfigurieren
Öffne Einstellungen → Stream und wähle den Dienst Benutzerdefiniert.
Server: rtmp://DEINE-SERVER-IP/live
Stream-Key: DEIN_GEHEIMER_STREAM_KEY
Die vollständige Adresse ergibt sich als rtmp://DEINE-SERVER-IP/live/DEIN_GEHEIMER_STREAM_KEY.
9. Moblin konfigurieren
Lege in Moblin ein benutzerdefiniertes RTMP-Ziel an:
RTMP-Adresse: rtmp://DEINE-SERVER-IP/live
Stream-Key: DEIN_GEHEIMER_STREAM_KEY
Der Datenweg lautet dann: iPhone → Moblin → Linux-RTMP-Server → OBS.
10. Stream in OBS empfangen
Füge auf dem Empfangs-PC eine Medienquelle oder eine FFmpeg-kompatible Quelle hinzu und verwende:
rtmp://DEINE-SERVER-IP/live/DEIN_GEHEIMER_STREAM_KEY
Von dort kann OBS das Signal weiterverarbeiten und beispielsweise an Twitch, YouTube oder Kick senden.
11. Richtigen und falschen Stream-Key testen
- Starte einen Test mit einem absichtlich falschen Key wie
falscherkey. Publishing muss scheitern. - Wiederhole den Test mit deinem echten Key. Die Verbindung muss funktionieren.
- Prüfe zusätzlich, dass Port 8080 aus dem Internet nicht erreichbar ist.
12. Logs und Fehlerdiagnose
Beobachte bei Verbindungsproblemen die Nginx-Fehler und den Dienststatus live:
sudo tail -f /var/log/nginx/error.log
sudo journalctl -u nginx -f
Kontrolliere außerdem Tippfehler im Key, die öffentliche Server-IP, die UFW-Regel und ob dein Hosting-Anbieter TCP 1935 zusätzlich in einer externen Firewall freigeben muss.
13. Autostart nach einem Neustart prüfen
sudo systemctl enable nginx
sudo reboot
Nach dem erneuten Anmelden:
sudo systemctl status nginx
sudo ss -tulpn | grep 193514. Sicherheitsübersicht
| Komponente | Erreichbarkeit | Schutz |
|---|---|---|
| SSH, TCP 22 | Öffentlich, falls benötigt | UFW; idealerweise SSH-Key statt Passwort |
| RTMP, TCP 1935 | Öffentlich | Langer, zufälliger Publish-Key via on_publish |
| Auth, TCP 8080 | Nur 127.0.0.1 | Nicht in UFW freigeben |
| Status, TCP 8081 | Öffentlich | Derzeit vollständig freigegeben; Zugriffsschutz später ergänzen |
| Aufzeichnungen | Deaktiviert | record off; |
Internet
├── TCP 22 → SSH
├── TCP 1935 → RTMP → on_publish → Key-Prüfung
└── TCP 8080 ✕ blockiert
└→ nur intern: 127.0.0.1:8080
Wer den RTMP-Port findet, kann ohne den geheimen Key trotzdem keinen Stream veröffentlichen. Beachte: allow play all; schützt den Abruf nicht. Wenn auch das Ansehen privat sein soll, benötigst du zusätzlich eine Play-Authentifizierung oder einen separaten privaten Transportweg.