RTSP und IPTables

13.04.2011

Das Realtime Streaming Protocol kurz RTSP wird genutzt um den Verbindungsaufbau mit Streamingservern zu koordinieren. Die Mobilversion von YouTube nutzt beispielsweise dieses Protokoll. Nach dem Verbindungsaufbau werden die Nutzdaten dann meist über RTP übertragen. Da dieses UDP-basierte Protokoll die verwendeten Ports dynamisch aushandelt, ist es schwierig, dieses ohne geeignetes Conntrack-Modul durch die Firewall zu bekommen. Wenn man also - so wie ich - eine IPTables-Firewall nutzt um den eingehenden und ausgehenden Traffic zu filtern, so hat man mit RTSP ein Problem.

Zwar gibt es für RTSP wohl irgendwo ein Conntrack-Modul, jedoch ist es in den meisten Distributionen nicht verfügbar. Wer jedoch nur einige bestimmte Seite (z.B. YouTube Mobile) zum laufen bekommen will, kann sich eines einfachen Tricks bedienen: Man öffnet einfach den nötigen UDP-Port-Range für ein bestimmte Zeit, wenn die Firewall vorher eine RTSP-Verbindung gesehen hat. Hierfür bietet das IPTables-Modul recent die nötigen Voraussetzungen. Es führt eine benannte Liste, in welche IP-Adressen und Zeitstempel hinzugefügt werden können. Später kann in der Liste nachgesehen werden, ob in den letzten X Sekunden ein Datenpaket an die angegebene IP-Adresse gesehen wurde.

D. h. um YouTube Mobile ausgehend durch eine IP-Tables Firewall nutzen zu können, genügen folgende Firewallregeln:

iptables -s <Internes Netz> -A FORWARD -p tcp -m tcp --dport 554 -m recent --name rtsp --set -m comment --comment "RTSP für Media Streaming" -j ACCEPT
iptables -s <Internes Netz> -A FORWARD -p udp -m udp --dport 10000:11000 -m recent --name rtsp --update --seconds 10 -m comment --comment "RTSP UDP erlauben, wenn vorher RTSP auf Port 554 gesprochen wurde." -j ACCEPT

Die erste Zeile erlaubt ausgehende Verbindungen auf Port 554 (RTSP). Bei <Internes Netz> ist jeweils das Netzwerk und die Maske für das interne Netzwerk anzugeben, in welchem sich die Clients befinden (z.B. 192.168.0.0/16). Der Abschnitt -m recent --name rtsp --set fügt nun die Quelladresse des internen Clients zur Recent-Liste hinzu. Dieser Client darf nun die nächten 10 Sekunden lang UDP-Pakete verschicken. Hierfür sorgt die zweite Zeile. Sie erlaubt den UDP-Portbereich 10000 bis 11000 (passend zu YouTube Mobile) für den Client. Die Option --update sorgt dafür, dass auch die UDP-Pakete den Zeitstempel der Quell-Adresse anpassen und somit das Zeitfenster weiter offen bleibt. Die Option --seconds 10 legt fest, dass 10 Sekunden nach dem letzten RTSP oder UDP-Paket keine weiteren Pakete mehr akzeptiert werden.

Damit das alles funktioniert, ist natürlich noch das normale Connection-Tracking notwendig. Ansonsten werden die UDP-Antwortpakete von der Firewall nicht akzeptiert. Also irgendwo in der Konfiguration muss noch die folgende Regel eingetragen werden:

iptables -A FORWARD -m state --state RELATED,ESTABLISHED -j ACCEPT

Da dieser Eintrag aber normalerweise Teil einer größeren Firewallkonfiguration ist, gehe ich hier nicht weiter darauf ein.

Um nachzusehen, welche Verbindungen gerade in der Recent-Liste stehen, kann man das vom Recent-Modul bereitgestellte Verzeichnis im Proc-Dateisystem nutzen:

cat /proc/net/xt_recent/rtsp

Dies gibt die gespeicherten Statistik-Informationen und Zeitstempel aus und kann zur Fehlerdiagnose sehr nützlich sein.

Mit dieser Konfiguration kann nun z.B. ein Android Smartphone problemlos RTSP-Inhalte von YouTube Mobile abspielen, ohne dass größere Löcher in die Firewall gebohrt werden müssen.