Voice Over IP - protokol SIP

Obsah

  1. Úvod do protokolu SIP
  2. Konfigurace serveru
  3. Konfigurace klienta
  4. SIP a překlad adres (NAT)
  5. Bezpečnost protokolu SIP

1. Úvod do protokolu SIP

SIP (Session Initiation Protocol) byl vyvinut organizací IETF (je popsán v RFC3261), a proto se podobá ostatním internetovým protokolům. Je založen na zprávach v textovém formátu. Zprávy se posílají v UDP paketech na port 5060. Hlavička paketů se podobá např. e-mailům (jsou v ní mimo jiné položky From: a To:). Stejně tak adresy uživatelů mají tvar jako e-mailové adresy, např. sip:joe@example.com. Narozdíl od e-mailu se nepoužívá nic jako MX záznamy - v uvedeném případně je kontaktován přímo server s DNS jménem example.com podobně jako u Jabberu. Oznámení o úspěchu nebo chybě používají chybové kódy podobné HTTP, např. 200 OK nebo 401 Unauthorized.

SIP ovšem není jediný protokol pro VoIP, existují i další:

SIP samotný však pro VoIP nestačí: slouží jen k výměně informací nutných ke spojení (které nemusí být jen hlasové). Konkrétně to znamená, že si účastníci hovoru vymění svoje IP adresy (pokud v tom cítíte problém, máte pravdu, budu se tomu věnovat ve čtvrté kapitole). Domluva kodeku probíhá pomocí protokolu RTP, který se přenáší v těle SIP paketů. Samotný hovor je pak prostý stream UDP paketů posílaný na IP adresu příjemce (používají se porty nad 7000). Neprovádí se žádné přeposílání ztracených paketů, zamaskování ztrát je ponecháno na kodeku.

Další informace najdete v SIP Introduction.

2. Konfigurace serveru

V nejjednodušším případě ani server není potřeba, lze volat přímo na IP adresu počítače, za předpokladu že na počítači běží SIP klient a je dostupný na portu 5060 (není za překladem adres). Ovšem pak je problém s dynamickými IP adresami a také nelze zjistit, kdo je zrovna online (jinak než tak, že mu zkusíte zavolat).

Pro běžné použití je tedy server potřeba. Server má dvě funkce, které nutně nemusí vykonávat jeden počítač (nebo program):

Pravděpodobně nejpokročilejším open source serverem je Asterisk. Podporuje nejen protokol SIP, ale i H.323 nebo vlastní protokol IAX. Funguje jako kompletní ústředna, včetně možnosti napojení na klasickou telefonní síť. Dokonce umožňuje naprogramovat známé "pokud chcete mluvit se živým operátorem, stiskněte osmičku". Za to vše však platí velmi komplikovanou konfigurací - konfigurační soubory si ničím nezadají se Sendmailem, a je jich asi 3x tolik.

Výrazně jednodušší je SIP Express Router. Po nainstalování stačí v /etc/ser/ser.cfg nastavit DNS jméno serveru:

listen=praha12.net

Pak už jen ve firewallu povolte UDP port 5060, a server by měl přijímat registrace a dovolit navázání spojení. Kdokoli se však bude moci zaregistrovat pod libovolným jménem a bez hesla, což asi není úplně bezpečné. Je vhodné nastavit přihlašování pomocí jména a hesla, která mohou být uložena např. v databázi MySQL. Vytvořte databázi příkazem

/usr/sbin/ser_mysql.sh

Velmi doporučuji změnit heslo pro vytvořeného uživatele ser - výchozí nastavení je "heslo", je vidět že server vyvíjí Češi :-)

A nyní v /etc/ser/ser.cfg odkomentujte několik řádek, čímž zapnete autentizaci podle údajů MySQL databázi:

loadmodule "/usr/local/lib/ser/modules/mysql.so"
loadmodule "/usr/local/lib/ser/modules/auth.so"
loadmodule "/usr/local/lib/ser/modules/auth_db.so"
modparam("auth_db", "calculate_ha1", yes)
modparam("auth_db", "password_column", "password")
modparam("usrloc", "db_url", "mysql://ser:xxxxxx@localhost/ser")

Místo xxxxxx zapište heslo do databáze pro uživatele ser, a nezapoměnte nastavit práva k ser.cfg, aby jej mohl číst pouze server!

Nyní můžete přidávat uživatele příkazem

serctl add jméno heslo e-mail

Kompletní návod na instalaci najdete na SER HowTo.

Nastavení KPhone

3. Konfigurace klienta

Konfigurace je u různých klientů různě komplikovaná, snad nejjednodušší je KPhone. Základní nastavení je v menu File/Identity. Na obrázku vpravo je konfigurace pro uživatele s SIP adresou sip:joe@example.com. Po stisknutí tlačítka Register se KPhone zeptá na heslo, zaregistruje na server a volání by již mělo fungovat. KPhone ve výchozím nastavení používá ALSA, OSS lze zvolit v Preferences/Audio preferences.

4. SIP a překlad adres (NAT)

Již jsem zmínil, že práce protokolu SIP končí ve chvíli, kdy si klienti vymění svoje IP adresy. To však stačí jen tehdy, kdy se klienti nenachází za překladem adres, dnes tedy spíše ve vyjímečných případech. Problém nejde vyřešit ani prostým přesměrováním portů, klient posílá svojí privátní IP adresu v těle paketu, NAT ji nijak nezmění.

Prvním řešením je použití STUN serveru (program stund). STUN funguje jednoduše, prostě mu pošlete UDP paket na port 3478, a on vám odpoví paketem s vaší vnější (veřejnou) adresou a portem, ze kterého mu paket přišel. Tuto adresu pak klient pošle druhé straně. V některých se dokonce pomocí STUN serveru mohou spojit i 2 klienti, kteří jsou oba za překladem adres - podle odpovědí STUN serveru se pokusí uhodnout, jaký port přidělí NAT pro jejich vzdálenou komunikaci. Mě se to nikdy nepovedlo, ale prý by to mělo fungovat.

Spolehlivější řešení je použít proxy server na veřejné IP adrese, typicky na bráně z privátní sítě do Internetu. Nemůže to být však obyčejná SIP Proxy (ta jen předává SIP pakety a do RTP části nezasahuje), ale RTP Proxy. Ta musí měnit IP adresy v paketech tak, aby hovor procházel přes ní. Já jsem vyzkoušel program siproxd.

Konfigurace se nachází v /etc/siproxd.conf. Základní parametry jsou síťové rozhraní do vnitřní sítě a rozhraní do Internetu:

if_inbound  = eth0
if_outbound = eth1

Dále je nutno povolit, ze kterých adres mohou přicházet volání a které adresy jsou považování za lokální (mohou se z nich registrovat uživatelé):

hosts_allow_sip = 0.0.0.0/0
hosts_allow_reg = 10.0.0.0/8

A to je vše. Siproxd umí fungovat jako registrátor, ale zároveň se dokáže chovat transparentně k registrátoru mimo privátní síť - pak je nutno nastavit i klienta (v KPhone zadejte adresu serveru, kde běží siproxd do políčka "Outbound Proxy"). Bohužel siproxd automaticky směřuje i hovory v rámci lokální sítě přes sebe, ve složitejší síti to může znamenat zbytečné plýtvání kapacitou spojů. Vytvořil jsem vlastní patch, který způsobí, že siproxd nebude do lokálních hovorů nijak zasahovat:

diff -ru siproxd-0.5.11.orig/src/proxy.c siproxd-0.5.11/src/proxy.c
--- siproxd-0.5.11.orig/src/proxy.c     Fri Apr 22 00:41:02 2005
+++ siproxd-0.5.11/src/proxy.c  Sat Oct  1 18:04:35 2005
@@ -947,9 +947,27 @@
    sdp_media_t *sdp_med;
    int rtp_direction=0;
    int have_c_media=0;
+
+   int i;
+   int num_local=0;

    if (configuration.rtp_proxy_enable == 0) return STS_SUCCESS;

+   /* Do not proxy calls inside of local network */
+   for (i=0; i<URLMAP_SIZE; i++) {
+     if (urlmap[i].active == 0) continue;
+     if (compare_url(mymsg->to->url, urlmap[i].reg_url)==STS_SUCCESS ||
+         compare_url(mymsg->from->url, urlmap[i].reg_url)==STS_SUCCESS)
+       num_local++;
+
+     if(num_local == 2) {
+        DEBUGC(DBCLASS_PROXY, "Internal call from %s@%s to %s@%s",
+            mymsg->from->url->username, mymsg->from->url->host,
+            mymsg->to->url->username, mymsg->to->url->host);
+        return STS_SUCCESS;
+     }
+   }
+
    /*
     * get SDP structure
     */

5. Bezpečnost protokolu SIP

Autentizace při registraci se provádí metodou challenge-response, nelze tedy osposlechnout heslo jako u protokolů FTP nebo POP3. Nicméně žádná další autentizace prováděna není (např. server vůči uživateli, nebo uživatelé vůči sobě). Obsah paketů také šifrovaný není, lze tedy odposlechnout kdo s kým komunikuje (narozdíl od Skype, které však šifrování používá spíše jako obranu proti reverse engineeringu, ne na ochranu hovorů). Stejně tak samotný hovor není šifrován, ale na to už existuje řešení. Zfone je SIP klient od Phila Zimmermana (autora PGP), který podporuje šifrování, nicméně jen pro komunikaci s jiným Zfone klientem. Používaný protokol ZRTP byl ale vydán jako draft standardu, takže se snad podpory dočkáme i v dalších klientech.