Cisco 79x1 za NATem

Diskuze o telefonování a telefonních službách, rady, návody, připomínky, ...
Odpovědět
Marek
Příspěvky: 4
Registrován: čtv 09. srp 2012 7:45:14

Cisco 79x1 za NATem

Příspěvek od Marek »

Dobrý den.

Během hovoru s technickou podporou Odoriku padl návrh, abych svůj problém s telefonem zkusil popsat zde na fóru. Jednak proto, abych mohl podat víc přesnějších informací o co vlastně jde, a za druhé aby tato diskuze mohla sloužit jako jakýsi "návod" pro případné další majitele telefonů stejné generace. Předně říkám, že nejsem odborník, spíše nadšený amatér. Mám tedy jakousi představu a nějaké základní znalosti, ale spoustu věcí si možná představuji zjednodušeně nebo si je domýšlím.

Téma se týká IP telefonů Cisco z "nové" řady využívající XML konfiguraci a firmware postavený na Javě. Konkrétně se jedná o populární modely 7961/41, ale také např. 7970 nebo levnější jednolinkové 7911/06. Tyto mám vyzkoušené, ale předpokládám že i ostatní z aktuální rodiny "Cisco Unified IP Phone" se budou chovat úplně stejně.

Jádrem problému je následující: Telefon SIP požadavky o registraci zasílá z náhodně generovaných portů, odpověď však očekává na jiném, pevně definovaném portu (typicky 5060). Jedná se o známé chování, pro úplnost přikládám citaci ze stránky Asterisk phone cisco 79x1 xml configuration files for SIP na Voip-Info.org:
Note that as of version 8.0(2)SR1 the phone sends UDP SIP requests from a high source port. This means that it will send from (for example) source port 50116 to SIP port 5060 on the SIP server. This is acceptable behaviour as per the SIP RFC, but it is different to the Cisco ATA and 7940 SIP software (and many but not all phones) and may have ramifications on your firewall rules if you are expecting the phone to send packets out from source port 5060 as well (as you may have with 7940 and ATAs etc). There are a few phones around which behave in the same way although most don't - this is not a cisco specific behaviour and is NOT a bug.
Netuším, co Cisco k této implementaci vedlo, ale zkrátka je to tak a nelze s tím nic dělat - chování je pevně definované ve firmwaru a uživatel může změnit pouze onen konkrétní port, na kterém zařízení naslouchá.

Pro reálné použití to však má velmi nepříjemné důsledky. Běžný uživatel se totiž k ústředně připojuje přes NAT na svém domácím routeru (a obecně takových NATů může být na cestě mezi telefonem a ústřednou v podstatě libovolný počet). Když dojde k překladu adres, NAT může, ale také nemusí zachovat zdrojový port, ze kterého telefon SIP požadavek odeslal. To znamená, že aby odpověď ústředny prošla zpět napůl otevřenými vrátky NATu, musí být adresována zpět na tento náhodný port, ze kterého telefon resp. NAT požadavek odeslal. Taková odpověď úspěšně projde NATem zpátky až k telefonu ... a ten ji zahodí, protože ji očekával na portu 5060.

Zde přikládám několik screenshotů z Wiresharku, které demonstrují výše popsané chování:
Cisco zasílá požadavek REGISTER z náhodně vygenerovaného portu 50932. V SIP hlavičce však uvádí Sent-by port: 5060, tedy port, kde očekává odpověď.
Cisco zasílá požadavek REGISTER z náhodně vygenerovaného portu 50932. V SIP hlavičce však uvádí Sent-by port: 5060, tedy port, kde očekává odpověď.
register.png (29.79 KiB) Zobrazeno 6941 x
Ústředna zasílá odpověď na REGISTER, která je fyzicky i na úrovni SIPu adresována na port 50932.
Ústředna zasílá odpověď na REGISTER, která je fyzicky i na úrovni SIPu adresována na port 50932.
reply.png (30.3 KiB) Zobrazeno 6941 x
Odpověď ústředny adresovaná na port 50932 vyvolává ICMP - port unreachable, protože Cisco naslouchá na portu 5060.
Odpověď ústředny adresovaná na port 50932 vyvolává ICMP - port unreachable, protože Cisco naslouchá na portu 5060.
unreachable.png (31.8 KiB) Zobrazeno 6941 x
V popisu prvního screenshotu jsem zmínil, že ačkoliv telefon UDP pakety zasílá z náhodného portu, na úrovni SIPu ústředně sděluje, že požadavek byl "Sent-by port: 5060". Zde se dostávám do roviny spekulací, avšak působí to na mě jako potvrzení výše uvedené anglické citace, že chování není tak úplně výmysl Cisco, ale má nějaký základ v SIP RFC.

Toto totiž souvisí i s vlastnostmi ústředny Asterisk. Bylo mi sice řečeno, že Odorik na Asterisku neběží, pro demonstraci však budu dále mluvit o Asterisku, protože jej znám. V nastavení sip.conf, kde jsou definovány jednotlivé pobočky lze totiž každé určit nastavení NATu. Pokud je definováno "nat=yes", Asterisk se chová "logicky" dle zákonitostí sítí - z jakého portu mi požadavky o registraci přišly, na takový port odpovídám. To proto, aby komunikace úspěšně prošla případnými NATy po cestě, které mohly zdrojový port libovolně měnit. Pokud však nastavíme "nat=no", Asterisk začně brát v úvahu obsah SIP hlavičky - odpovědi zasílám na takový port, který si zařízení SIP požadavkem vyžádalo.

Výše uvedené má za následek, že Cisco telefony 79x1 fungují naprosto bez problému, pokud je ústředna Asterisk ve stejné lokální síti a v nastavení poboček je uvedeno "nat=no". Toto mám ověřeno.


Takže jsme se konečně dostali k základní otázce - jak na základě výše uvedených znalostí zprovoznit Cisco telefony 79x1 v Internetu, resp. s Odorikem?

Momentálně mě napadají dvě možná řešení. První mi přijde o něco elegantnější, ale není použitelné vždy. Za předpokladu, že mezi telefonem a ústřednou je pouze jeden NAT - na domácím routeru uživatele, mělo by fungovat následující:
  1. Na ústředně nastavíme NAT=no, aby odpovědi zasílala ne zpět na port odkud požadavek přišel, ale ne port specifikovaný v SIP hlavičce.
  2. Na domácím routeru otevřeme port 5060 a nastavíme klasický port forwarding na IP adresu telefonu.
Toto řešení by vyžadovalo podporu ze strany ústředny - ať už manuální zásah do konfigurace pro konkrétní pobočku, nebo přidat do webové administrace možnost měnit NAT=yes/no přímo uživatelem. Zde tedy předpokládám, že ústředna Odoriku se chová podobně jako Asterisk. Tento způsob lze aplikovat i na uživatele s více než jedním telefonem - jak jsem se dříve zmínil, port na kterém telefon naslouchá lze specifikovat. Stačí tedy každému telefonu přiřadit jiný port a na NATu vytvořit odpovídající počet přesměrování.

Druhé řešení, opět pouze teoretické:
  1. Na ústředně se nic nemění, odpověď je stále zasílána na stejný port, odkud přišel požadavek
  2. Na posledním NATu před telefonem vytvoříme pravidlo, které zajistí, že všechny odpovědi od ústředny budou adresovány na port 5060
Toto by mělo fungovat i pokud je na cestě více než jen jeden NAT a nevyžaduje žádné zásahy na straně ústředny. Vyvstává však několik otázek - jak takové pravidlo vytvořit? Experimentoval jsem se svým domácím routerem, na kterém běží firmware na bázi linuxu a umožňuje zadávat pravidla přes iptables, nepodařilo se mi ale vymyslet takový zápis, který by zajisti potřebnou změnu portů typu "many-to-one". Také mě napadá, zda by pravidlo nebylo příliš obecné a nezačalo pozměňovat i jiné pakety, než jenom žádosti o registraci? Samozřejmě by bylo omezené na UDP, source-address ústředny a source-port 5060, ale nedokáži spolehlivě říct, zda to stačí.


No a zde bych tedy prosil o vyjádření ze strany Odoriku a případné komentáře uživatelů. Zejména by mě zajímalo, zda existuje reálná šance aplikovat 1. navržené řešení a zda by podle vás bylo funkční. Případně bych potřeboval poradit, jak by mělo vypadat pravidlo pro iptables vyžadované 2. navrženým řešením - už jsem nad tím strávil nějakou dobu, ale zatím se mi funkční zápis (který by fungoval na mém routeru) nedaří vymyslet.

A také děkuji za trpělivost všem, kteří dočetli až do konce :)
Uživatelský avatar
xsouku04
Administrátor
Příspěvky: 8162
Registrován: pát 15. říj 2010 11:11:44
Bydliště: Brno
Kontaktovat uživatele:

Re: Cisco 79x1 za NATem

Příspěvek od xsouku04 »

Díky za naprosto bezvadné a přesné popsání problému.
Můžete ještě poslat it iptables pravidla co jste zkoušel, jestli v nich neuvidíme chybu ?

Napadají mě ještě dvě dotazy. Díval jste se jestli onen cisco telefon nepodporuje přenosu sipu přes TCP? Tam by možná zběsilé měnění portu neprováděl. Asterisky dříve vůbec nepodporovali TCP, takže je možné že tohle řešení ještě nikdo nevyslovil. My TCP podporujeme.


Další postřeh. Vy chcete, aby naše ústředna dodržela to, co je napsáno v sip hlavičce tedy posílala na port 5060
ve stejné hlavičce je ale napsáno Sent-by Address: 192.168.16.8 , tedy ip adresa v lokální síti. Je zjevné, že naš proxy nemůže poslat na lokální adresu. Proč by pak měl brát v úvahu zrovna port ? Obávám se že tohle by fungovalo stejně jen v lokální síti, protože asterisk na veřejné adrese by poslal hovor na ip adresu 192.168.16.8 takže by to nefungovalo.

Připadá mi, že je opravdu nejsnadnější si pohrát na s těmi iptables pravidly, popřípadě si na tom routeru spustit mini astaerisk/ proxy co by mohla udělat lokální registraci .... :) Možná by stačila nějaké aplikace typu socat co jen chytne paket na daném portu a přepošle ho prostě na ip adresu telefonu a port 5060. Funkci natu totiž v tomto případě ani nijak nepotřebujeme.

V tomto případě mě napadá, že by mohla hodit většinou právem proklínaná funkce routeru SIP ALG, která mění SIP hlavičky. V tomto případě by to mohla být záchrana.
Marek
Příspěvky: 4
Registrován: čtv 09. srp 2012 7:45:14

Re: Cisco 79x1 za NATem

Příspěvek od Marek »

Nemám teď telefon/router u sebe, takže alespoň teoreticky.

TCP je skvělý nápad - nemám s tímto žádné zkušenosti, takže jsem o TCP vůbec nepřemýšlel, ale telefon jej podporuje takže určitě vyzkouším.

Co se týká údajů v SIP hlavičce, máte naprostou pravdu. Jedná se o mé pochybení - není to poprvé, co řeším tento problém, a tak jsem při pořizování screenshotů postupoval už poněkud automaticky a vůbec jsem si nevšiml, že mám chybu v konfiguraci. Telefonu lze totiž nastavit <natEnabled>true</natEnabled>, načež vyžaduje i natAddress, kterou začne vkládat právě do SIP hlaviček. V sent-by address by tedy ústředna obdržela moji veřejnou IP a zasílání odpovědí by mělo fungovat. Zde by bylo naprosto logické, kdyby se telefon při nat=enabled přepnul do jiného režimu, ve kterém začně požadavky zasílat normálním způsobem z portu 5060 (případně začně poslouchat na tomtéž portu, ze kterého požadavek poslal). Bohužel to tak není, problém s porty stále přetrvává. Pokud by to bylo bezpodmínečně nutné, mohu později dodat aktualizovaný screenshot, doufám ale, že zde bude již stačit jenom moje slovo :)

Jako router funguje Netgear WNR3500L, na kterém běží TomatoUSB. Takže ačkoliv jsem schopen se přes SSH připojit do linuxového prostředí a používat např. iptables, instalace lokálního Asterisku je nejspíše vyloučena. Socat vypadá zajímavě ale opět tu narážím na podobný problém jako v případě konstrukce iptables pravidel - není problém poslouchat na portu A a přeposílat na port B. Je ale problém, když port A je náhodný a komunikaci je tak třeba identifikovat pouze na základě source-address a source-port.
Marek
Příspěvky: 4
Registrován: čtv 09. srp 2012 7:45:14

Re: Cisco 79x1 za NATem

Příspěvek od Marek »

Dobrý den.

Tak s potěšením hlásím úspěch. Při použití signalizace přes TCP vše funguje naprosto bez problému. Telefon sice pro požadavky stále používá náhodné porty, tentokrát na nich však už i poslouchá odpovědi. Připadám si trochu hloupě, že po tom všem experimentování nakonec stačilo změnit jediný parametr v konfiguraci. Každopádně děkuji za užitečnou radu.

Ještě mi ale úplně nechodí samotné hovory. Odchozí volání funguje, ale pokud někdo volá na VoIP telefon, tak se 1) nezobrazuje jeho číslo (namísto něj je řetězec "Private") a 2) po zvednutí se nic neděje a v přehledu hovorů je záznam s duration 00:00. Zkoušel jsem volat jak z mobilu, tak i z pevné od O2.

Nemám teď telefon připojený, aby bylo možné provádět nějakou diagnostiku, spíše jsem se chtěl o problému zmínit. jestli se nejedná o nějaký známý bug.
vanas
Příspěvky: 72
Registrován: úte 17. led 2012 23:05:34

Re: Cisco 79x1 za NATem

Příspěvek od vanas »

Marek píše:Dobrý den.

Tak s potěšením hlásím úspěch. Při použití signalizace přes TCP vše funguje naprosto bez problému. Telefon sice pro požadavky stále používá náhodné porty, tentokrát na nich však už i poslouchá odpovědi. Připadám si trochu hloupě, že po tom všem experimentování nakonec stačilo změnit jediný parametr v konfiguraci. Každopádně děkuji za užitečnou radu.

Ještě mi ale úplně nechodí samotné hovory. Odchozí volání funguje, ale pokud někdo volá na VoIP telefon, tak se 1) nezobrazuje jeho číslo (namísto něj je řetězec "Private") a 2) po zvednutí se nic neděje a v přehledu hovorů je záznam s duration 00:00. Zkoušel jsem volat jak z mobilu, tak i z pevné od O2.

Nemám teď telefon připojený, aby bylo možné provádět nějakou diagnostiku, spíše jsem se chtěl o problému zmínit. jestli se nejedná o nějaký známý bug.
Zdravím,problém č. 1 jsem řešil s technickou podporou Odoriku také. Je to dáno tím, že Odorik posílá trochu upravené hlavičky a tahle Cisca je neumí zpracovat. Žádné RFC podle mě ale Odorik neporušuje, takže problém je někde v Cisco firmwaru. Zkuste hledat jinou verzi. Mně se celkem osvědčila verze 8.2.3, kde mi to funguje všechno. Bohužel na 79x1 jsem to nezkoušel, pouze na 79x0 nebo 7905 či 7912. Měl jsem totiž ten samý problém s registrací telefonu, ale taky mě nenapadlo použít TCP. Musím to také vyzkoušet, bohužel jen na levnějším 7906
Marek
Příspěvky: 4
Registrován: čtv 09. srp 2012 7:45:14

Re: Cisco 79x1 za NATem

Příspěvek od Marek »

Pokud jsem to správně pochopil, tak mluvíte o telefonech 7960/40, případně 7912/05. To je ale úplně jiná generace, která nepoužívá Java firmware, má jiný styl konfigurace a obecně se chová dost jinak - paradoxně mnohem méně problémově, ač jde o starší zařízení.
Uživatelský avatar
kovik
Příspěvky: 505
Registrován: stř 16. lis 2011 11:07:52

Re: Cisco 79x1 za NATem

Příspěvek od kovik »

Zdravim, teoreticky by melo stacit:

iptables -t nat -A PREROUTING -p UDP -s 81.31.45.51 --sport 5060 -j REDIRECT --to-port 5060

vsechno co prijde z (81.31.45.51 - sip.odorik.cz) poslat na port 5060
Uživatelský avatar
xsouku04
Administrátor
Příspěvky: 8162
Registrován: pát 15. říj 2010 11:11:44
Bydliště: Brno
Kontaktovat uživatele:

Re: Cisco 79x1 za NATem

Příspěvek od xsouku04 »

kovik píše:Zdravim, teoreticky by melo stacit:

iptables -t nat -A PREROUTING -p UDP -s 81.31.45.51 --sport 5060 -j REDIRECT --to-port 5060

vsechno co prijde z (81.31.45.51 - sip.odorik.cz) poslat na port 5060
Já bych jen doplnil, že tento příkaz nemusí fungovat starším Linuxovým jádrem řady 2.4 a ani s novějším to není otestováno.

Co se týče onoho červeně zakroužkovaného portu a ip z onoho výpisu ethereal (obrázek výše), tak to je skutečný stav nikoli SIP hlavička. Asi to ale na věci nic nemění.
Odpovědět