Anycast Voip Proxy
Contents
- Anycast Voip Proxy
- Kurzfassung
- Einleitung
- Anycast verstehen
- Quagga Konfiguration
- Secure Anycast Tunneling Protocoll (SATP)
- Kompatibilität mit Network Address Translation (NAT)
- Anycast Tunneling Daemon (anytun)
- Bauen vom Quelltext
- Starten des Programms
- Programm Optionen
- [-D|--nodaemonize]
- [-s|--sender-id ] <sender id>
- [-i|--interface] <ip-address>
- [-p|--port] <port>
- [-I|--sync-interface] <ip-address>
- [-S|--sync-port] <port>
- [-M|--sync-hosts] <hostname|ip>:<port>[,<hostname|ip>:<port>[...]]
- [-r|--remote-host] <hostname|ip>
- [-o|--remote-port] <port>
- [-d|--dev] <name>
- [-t|--type] <tun|tap>
- [-n|--ifconfig]
- [-w|--window-size] <window size>
- [-c|--cipher] <cipher type>
- [-K|--key] <master key>
- [-A|--salt] <master salt>
- [-k|--kd-prf] <kd-prf type>
- [-a|--auth-algo] <algo type>
- Beispiele:
- Debugging mit Wireshark
- Anycast RTP Media Relay (anyrtpproxy)
Kurzfassung
Dieses Dokument befasst sich mit einer speziellen Addressierungsform im Internet. Anycast Addressen erlauben es große skalierbare und fehlertolerante Services anzubieten. Diese Technik war bis jetzt nur für einfache Services im Einsatz. Wir beschäftigen uns mir dem Einsatz dieser Technik für komplexere Dienste, insbesondere für Telefonie. Zum Schutz der Datenübertragung wurde ebenfalls ein geeignetes Verschlüsselungs-Verfahren implementiert.
Einleitung
Viele Lebensbereiche sind bereits von modernen Technologien abhängig und werden zunehmend komplexer. So werden mittlerweile Telefonanschlüsse über das Internet (Voice over IP, kurz VoIP) für Endkunden angeboten. Diese sind vom herkömmlichen Telefonnetz hohe Zuverlässigkeit und Qualität gewöhnt. Um dies auch im Internet sicherstellen zu können, ist die Aufteilung auf mehrere Server und die automatische Übernahme von Gesprächen bei Ausfällen nötig. Gleichzeitig muss auf die Bedürfnisse der Betreiber eingegangen werden, die die Größe Ihre Netze an die Zahl der Benutzer anpassen müssen. Mit Hilfe von Anycast Addressierung können diese Ziele erreicht werden. Dies war bisher nur für einfache Dienste (wie DNS) möglich. Wir beschäftigen uns mit dem Einsatz von Anycast bei schwierigeren Problemen und haben ein generelles Protokoll erstellt, das komplexere Services erlaubt. Dabei konzentrieren wir uns auf die Übertragung von Telefongesprächen.
Anycast verstehen
Unter Anycast versteht man die mehrfache Vergabe einer IP-Adresse an mehrere Computer. Dies ist vergleichbar mit speziellen Telefonnummern. Sie können beispielsweise in ganz Österreich die Polizei unter der Nummer 133 erreichen. Je nachdem an welchem Ort sie sich aufhalten, erreichen sie den nächstgelegenen Polizeiposten. Sie müssen dabei nicht darüber informiert sein ob ein Polizeiposten in Ihrer Nähe geschlossen wurde oder ein neuer gebaut wurde, Sie können stets unter der selben Nummer den Polizeinotruf erreichen. Daher ist es für den Staat Österreich als Betreiber möglich auf die Überlastung einer Polizeistation einfach zu reagieren bzw. bei fehlendem Bedarf die Anzahl zu reduzieren.
Diese Vorteile, die wir im Telefonsystem lange kennen und meist nur unbewusst wahrnehmen, lassen sich auf die Kommunikation zwischen Computern übertragen. Mit dieser Technik ist es möglich innerhalb von Sekunden „Polizeistationen zu eröffnen“ also Server hinzuzufügen, die somit die zu erbringenden Services auf mehrere Rechner zu verteilen. Darüber hinaus nehmen die Daten immer den kürzesten Weg, da sie vom nächstgelegenen Server bearbeitet werden
Anycast im Internet
Anycast im LAN
Grundsätzlich eigenen sich mehrere Möglichkeiten zur Realisierung von Anycast Addressen im Internet. Die sicherlich einfachste ist die mehrfache Vergabe einer IP Adresse in einem Ethernet-LAN. Dadurch übernimmt stets der Rechner die Verbindung, der als erster auf eine ARP Anfrage antwortet. Diese extrem einfache Lösung führt bereits zur Erreichung einer hohen Ausfallssicherheit. Um zusätzlich auch ein gutes Verteilen der Last zu ermöglichen können spezielle Programme wie z.B. CARP eingesetzt werden.
Anycast in mittelgroßen Netzen
In mittelgroßen Firmen-Netzen kommen typischerweise bereits interne Routing Protokolle zum Einsatz. Diese können verwendet werden um ein Subnetz oder eine einzelne IP Adresse mehrfach anzukündigen. Clients verbinden sich dann jeweils zum aus Sicht des Routings nächstgelegenen Server.
Bei Netzen die über mehr als einen Upstream Provider verfügen, bietet sich die Möglichkeit an an jedem Border Router einen Anycast Server zu platzieren und diese in das interne Routing Protokoll aufzunehmen. Dadurch lässt sich eine hohe Ausfallssicherheit und gleichzeitig eine gute Lastverteilung bereits einfach realisieren.
Anycast global
Um global verteilte Anycast Server einsetzen zu können, also Server die nicht über ein eigenes Netzwerk verbunden sind, muss ein IP Netz im internationalen Routing angekündigt werden. Dies geschieht im Internet per BGP4. BGP4 ermöglicht es üblicherweise Netzen die mehre Upstreamprovider besitzen (d.h. multihomed sind) ihre Adressen über diese Leitungen erreichbar zu machen. Es ist aus der Sicht des Internets nicht feststellbar ob zwischen den Borderroutern Verbindungen bestehen. Es verhält sich folglich alles gleich wie beim zuvor beschriebenen Fall.
Von außen ist ein Anycast Netz nicht von einem gewöhnlichen multihomed Unicast Netz zu unterscheiden und wird somit im Internet voll unterstützt. Die Daten gelangen stets zu dem auf internationalen Wegen am kürzesten gelegenen Server.
Am besten ist es, die Maschine auf der die Anycast Serivces laufen gleichzeitig als BGP Router zu konfigurieren, da dann ein Hardwareausfall des Anycast Servers gleichzeitig zum Erlöschen der angekündigten Route führt. Dadurch erhält der Rechner automatisch keine Daten mehr und die anderen Anycast Server übernehmen seine Arbeit. Geeignet sind beispielsweise BSD oder Linux Systeme mit dem Routing Programm Quagga.
Dabei ist darauf zu achten, dass viele Provider Routing Informationen filtern. Es scheint üblich zu sein, Ipv4 Netze kleiner als /24 (256 IPv4 Adressen) und Ipv6 Netze kleiner als /32 (65536 Ipv6 Endnutzer Netze) zu filtern. Daher ist für den Betrieb eines Anycast Services nötig ein Netz dieser Größe zu verwenden. Um dennoch den hohen Bedarf an IP Adressen zu rechtfertigen, dürfte die Verwendung des Addressraums für mehrere Anycast Services nötig sein. Ebenfalls nötig ist eine eigene Autonomous System Nummer. Die Zuweisung dieser Nummern kann in Europa bei RIPE beantragt werden. Im Rahmen des von uns durchgeführten Projektes wurden uns vom RIPE NCC Adressen zu Testzwecken zur Verfügung gestellt.
Quagga Konfiguration
Bei den meisten Betriebsystemen muss Quagga erst installiert werden. Dies geschieht bei Debian und Ubuntu beispielsweise durch den Befehl „aptitude install quagga“. Danach kann mit der Konfiguration begonnen werden.
Die Konfigurations-Dateien befinden sich üblicher weise in /etc/quagga. Dort müssen die Dateien bgpd.conf und zebra.conf angelegt werden. Und in beide die die Zeile „line vty“ eingefügt werden. Dies ermöglicht das spätere Konfigurieren per Command Line Interface.
Anlegen der Konfiguration:
cd /etc/quagga echo „line vty“ > bgpd.conf echo „line vty“ > zebra.conf
Anschließend muss noch in der Datei „daemons“ die Zeile bgpd und zebra auf yes gesetzt werden.
vi daemons zebra=yes bgpd=yes ospfd=no ospf6d=no ripd=no ripngd=no isisd=no
Nach Restart von Quagga kann mit der eigentlichen Konfiguration begonnen werden.
/etc/init.d/quagga restart vtysh Hello, this is Quagga (version 0.99.5). Copyright 1996-2005 Kunihiro Ishiguro, et al. router#
Sollte auf Ihrem Bildschirm nur „(END)“ zu lesen sein, dann drücken sie Q und tippen Sie den Befehl „terminal length 0“
mit „show running-config“ lässt sich die aktive Konfiguration anzeigen, mit „configure terminal“ gelangt man die den Konfigurationsmodus. Dieser wird mit „end“ wieder verlassen. Das Speicher der Konfiguration erfolgt abschliessend durch den „write“ Befehl.
Eine gültige Konfiguration kann wie folgt aussehen (die Felder in <> sind durch die jeweiligen Adressen zu ersetzen):
interface eth0 ipv6 nd suppress-ra ! interface lo ip address <192.0.2.1>/32 ipv6 address <2001:DB8::1>/64 ! router bgp <99999> bgp router-id <192.0.2.1> network <192.0.2.0>/<24> neighbor <192.168.1.1> remote-as <99998> neighbor <2001:3GG::1> remote-as <99998> no neighbor <2001:3GG::1> activate ! address-family ipv6 network <2001:DB8::>/<32> neighbor <2001:3GG::1> activate exit-address-family ! ip route <192.0.2.0>/<24> Null0 250 ipv6 route <2001:DB8::>/<32> Null0 250 ! line vty !
Die Werte sind wie folgt zu ersetzen:
<192.0.2.0> Die IPv4 Netzwerkadresse des Netzes das für Anycast verwendet wird <192.0.2.1> die IPv4 Adresse innerhalb des Netzwerks, auf der der anycast Service läuft
<2001:DB8::> Die IPv6 Netzwerkadresse des Netzes das für Anycast verwendet wird <2001:DB8::1> die IPv6 Adresse innerhalb des Netzwerks, auf der der anycast Service läuft
<192.168.1.1> Die IPv4 Adresse des Uptream Provders <2001:3GG::1>Die IPv6 Adresse des Uptream Provders
<99999> Die eigene Autononmouse System Nummer <99998> Die Autononmouse System Nummer des Upstream Providers
Bitte beachten Sie, dass die obige Konfiguration ungültige IP-Adresse und AS Nummern enthält.
Secure Anycast Tunneling Protocoll (SATP)
Das „Secure Anycast Tunneling Protocoll“ stellt das Grundgerüst für komplexere Anycast Services zur Verfügung. Insbesondere stellt es Funktionen zur Verschlüsselung, Authentifizierung, dem Schutz vor Replay-Attacken, die Unterstützung von dynamischen IP Adressen und die Kommunikation mit Rechnern hinter Firewalls und NAT Routern bereit.
Verschlüsselung, Authentifizierung und Schutz vor Replay Attacken
Kompatibilität mit Network Address Translation (NAT)
Das Secure Anycast Tunneling Protocoll kann als eigenständiges Protokoll direkt auf IP Ebene oder über UDP verwendet werden. Die Implementierung Anytun realisiert die Übertragung über UDP, da dies mit handelsüblichen NAT Routern kompatibel ist.
Hier konzentriert sich die Lösung auf das Modell eines Unicast Clients hinter einem NAT Router der zu den Anycast Servern eine Verbindung herstellt. Beim schicken des ersten Anytun UDP Pakets wird im NAT Router ein Eintrag in der NAT Tabelle erstellt, der der Verbindung einen lokalen UDP Port zuweist. Der Anycast Server der das Paket empfängt erkennt automatisch aufgrund der Multiplex-Nummer im SATP-Paket um welchen Client es sich handelt. Die Identität wird bei aktivierter Authentifizierung zusätzlich durch eine kryptopgraphische Prüfsumme sichergestellt. Die IP Adresse und UDP Port Nummer werden anschließend zwischen den Anycast Servern syncronisiert, wodurch der Verbindungsaufbau abgeschlossen ist. Danach können alle Anycast Server mit dem Client kommunizieren. Bei Änderung der IP Adresse (typisch bei vielen Providern) oder bei Änderung des UDP Ports (typisch bei NAT Routern mit beschränkter NAT Tabelle) wiederholt sich der oben beschriebene Vorgang automatisch.
Da die IP Address- und Port-Erkennung direkt mit Datenpaketen arbeitet, passiert sie für den Client unsichtbar und verursacht keine Verbindungsabbrüche.
Anycast Tunneling Daemon (anytun)
Anytun stellt die Implementierung des Secure Anycast Tunneling Protocolls dar. Es handelt sich um eine komplette VPN Lösung ähnlich zu OpenVPN oder IPSec im Tunnel Modus. Allerdings erlaubt es den Aufbau von Tunneln zwischen einer beliebigen Kombination aus Anycast, Unicast und Multicast Rechnern.
Ermöglicht wird die Übertragung von IP oder Ethernet Daten.
Bauen vom Quelltext
Die aktuelle Source Code Version kann mittels Subversion vom Server geladen werden:
svn co https://anytun.org/svn/anytun
Stellen Sie sicher, dass alle im Readme erwähnten Programme auf Ihrem System installiert sind
Führen Sie nun folgende Befehle aus:
cd anytun ./configure cd Sockets make cd .. make
Bekannte Probleme:
Note: Cannot open TUN/TAP dev /dev/net/tun: No such file or directory (errno=2) Cannot open TUN/TAP dev /dev/anytun0: No such file or directory (errno=2)
Lösung:
modprobe tun cd /dev ./MAKEDEV tun
Editieren Sie /etc/modules und fügen Sie die Zeile
tun
ein um in Zukunf das Modul automatisch zu laden.
Starten des Programms
anytun ist grunsätzlich als Peer to Peer Applikation entwickelt worden. Es besteht also kein unterschied zwischen Client und Server. Folgende Parameter können übergeben werden:
anytun [-h|--help] prints this...
[-D|--nodaemonize] don't run in background
[-s|--sender-id ] <sender id> the sender id to use
[-i|--interface] <ip-address> local anycast ip address to bind to
[-p|--port] <port> local anycast(data) port to bind to
[-I|--sync-interface] <ip-address> local unicast(sync) ip address to bind to
[-S|--sync-port] <port> local unicast(sync) port to bind to
[-M|--sync-hosts] <hostname|ip>:<port>[,<hostname|ip>:<port>[...]]
remote hosts to sync with
[-r|--remote-host] <hostname|ip> remote host
[-o|--remote-port] <port> remote port
[-d|--dev] <name> device name
[-t|--type] <tun|tap> device type
[-n|--ifconfig] <local> the local address for the tun/tap device
<remote|netmask> the remote address(tun) or netmask(tap)
[-w|--window-size] <window size> seqence number window size
[-c|--cipher] <cipher type> payload encryption algorithm
[-K|--key] <master key> master key to use for encryption
[-A|--salt] <master salt> master salt to use for encryption
[-k|--kd-prf] <kd-prf type> key derivation pseudo random function
[-a|--auth-algo] <algo type> message authentication algorithm
Programm Optionen
[-D|--nodaemonize]
Mit dieser Option kann verhindert werden das das Programm im Hintergrund läuft.
[-s|--sender-id ] <sender id>
Die Sender Id wird für Anycast Tunnelendpunkte benötigt. Jder Anycast Rechner muss eine eindeutige ID haben (1,2,3,...). sie wird benötigt um beim Schutz vor Replay-Attacken die Sender unterscheiden zu können. Für Unicast Endpunkte hat diese Option keine Wirkung.
[-i|--interface] <ip-address>
Diese IP Adresse wird bei ausgehenden Paketen als Senderaddresse benutzt. Bei Anycast Tunnelendpunkten muss die Anycast IP benutzt werden. Bei Unicast Endpunkten wird die Addresse über die Routingtabelle meist automatisch richtig bestimmt.
[-p|--port] <port>
local anycast(data) port to bind to
Der lokale Port auf dem die Payload Daten verschickt und empfangen werden. Die 2 Tunnelendpunkte können verschiedene Ports benutzen. Besteht ein Tunnelendpunkt aus mehreren Anycast Rechnern, so müssen alle den selben Port benutzen.
[-I|--sync-interface] <ip-address>
local unicast(sync) ip address to bind to
Diese Option wird nur für Tunnelendpunkte benötigt die aus mehreren Anycast Rechnern bestehen. Hier kann die Unicast IP Addresse des Anycast Rechners angegeben werden. Die wird zur Kommunikation mit den anderen Anycast Rechnern benutzt.
[-S|--sync-port] <port>
local unicast(sync) port to bind to
Diese Option wird nur für Tunnelendpunkte benötigt die aus mehreren Anycast Rechnern bestehten. Über diesen Port kommunizieren die Anycast Rechner untereinander um Informationen über Tunnelendpunkte zu syncronisieren. Hier werden keine Payload-Daten übertragen.
Es ist möglich sich mit Telnet auf diesen Port zu verbinden und somit eine Liste der aktiven Verbindungen zu erhalten. Dieser Port erlaubt nur Lesezugriff und ist standardmässig nicht geschützt. Die Verwendung von Firewallregeln und eventuell IPSec wird empfohlen.
[-M|--sync-hosts] <hostname|ip>:<port>[,<hostname|ip>:<port>[...]]
remote hosts to sync with
Diese Option wird nur für Tunnelendpunkte benötigt die aus mehreren Anycast Rechnern bestehten. Hier müssen die Unicast Adressen aller anderen Anycast Rechner angegeben werden. Mit diesen Rechnern werden bestehtende Tunnelverbindungen syncronisiert.
[-r|--remote-host] <hostname|ip>
remote host
Hier kann der entfernte Tunnelendpunkt angegeben werden. Bei Anycast Tunnelendpunkten ist die Anycast Adresse zu verwenden. Wir keine Adresse angegeben, so wird diese beim ersten empfangenen Datenpaket automatisch erkannt.
[-o|--remote-port] <port>
remote port
Der zugehörige Port zum remote Host.
[-d|--dev] <name>
device name
Optional kann ein anderer Name für das Tunnel Interface gewählt werden. Standardmässig wird tap0 für Ethernet Tunnel Interfaces und tun0 für IP Tunnel verwendet.
[-t|--type] <tun|tap>
device type
Type der zu erzeugenden Tunnel. tap für Ethernet Tunnel, tun für IP Tunnel.
[-n|--ifconfig]
[-n|--ifconfig] <local> the local address for the tun/tap device
<remote|netmask> the remote address(tun) or netmask(tap)
Im tap/Ethernet Tunnel Modus:
Die lokale IP Adresse und Subnetmaskte des Tunnelinterfaces. Der entfernte Tunnelendpunkt muss eine andere IP Addresse im geleichen Subnet besitzen.
Im tun/IP Tunnel Modus:
Die lokale IP Addresse des Tunnelinterfaces und die IP Addresse des Tunnelinterfaces des entfernten Tunnelendpunkts.
[-w|--window-size] <window size>
seqence number window size
Pakete treffen manchmal beim Empfänger nicht in der Reihenfolge ein in der sie gesendet werden. Es wird eine Liste dieser größe geführt, die bestimmt welche Pakete bereits empfangen wurden. Trifft ein Paket ein, das laut Liste bereits empfangen wurde oder das länger in der Vergangenheit verschickt wurde als die Lsite lang ist, so wird es als Replay-Attacke interpretiert und verworfen. Der Wert 0 deaktiviert die Liste und den Schutz vor Replay-attacken. d.h. es werden keine Pakete auf Grund der Sequenz Nummer gefiltert.
[-c|--cipher] <cipher type>
payload encryption algorithm
Eingesetzte Verschlüsselung, mögliche Werte:
null - keine Verschlüsselung
aes-ctr - AES im Counter Modus
[-K|--key] <master key>
master key to use for encryption
Master Key in hexadezimaler Schreibweise, z.B. 01a2b3c4d5e6f708a9b0cadbecfd0fa1, mit einer vorgeschriebenen Länge von 32 Stellen (16 Byte).
[-A|--salt] <master salt>
master salt to use for encryption
Master Salt in hexadezimaler Schreibweise, z.B. 01a2b3c4d5e6f708a9b0cadbecfd, mit einer vorgeschriebenen Länge von 28 Stellen (14 Byte).
[-k|--kd-prf] <kd-prf type>
key derivation pseudo random function
Eingesetzte sichere Schlüsselableitung, mögliche Werte:
null - keine Verschlüsselung
aes-ctr - AES im Counter Modus
[-a|--auth-algo] <algo type>
message authentication algorithm
Verwendeter Authentifizierungsalgorithmus
null - keine Verschlüsselung
sha1 - HMAC-SHA1
Wenn HMAC-SHA1 verwendet wird wächst die Paketlänge um 10 Byte. In diesen 10 Byte werden die Authentifizierungsdaten gespeichert.
Beispiele:
ein Unicast und ein Anycast Tunnelendpunkt
Unicast Tunnelendpunkt:
./anytun -r anycast.anytun.org -d anytun0 -t tun -n 192.0.2.2 192.0.2.1 -w 0 -c null
Anycast Tunnelendpunkte
Auf dem Rechner mit Unicast Hostname: unicast1.anycast.anytun.org und Anycast Hostname: anycast.anytun.org
./anytun -i anycast.anytun.org -d anytun0 -t tun -n 192.0.2.1 192.0.2.2 -w 0 -S 23 -M unicast2.anycast.anytun.org:23,unicast3.anycast.anytun.org:23
Auf dem Rechner mit Unicast Hostname: unicast2.anycast.anytun.org und Anycast Hostname: anycast.anytun.org
./anytun -i anycast.anytun.org -d anytun0 -t tun -n 192.0.2.1 192.0.2.2 -w 0 -S 23 -M unicast1.anycast.anytun.org:23,unicast3.anycast.anytun.org:23
Auf dem Rechner mit Unicast Hostname: unicast3.anycast.anytun.org und Anycast Hostname: anycast.anytun.org
./anytun -i anycast.anytun.org -d anytun0 -t tun -n 192.0.2.1 192.0.2.2 -w 0 -S 23 -M unicast1.anycast.anytun.org:23,unicast2.anycast.anytun.org:23
mehrere Unicast zu einem Anycast Tunnelendpunkt
Anlegen einer Client Connection/Routing Table für den Server
./anytun-config -n 192.168.1.3 -w 0 -m 3 -k null > routingtable ./anytun-config -n 192.168.1.4 -w 0 -m 4 -k null >> routingtable ./anytun-config -n 192.168.1.5 -w 0 -m 5 -k null >> routingtable ./anytun-config -n 192.168.1.6 -w 0 -m 6 -k null >> routingtable ./anytun-config -n 192.168.1.7 -w 0 -m 7 -k null >> routingtable
Verschlüsselete Clients
./anytun-config -n 192.168.217.10 -m 10 -K aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa -A bbbbbbbbbbbbbbbbbbbbbbbbbbbb -w0 > routingtable ./anytun-config -n 192.168.217.11 -m 11 -K aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa -A bbbbbbbbbbbbbbbbbbbbbbbbbbbb -w0 >> routingtable ./anytun-config -n 192.168.217.12 -m 12 -K aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa -A bbbbbbbbbbbbbbbbbbbbbbbbbbbb -w0 >> routingtable
Eine Mischung aus verschlüsselten und unverschlüsselten Clients wird noch nicht unterstützt
Ansehen der Routingtabelle
perl -ne 'chomp; print' < routingtable | ./anytun-showtables
Routingtabelle+Updates Live betrachten
nc unicast1.anycast.anytun.org 23 | ./anytun-showtables
Starten des Routing Servers
./anytun-controld -f routingtable &
Durch Neustart des Routingservers werden automatische alle neuen Routen und Verbindungen von den Anycast Nodes aktualisiert.
Starten der Anycast Server
./anytun -i anycast.anytun.org -d anytun0 -t tun -n 192.168.1.1 192.168.1.2 -w 0 -m 2 -S 23 -M unicast1.anycast.anytun.org:23,unicast2.anycast.anytun.org:23,routingserver.anycast.org:1234 -c null ip route add 192.168.1.3 dev anytun0 ip route add 192.168.1.4 dev anytun0 ip route add 192.168.1.5 dev anytun0 ip route add 192.168.1.6 dev anytun0 ip route add 192.168.1.7 dev anytun0
Starten der Anycast Server mit Verschlüsselung
./anytun -i anycast.anytun.org -d anytun0 -t tun -n 192.168.1.1 192.168.1.2 -w 0 -m 2 -S 23 -M unicast1.anycast.anytun.org:23,unicast2.anycast.anytun.org:23,routingserver.anycast.org:1234 -K aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa -A bbbbbbbbbbbbbbbbbbbbbbbbbbbb ip route add 192.168.1.3 dev anytun0 ip route add 192.168.1.4 dev anytun0 ip route add 192.168.1.5 dev anytun0 ip route add 192.168.1.6 dev anytun0 ip route add 192.168.1.7 dev anytun0
Starten des eines Unicast Clients 3
./anytun -r anycast.anytun.org -d anytun0 -t tun -n 192.168.1.3 192.168.1.1 -w 0 -c null -m 3
Starten des eines Unicast Clients 4 mit Verschlüsselung
./anytun -r anycast.anytun.org -d anytun0 -t tun -n 192.168.1.4 192.168.1.1 -w 0 -c null -m 4 -K aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa -A bbbbbbbbbbbbbbbbbbbbbbbbbbbb
Debugging mit Wireshark
Mit Wireshark kann der SATP Datenverkehr aufgezeichnet und die einzelnen Packete analysiert werden. Dazu wurde ein spezielles Lua Skript erstellt, welches Wireshark um die Funktionalität erweitert SATP Packete zu analysieren und darzustellen. Der Lua Support ist in Wireshark "Version 0.99.7" enthalten, welche unter Debian "unstable" (Sid) mitgeliefert wird. Um diese Version unter Debian "stable" (Etch) verwenden zu können muss der Wireshark-Quellcode aus Debian "unstable" under Debian "stable" compiliert werden.
Das gleiche Problem mit Wireshark und Lua Support tritt bei Ubuntu "Feisty" auf: Für eine Wireshark Version mit Lua Support in Ubuntu "Feisty" muss man die Quellcode Dateien von Wireshark aus Ubuntu "Hardy" verwenden.
Generieren von .deb Packeten für Debian "Etch" und Ubuntu "Feisty":
Benötigte Packete zum generieren von Debian/Ubuntu Packges:
- build-essential
- fakeroot
Für Debian "Etch": Hinzufügen der "Sid"-Quellen zu /etc/apt/sources.list:
deb-src http://ftp.at.debian.org/debian/ sid main contrib non-free
Für Ubuntu "Feisty": Hinzufügen der "Hardy"-Quellen zu /etc/apt/sources.list:
deb-src http://archive.ubuntu.com/ubuntu/ hardy universe
Aktualisieren der lokalen Liste von verfügbaren Packeten:
aptitude update
Download der Quellcode Dateien von Wireshark:
apt-get source wireshark
Compilieren der Packete:
apt-get build-dep wireshark cd wireshark-0.99.7 fakeroot dpkg-buildpackage cd ..
Installieren der Wireshark Packete:
dpkg -i wireshark-common_0.99.7-1_i386.deb wireshark_0.99.7-1_i386.deb
Konfiguration von Wireshark:
Damit der Lua Support in Wireshark aktiv ist, muss in /usr/share/wireshark/wireshark/init.lua folgende Zeile
disable_lua = true; do return end;
auskommentiert, also auf folgende Zeile geändert werden:
-- disable_lua = true; do return end;
Ausführen von Wireshark mit Fähigkeit zur Analyse von anytun Packenten:
Ins anytun svn-Verzeichnis wechseln, und Wireshark mit folgenden Befehl starten:
wireshark -X lua_script:wireshark-lua/satp.lua
Das aktuelle Lua Skript ist im anytun svn-Verzeichnis unter https://anytun.org/svn/anytun/wireshark-lua/satp.lua verfügbar.
WICHTIG:
Die soeben erzeugte Wireshark Version enthält keinen offiziellen Support!
Diese Wireshark Version mit Lua Unterstützung sollte nicht als Superuser (root) laufen, da mögliche Sicherheitslücken in Wireshark von Angreifern ausgenutzt werden könnten um in das Hostsystem einzudringen. Das bringt jedoch den Umstand mit sich, dass keine Daten live aufgezeichnet, sondern nur bereits aufgezeichnete .pcap Dateien in Wireshark importiert und analysiert werden können. Das Aufzeichnen der .pcap Dateien kann mit einer Wireshark Version ohne Lua Unterstützung, oder mit einem anderen Programm, wie z.B. tcpdump, erfolgen.
Soll Wireshark trotzdem als Superuser ausgeführt werden müssen in /usr/share/wireshark/wireshark/init.lua folgende Änderungen vorgenommen werden:
Nachfolgende Zeile von
run_user_scripts_when_superuser = false
auf
run_user_scripts_when_superuser = true
ändern.
Nachfolgende Sektion von
-- disable potentialy harmful lua functions when running superuser if running_superuser then
auf
-- disable potentialy harmful lua functions when running superuser if false then
ändern.
Anycast RTP Media Relay (anyrtpproxy)
Das Anycast RTP Media Relay wird mit Hilfe von anyrtpproxy realisiert. Anyrtpproxy führt intern eine Tabelle der bestehenden RTP Verbindungen. Diese wird von OpenSER für alle Anycast Proxys gesetzt. Die Proxys syncronisieren dies Liste intern.
Anyrtpproxy aus dem Quelltext bauen
Anyrtpproxy wird gemeinsam mit Anytun entwickelt. Nach dem Erfolgreichen bauen von Anytun (siehe unten) kann er mittels
cd anyrtpproxy make
gebaut werden.
Anyrtpproxy konfigurieren / starten
Anyrtpproxy wird nur durch Command Line Argumente konfigureiert. Es gibt keine Konfigurations dateien.
Eraubte Parameter sind
anyrtpproxy [-h|--help] prints this...
[-t|--chroot] chroot and drop priviledges
[-u|--username] <username> in case of chroot run as this user
[-c|--chroot-dir] <directory> directory to make a chroot to
[-d|--nodaemonize] don't run in background
[-s|--control] <addr[:port]> the address/port to listen on for control commands
[-p|--port-range] <start> <end> port range used to relay rtp connections
[-n|--nat] enable permantent automatic nat detection(use only with anytun)
[-o|--no-nat-once] disable automatic nat detection for new connections
[-S|--sync-port] <port> local unicast(sync) port to bind to
[-M|--sync-hosts] <hostname|ip>:<port>[,<hostname|ip>:<port>[...]]
List of Remote Sync Hosts/Ports
Erklärung
[-t|--chroot]
Erlaubt dem Programm sich automatisch in eine Verzeichnis zu sperren (Chroot) und alle überflüssigen Syswtemrechte abzugeben
[-u|--username] <username>
Falls Chroot aktiviert ist, ändert das Programm nach erfolgreichem Chroot seine Benutzer Rechte auf den ausgewählten User.
[-c|--chroot-dir] <directory>
Das Verzeichnis in das sich das Programm chrooten soll. In diesm Verzeichnis sollte die Datei dev/log existieren.
[-d|--nodaemonize]
Lässt das Programm im Vordergrund laufen
[-s|--control] <addr[:port]>
Der UDP Controll - Port. Er wird zu kommunikation mit OpenSER benutzt.
[-p|--port-range] <start> <end>
Die lokalen UDP Ports, welche für die Weiterleitung von RTP Paketen verwendet werden. Diese dürfen sich für verschiedene Anycast Server nicht überschneiden!
[-n|--nat]
Unterstützung für veränderliches NAT und dynamische IP Adressen. Diese Option führt dazu, dass nach jedem erhaltenen RTP Paket die Verbindung auf dessen IP Adresse und Port umgeleitet wird. Dies sollte nur dann aktiviert werden, wenn die Pakete zuvor authentifizeirt wurden (beispielsweise mittels Anytun)
[-o|--no-nat-once]
Deaktiviert das automatische Ändern der Verbindungs IP Adresse, falls das erste RTP Paket das empfangen wird nicht mit den Daten von OpenSER übereinstimmt. Das Angeben dieser Option erhöht die Sicherheit, erfordert aber, dass entweder alle verbundenen Clients direkt erreichbar sind (kein NAT Router oder über Tunnel) oder für alle Cients hinter NAT funktionierendes NAT Transversal (z.B. STUN) verwendet wird.
[-S|--sync-port] <port>
Der lokale Port der zur Kommunikation mit anderen anyrtpproxies verwendet wird.
[-M|--sync-hosts] <hostname|ip>:<port>[,<hostname|ip>:<port>[...]]
Eine Liste aller anyrtpproxies die gemeinsam mit diesem anyrtpproxy eine anycast IP Addresse teilen. In der Liste muss immer die jeweilige Unicast Addresse aller anderen anyrtpproxies angegeben werden. Als Port ist der mit der Option -S angegebene Sync Port zu verwenden.
Anyrtpproxy mit Firewall Regeln schützen
Der Controllport sollte jedenfalls per Firewall beschränkt werden:
iptables -A INPUT --protocol udp --destination-port 22222 -s 192.0.2.1 -j ACCEPT iptables -A INPUT --protocol udp --destination-port 22222 -j DROP
Openser konfigurieren
Eine Beispiel Konfiguration für OpenSER finden sie hier. Im Prinzip ist es eine normale OpenSER Konfiguration mit NAT Support nur das in jedem Fall ein RTP-Proxy dazwischengeschaltet wird und nicht nur wenn ein Client hinter Nat erkannt wird.
# ----------- global configuration parameters ------------------------
fork=yes
port=5060
log_stderror=no
debug=3
alias=voip.anytun.org:5060
check_via=no # (cmd. line: -v)
dns=yes # (cmd. line: -r)
rev_dns=yes # (cmd. line: -R)
children=4
fifo="/tmp/openser_fifo"
fifo_db_url="mysql://<user>:<passwd>@localhost/anytun"
# ------------------ module loading ----------------------------------
loadmodule "/usr/lib/openser/modules/mysql.so"
loadmodule "/usr/lib/openser/modules/sl.so"
loadmodule "/usr/lib/openser/modules/tm.so"
loadmodule "/usr/lib/openser/modules/rr.so"
loadmodule "/usr/lib/openser/modules/textops.so"
loadmodule "/usr/lib/openser/modules/maxfwd.so"
loadmodule "/usr/lib/openser/modules/usrloc.so"
loadmodule "/usr/lib/openser/modules/registrar.so"
loadmodule "/usr/lib/openser/modules/auth.so"
loadmodule "/usr/lib/openser/modules/auth_db.so"
loadmodule "/usr/lib/openser/modules/uri_db.so"
loadmodule "/usr/lib/openser/modules/nathelper.so"
## ----------------- setting module-specific parameters ---------------
modparam("auth_db|uri_db", "db_url", "mysql://<user>:<passwd>@localhost/anytun")
modparam("auth_db", "calculate_ha1", 1)
modparam("auth_db", "password_column", "password")
modparam("usrloc", "db_url", "mysql://<user>:<passwd>@localhost/anytun")
modparam("usrloc", "db_mode", 2)
modparam("rr", "enable_full_lr", 1)
modparam("nathelper", "rtpproxy_sock", "udp:<anyrtpproxy-unicast-ip>:22222")
# ------------------------- request routing logic -------------------
route{
# initial sanity checks -- messages with
# max_forwards==0, or excessively long requests
if (!mf_process_maxfwd_header("10")) {
sl_send_reply("483","Too Many Hops");
exit;
};
if (msg:len >= 2048 ) {
sl_send_reply("513", "Message too big");
exit;
};
# we record-route all messages -- to make sure that
# subsequent messages will go through our proxy; that's
# particularly good if upstream and downstream entities
# use different transport protocol
if (method!="REGISTER")
record_route();
if (method=="BYE" || method=="CANCEL") {
unforce_rtp_proxy();
};
# subsequent messages withing a dialog should take the
# path determined by record-routing
if (loose_route()) {
route(4);
route(1);
};
if (!uri==myself) {
route(4);
route(1);
};
if (method=="ACK") {
route(1);
} if (method=="INVITE") {
route(3);
} else if (method=="REGISTER") {
route(2);
};
lookup("aliases");
if (uri!=myself) {
route(4);
route(1);
};
# native SIP destinations are handled using our USRLOC DB
if (!lookup("location")) {
sl_send_reply("404", "Not Found");
exit;
};
route(1);
};
if (!uri==myself) {
route(4);
route(1);
};
if (method=="ACK") {
route(1);
} if (method=="INVITE") {
route(3);
} else if (method=="REGISTER") {
route(2);
};
lookup("aliases");
if (uri!=myself) {
route(4);
route(1);
};
# native SIP destinations are handled using our USRLOC DB
if (!lookup("location")) {
sl_send_reply("404", "Not Found");
exit;
};
route(4);
route(1);
}
route[1] {
# send it out now; use stateful forwarding as it works reliably
# even for UDP2TCP
if (!t_relay()) {
sl_reply_error();
};
exit;
}
route[2] {
sl_send_reply("100", "Trying");
if (!www_authorize("","subscriber")) {
www_challenge("","0");
exit;
};
if (!check_to()) {
sl_send_reply("401", "Unauthorized");
exit;
};
consume_credentials();
if (!save("location")) {
sl_reply_error();
};
exit;
}
route[3] {
if (!proxy_authorize("","subscriber")) {
proxy_challenge("","0");
exit;
} else if (!check_from()) {
sl_send_reply("403", "Use From=ID");
exit;
};
consume_credentials();
lookup("aliases");
if (uri!=myself) {
route(4);
route(1);
};
if (!lookup("location")) {
sl_send_reply("404", "User Not Found");
exit;
};
route(4);
route(1);
}
route[4] {
if (method=="INVITE") {
force_rtp_proxy("","<anyrtpproxy-anycast-ip>");
};
}
onreply_route {
if (!search("^Content-Length:[ ]*0")) {
force_rtp_proxy("","<anyrtpproxy-anycast-ip>");
};
}