oriolrius.cat

Des del 2000 compartiendo sobre…

Tag: internet

Podcast 2×04: SSH avançat

Reading time: 3 – 5 minutes

El podcast

[display_podcast]

Notes sobre el podcast

  • -L: connecta per SSH a un HOST Un cop allà obre una connexió TCP a un altre HOST:PORT i obre un port TCP local que al connectar-hi ens envia al HOST:PORT anteriors, o sigui, portforwarding.
    • -L [bind_address:]port:host:hostport]
  • -W: connecta per SSH a un HOST un cop allà obre una connexió TCP a un altre HOST:PORT i ens retorna a la stdin/stdout el contingut d’aquest darrer enllaç TCP
    • -W host:hostport
  • -R publicar un port: connecta per SSH a un host i un cop allà publica un port TCP, quan un client es connecta a aquest port TCP accedeix per SSH a la màquina que ha llença l’enllaç SSH i obre un altre enllaç TCP a una altre IP:PORT.
    • -R[bind_address:]port:host:hostport
  • -D socks5: connecta per SSH a un HOST i després publica un port SOCKS5/TCP, és a dir, que podem connectar a aquest port local i sortir a internet a través de la IP del HOST on hem connectat per SSH
    • -D [bind_address:]port
  • -w tunel: connecta per SSH a un HOST i el socket que s’ha usat per fer l’enllaç SSH es connecta a dues interficies de tipus TUN, una a cada extrem del socket. Així doncs, si configurem les corresponents IPs a les interficies TUN tenim un tunel/VPN montada entre els extrems.
    • -w local_tun[:remote_tun]

HPN-SSH

La web de: HPN-SSH -> especialment interessant: Dynamic Windows and None Cipher

  • treballa amb mida de finestra dinàmica
  • treballa sense xifrat quan un enllaç no té terminal associat, sovint usat per pas de fitxers

Les proves:

  • Openssh 5.3p1 + hpn-13 (només el patch: Dynamic Windows and None Cipher)
  • després d’aplicar el patch: openssh5.3-dynwindow_noneswitch.diff.gz
  • modifiquem el fitxer: sshconnect2.c
    linia: 366
    - 		if (!tty_flag) /* no null on tty sessions */
    + 		if (1) /* no null on tty sessions */
  • així podem fer SSH sense xifrar només després d’haver fet el login.

exemple ampla de banada d’un SSH amb xifrat aes128-ctr, usant finestra dinàmica:

scp -v -oNoneEnabled=no -oNoneSwitch=yes fitxer root@127.0.0.1:/tmp/ssh
o
ssh -v -oNoneEnabled=no -oNoneSwitch=yes root@127.0.0.1 "dd if=/dev/zero"|pv > /dev/null

velocitat de transferència:  13.7MB/s
  • debug ciphers, una única negociació de ciphers:
    debug1: AUTH STATE IS 0
    debug1: REQUESTED ENC.NAME is 'aes128-ctr'
    debug1: kex: server->client aes128-ctr hmac-md5 none
    debug1: REQUESTED ENC.NAME is 'aes128-ctr'
    debug1: kex: client->server aes128-ctr hmac-md5 none
    

exemple sense xifrat, usant finestra dinàmica:

scp -v -oNoneEnabled=yes -oNoneSwitch=yes fitxer root@127.0.0.1:/tmp/ssh
o
ssh -v -oNoneEnabled=yes -oNoneSwitch=yes root@127.0.0.1 "dd if=/dev/zero"|pv > /dev/null

velocitat de transferència:  37.4MB/s
  • abans del pass de login:
  • debug1: AUTH STATE IS 0
    debug1: REQUESTED ENC.NAME is 'aes128-ctr'
    debug1: kex: server->client aes128-ctr hmac-md5 none
    debug1: REQUESTED ENC.NAME is 'aes128-ctr'
    debug1: kex: client->server aes128-ctr hmac-md5 none
    
  • després d’autenticar-se:
  • debug1: AUTH STATE IS 1
    debug1: REQUESTED ENC.NAME is 'none'
    debug1: Requesting NONE. Authflag is 1
    debug1: None requested post authentication.
    debug1: kex: server->client none hmac-md5 none
    debug1: REQUESTED ENC.NAME is 'none'
    debug1: Requesting NONE. Authflag is 1
    debug1: None requested post authentication.
    debug1: kex: client->server none hmac-md5 none
    

Podcast 2×03: eines per jugar amb SOCKS5

Reading time: 1 – 2 minutes

Finalment l’última entrega de la trilogia de podcasts sobre SOCKS. Com indica el títol i podeu veure amb els links aquest parla d’eines per montar servidors SOCKS i wrappers per montar clients SOCKS5.

El podcast:

[display_podcast]

Referències:

Podcast 2×02: SOCKS5 Bytestreams (XEP-0065)

Reading time: 4 – 7 minutes

La segona part sobre la trilogia de SOCKS5.

El podcast:

[display_podcast]

Exemples extrets del XEP-0065:

Example 1. Initiator Sends Service Discovery Request to Target

<iq type='get'
    from='initiator@example.com/foo'
    to='target@example.org/bar'
    id='hello'>
  <query xmlns='http://jabber.org/protocol/disco#info'/>
</iq>

Example 2. Target Replies to Service Discovery Request

<iq type='result'
    from='target@example.org/bar'
    to='initiator@example.com/foo'
    id='hello'>
  <query xmlns='http://jabber.org/protocol/disco#info'>
    <identity
        category='proxy'
        type='bytestreams'
        name='SOCKS5 Bytestreams Service'/>
    <feature var='http://jabber.org/protocol/bytestreams'/>
  </query>
</iq>

Example 3. Initiator Sends Service Discovery Request to Server

<iq type='get'
    from='initiator@example.com/foo'
    to='example.com'
    id='server_items'>
  <query xmlns='http://jabber.org/protocol/disco#items'/>
</iq>

Example 4. Server Replies to Service Discovery Request

<iq type='result'
    from='example.com'
    to='initiator@example.com/foo'
    id='server_items'>
  <query xmlns='http://jabber.org/protocol/disco#items'>
    <item jid='streamhostproxy.example.net' name='Bytestreams Proxy'/>
  </query>
</iq>

Example 5. Initiator Sends Service Discovery Request to Proxy

<iq type='get'
    from='initiator@example.com/foo'
    to='streamhostproxy.example.net'
    id='proxy_info'>
  <query xmlns='http://jabber.org/protocol/disco#info'/>
</iq>

Example 6. Server Replies to Service Discovery Request

<iq type='result'
    from='streamhostproxy.example.net'
    to='initiator@example.com/foo'
    id='proxy_info'>
  <query xmlns='http://jabber.org/protocol/disco#info'>
    <identity category='proxy'
              type='bytestreams'
              name='SOCKS5 Bytestreams Service'/>
    <feature var='http://jabber.org/protocol/bytestreams'/>
  </query>
</iq>

Example 7. Initiator Requests Network Address from Proxy

<iq type='get'
    from='initiator@example.com/foo'
    to='streamhostproxy.example.net'
    id='discover'>
  <query xmlns='http://jabber.org/protocol/bytestreams'
         sid='vxf9n471bn46'/>
</iq>

Example 8. Proxy Informs Initiator of Network Address

<iq type='result'
    from='streamhostproxy.example.net'
    to='initiator@example.com/foo'
    id='discover'>
  <query xmlns='http://jabber.org/protocol/bytestreams'>
         sid='vxf9n471bn46'>
    <streamhost
        jid='streamhostproxy.example.net'
        host='24.24.24.1'
        p
        zeroconf='_jabber.bytestreams'/>
  </query>
</iq>

Example 9. Proxy Returns Error to Initiator

<iq type='error'
    from='initiator@example.com/foo'
    to='streamhostproxy.example.net'
    id='discover'>
  <query xmlns='http://jabber.org/protocol/bytestreams'
         sid='vxf9n471bn46'/>
  <error code='403' type='auth'>
    <forbidden xmlns='urn:ietf:params:xml:ns:xmpp-stanzas'/>
  </error>
</iq>

Example 10. Proxy Returns Error to Initiator

<iq type='error'
    from='initiator@example.com/foo'
    to='streamhostproxy.example.net'
    id='discover'>
  <query xmlns='http://jabber.org/protocol/bytestreams'
         sid='vxf9n471bn46'/>
  <error code='405' type='cancel'>
    <not-allowed xmlns='urn:ietf:params:xml:ns:xmpp-stanzas'/>
  </error>
</iq>

Example 11. Initiation of Interaction

<iq type='set'
    from='initiator@example.com/foo'
    to='target@example.org/bar'
    id='initiate'>
  <query xmlns='http://jabber.org/protocol/bytestreams'
         sid='vxf9n471bn46'
         mode='tcp'>
    <streamhost
        jid='initiator@example.com/foo'
        host='192.168.4.1'
        port='5086'/>
    <streamhost
        jid='streamhostproxy.example.net'
        host='24.24.24.1'
        zeroconf='_jabber.bytestreams'/>
  </query>
</iq>

Example 12. Target Refuses Bytestream

<iq type='error'
    from='target@example.org/bar'
    to='initiator@example.com/foo'
    id='initiate'>
  <error code='406' type='auth'>
    <not-acceptable xmlns='urn:ietf:params:xml:ns:xmpp-stanzas'/>
  </error>
</iq>

Example 13. Target Is Unable to Connect to Any StreamHost and Wishes to End Transaction

<iq type='error'
    from='target@example.org/bar'
    to='initiator@example.com/foo'
    id='initiate'>
  <error code='404' type='cancel'>
    <item-not-found xmlns='urn:ietf:params:xml:ns:xmpp-stanzas'/>
  </error>
</iq>

Example 16. Target Notifies Initiator of Connection

<iq type='result'
    from='target@example.org/bar'
    to='initiator@example.com/foo'
    id='initiate'>
  <query xmlns='http://jabber.org/protocol/bytestreams'
         sid='vxf9n471bn46'>
    <streamhost-used jid='streamhostproxy.example.net'/>
  </query>
</iq>

Example 19. Initiator Requests Activation of Bytestream

<iq type='set'
    from='initiator@example.com/foo'
    to='streamhostproxy.example.net'
    id='activate'>
  <query xmlns='http://jabber.org/protocol/bytestreams'
         sid='vxf9n471bn46'>
    <activate>target@example.org/bar</activate>
  </query>
</iq>

Example 20. Proxy Informs Initiator of Activation

<iq type='result'
    from='streamhostproxy.example.net'
    to='initiator@example.com/foo'
    id='activate'/>

Referències:

<iq type=’get’
from=’initiator@example.com/foo’
to=’target@example.org/bar’
id=’hello’>
<query xmlns=’http://jabber.org/protocol/disco#info’/>
</iq>

reDuh: TCP sobre HTTP

Reading time: 1 – 2 minutes

La idea es força simple es tracta de transportar un fluxe TCP sobre d’una connexió HTTP convencional, fiexeu-vos que en aquest cas no estem parlant de proxies ni similars. Sinó de paquets TCP+HTTP que en la part de dades del HTTP tornen a implementar TCP, si fessim un petit esquema seria algo així:

+----+----+------+------+-----+------+
|... | IP | TCP | HTTP | TCP | DATA |
+----+----+------+------+-----+------+

Si realment teniu aquest interés montar reDuh és realment senzill, de fet, suporta servidors amb JSP, PHP i ASP. En escència l’únic que fa és usar aquests protocols per re-obrir una connexió TCP. Així doncs, al servidor on montem aquesta eina hem de tenir certs privilegis per poder obrir sockets des d’un script.
L’eina no és massa recomanable si pensem tenir fluxes de dades molt intensos, per exemple, senssions VNC. Però funciona prou bé si el que volem és transportar una sessió SSH o similar.

Proxytunnel: connecta un socket a través d’un proxy HTTP i HTTPs

Reading time: 2 – 2 minutes

Descrirure tècnicament el que fa proxytunnel és força senzill, ja que l’únic que fa és connectar l’entrada i sortides estàndard a través d’un socket que va del client al servidor a través d’un servidor proxy HTTP o HTTPs; soportant autenticació de diversos tipus en el servidor proxy.
Gràcies a aquesta funcionalitat tan simple es pot aplicar en infinitat de llocs, per exemple, com a backend d’OpenSSH per tal de poder fer connexions SSH a través d’un proxy HTTP. Això si el proxy haurà de suportar el mètode CONNECT.
Un cop ha establert la connexió amb l’extrem desitjat publica un port a través del qual ens podem connectar a través d’un client TCP convencional i enviar/rebre dades de l’altre extrem del túnel.
Quan treballem sobre proxies HTTP aquests no poden fer inspecció de continguts de capa 7 sinó s’adonaran que el tràfic qeu es passa no és legítim, encanvi si fem el túnel sobre HTTPs això no e un problema ja que no es pode inspeccionar les dades que van per sobre de la capa 4 al anar xifrades.
També cal pensar que és habitual que si el mètode CONNECT, que ha de ser suportat pel proxy esta habilitat (cosa rara que passi) segurament estarà restringit a connectar-se al port 80, 8080 i 443 remots, com a molt. Així doncs, si el que volem és fer una connexió SSH el que hem de fer és publicar el servidor SSH per algún d’aquests ports.
Si esteu interessats en aplicar la solució de la connexió SSH sobre proxy HTTP/s ús recomano seguir el manual que hi ha a la pàgina: DAG WIEERS: Tunneling SSH over HTTP(S).

Podcast 2×01: introudcció i descripció detallada del protcol SOCKS5

Reading time: 3 – 4 minutes

Després de moltes hores de feina estudiant el protocol SOCKS he decidit publicar un podcast que expliqui el seu RFC, el podcast pretent fer una introducció des de la part meś conceptual fins endinsar-se en el fluxe de paquets, els camps de les peticions llençades arribant a explicacions de nivell de bit. Amb l’ajuda dels diagrames adjunts a aquest article, l’RFC1928 i l’explicació del podcast després hauriem d’estar capacitats per implementar un client/servidor SOCKS5.

El podcast:

[display_podcast]

Esquemes que ajuden a seguir el podcast

esquema 1: petició d’un client SOCKS5 al servidor

                   +----+----------+----------+
                   |VER | NMETHODS | METHODS  |
                   +----+----------+----------+
                   | 1  |    1     | 1 to 255 |
                   +----+----------+----------+

esquema 2: resposta del servidor SOCKS5 al client

                         +----+--------+
                         |VER | METHOD |
                         +----+--------+
                         | 1  |   1    |
                         +----+--------+

mètodes d’autenticació

  • X’00’ NO AUTHENTICATION REQUIRED
  • X’01’ GSSAPI
  • X’02’ USERNAME/PASSWORD
  • X’03’ to X’7F’ IANA ASSIGNED
  • X’80’ to X’FE’ RESERVED FOR PRIVATE METHODS
  • X’FF’ NO ACCEPTABLE METHODS

esquema 3: el client SOCKS5 envia una comanda al servidor

        +----+-----+-------+------+----------+----------+
        |VER | CMD |  RSV  | ATYP | DST.ADDR | DST.PORT |
        +----+-----+-------+------+----------+----------+
        | 1  |  1  | X'00' |  1   | Variable |    2     |
        +----+-----+-------+------+----------+----------+

camp: ATYP -> address type

  • IP V4 address: X’01’
  • DOMAINNAME: X’03’
  • IP V6 address: X’04’

esquema 4: resposta del servidor SOCKS5 a la comanda del client

        +----+-----+-------+------+----------+----------+
        |VER | REP |  RSV  | ATYP | BND.ADDR | BND.PORT |
        +----+-----+-------+------+----------+----------+
        | 1  |  1  | X'00' |  1   | Variable |    2     |
        +----+-----+-------+------+----------+----------+

camp: REP -> reply

  • X’00’ succeeded
  • X’01’ general SOCKS server failure
  • X’02’ connection not allowed by ruleset
  • X’03’ Network unreachable
  • X’04’ Host unreachable
  • X’05’ Connection refused
  • X’06’ TTL expired
  • X’07’ Command not supported
  • X’08’ Address type not supported
  • X’09’ to X’FF’ unassigned

esquema 5: encapsulaments per enviaments de paquets UDP

      +-----+----+-----+------------------------+------+
      | ... | IP | UDP | SOCKS5 UDP ASSOCIATION | DATA |
      +-----+----+-----+------------------------+------+

esquema 6: camps de l’encapsulament: UDP ASSOCIATION

      +----+------+------+----------+----------+----------+
      |RSV | FRAG | ATYP | DST.ADDR | DST.PORT |   DATA   |
      +----+------+------+----------+----------+----------+
      | 2  |  1   |  1   | Variable |    2     | Variable |
      +----+------+------+----------+----------+----------+

Referències d’utilitat

  • Apunts per fer el podcast: fitxer .txt amb la llista de coses que havia de comentar al podcast és una barreja de català, castellà i anglès… però pot servir-vos per entendre el que intento explicar
  • Wikipedia: SOCKS
  • RFC’s:
    • RFC1928: SOCKS Protocol v5
    • RFC1929: Username/Password Authentication for SOCKS V5
    • RFC1961: GSS-API Authentication Method for SOCKS V5

Glosari de Telepathy

Reading time: 3 – 4 minutes

Abans que res una petita introducció a: Què és Telepathy?

Es tracta d’un framework que unifica diferents sistemes de comunicació en temps real. Usa DBUS com a interficie de comunicació entre aplicacions.

Avantatges de Telepathy:

  • Temps real: suporta sistemes IM (un-a-un i grups), video trucades i trucades de veu.
  • Unificat: permet que diferentes aplicacions i de forma simultànea s’aprofitin de les capacitats del sistema i que treballin de forma col·laborativa.
  • Framework: disecciona el sistema de comunicacions en petites parts i les fa tan simples com pot perquè al usar-les contjuntament el procés de comuncació sigui el més senzill possible.

El glosari de termes, en poques paraules el que cal tenir en ment i recordar quan parlem de Telepathy.

  • MUC (multi user chat): o també anomenat chat room, o canal de xat.
  • Mission Control: responsable de la gestió de comptes de missatgeria: creació de connexions i manteniment dels estats de presència dels contactes.
  • Glabbe: és un connection manager de Jabber.
  • Tapioca: és un framework per VoIP i aplicacions IM. Suporta SIP/XMPP.
  • Farsight: idem que el Tapioca, però orientat a videoconferències.
  • Stream Engine: exporta les funcions de Farsight a DBUS. i viceversa.
  • Tubes: és el mecanisme que usa Telepathy per suportar transferència de dades entre aplicacions remotes, o sigui: remote IPC. La idea que hi ha darrera és “si dues persones connectades a un servei de IM poden parlar, perquè dues aplicacions connectades a un IM no poder intercanviar informació”.
  • Stream Tubes: és un mètode de transport usat per Telepathy molt similar al SOCK_STREAM sockets: enviament de paquets ordenat i confiable.
  • IB (in-band): quan els ‘Tubes’ usen el servidor de missatgeria per intercanviar dades. Aquest sistema pot ser molt lent per transportar depèn quin tipus d’informacions, per exemple, sessions VNC.
  • OOB (out of band): els ‘Tubes’ de dades usen diferents camins fora de la xarxa XMPP, per exemple, connexions directes entre peers via UDP o TCP.
  • Empathy: es tracta d’un client d’IM programat usant les llibreries de Telepathy.
  • XEP-0095 Stream Initiation: aquesta especificació defineix una extenció d’XMPP que iniciar fluxes de dades entre dos entitats connectades a la xarxa XMPP. El protocol soporta la possibilitat d’incloure metadades sobre el fluxe de dades a intercanviar.
  • XEP-0065 SOCKS5 bytestreams abstract: es defineix una extenció d’XMPP per establir connexions OOB entre dos peers, la connexió entre els peers pot ser directe o via un proxy SOCKS5, en principi la idea és usar TCP per aquests tipus d’enllaços malgrat també podria funcionar per UDP.
  • XEP-0163 PEP (Personal Eventing Protocol): defineix la semàntica d’un protocol que usant les funcions publish-subscribe d’XMPP dinfon els canvis d’estat i presencia. D’aquesta forma podem fer funcionar l’estat d’una compte com si es tractés d’un servei pubsub; simplificant la possibilitat de sindicar-nos a dades i notificacions associades amb aquella compte. Un exemple, per fer-ho més entendor: podem tenir un servei d’agenda que ens avisa que hem de fer certes coses si és que estem disponibles però si en canvi este ausents no té sentit que ens avisi.
  • XEP-0080 User Location: és una extenció per permet enviar informació sobre la posició geogràfica de l’usuari.

XMPP amb BOSH: usant HTTP com a protocol de transport

Reading time: 4 – 7 minutes

La potència de treballar amb BOSH (Bidirectional-streams Over Synchronous HTTP) rau en que malgrat aparentment l’única forma que hi ha d’implementar XMPP sobre HTTP seria mitjançant tècniques de polling, o sigui, que periódicament el client anés connectant-se al servidor per preguntar si hi ha alguna nova informació per ell.

Doncs BOSH aconsegueix millorar aquest algoritme i el que intenta descriure és quelcom així:

  1. El client fa una connexió ‘HTTP request’ al servidor
  2. El servidor no envia cap resposta, així doncs, la connexió no es tanca.
  3. Quan el servidor té una informació (asíncrona) a enviar al client, llavors busca alguna connexió oberta del client i que estigui esperant resposta, o sigui, qu estigui al punt 2. Llavors el que fa és enviar l’informació a través d’aquesta connexió com una ‘request response’. La connexió es tanca.
  4. Un cop el client rep l’informació inmediatament després de tancar-se l’enllaç, aquest torna a obrir una connexió contra el servidor, o sigui, tornem al punt 1.

Obviament quan el client té alguna cosa a enviar això es fa en el punt 1.

A l’hora de la veritat els servidors de Jabber/XMPP el que tenen per oferir accés via BOSH és un especie de proxy que rep les connexions HTTP i les processa tal com he explica més amunt, per l’altre costat captura els events que rep de cada un dels clients XMPP que esta instanciant i va connectant els fluxes de dades que rep a través d’XMPP als sockets HTTP que té esperant informació.

Servidors BOSH incrustats en servidors XMPP

Obviament això ens porta a pensar, que podem usar un servidor BOSH per un servidor XMPP que no el suporti a mode de proxy. Això es podria programar de forma força senzilla amb twisted, per altre banda, hi ha servidors XMPP que ja suporten de serie el servidor BOSH, alguns exemples són: ejabberd, Tigase, Openfire i Jabber XCP.

Avantatges de tenir el servidor BOSH dins del servidor XMPP:

  • Sovint esta més ben testejat que el codi que podem fer-nos o que ha desenvolupat un tercer per fer aquesta tasca.
  • A priori hauria de ser més eficient, ja que la part de recepció d’events/senyals es fa a través de l’API nativa i no pas d’un client XMPP. Cosa que permet estalviar recursos i ser més eficient en la seva tasca.
  • És més fàcil de configurar, sovint només cal descomentar la línia corresponent del fitxer de configuració i llestos.

Com que no tot podien ser avantatges aquí van els inconvenients:

  • Un servidor BOSH que esta incrustat en un servidor XMPP obviament només pot atendre les peticions que van cap aquell servidor, per tant, si volem que això sigui escalable haurem de montar un balencejador de càrrega sobre el port HTTP per anar desviant connexions entre diferents sevidor BOSH.
  • El suport del servidor BOSH esta lligat al suport que la comunitat doni al servidor XMPP amb el que va lligat, això no sempre és suficient.

Quan no hem de suportar més d’un servidor XMPP, i a més aquest ja suporti BOSH no hi ha hauran mai problemes. La cosa es complicarà quan haguem d’escalar aquesta infraestructura.

Servidors BOSH dedicats, per tant independents del servidor XMPP

Per exemple: Punjab, Araneo, JabberHTTPBind i rhb. Pel que fa les avantatges i desavantatges d’aquest tipus de servidors BOSH, obviament són les mateixes que les anteriors però invertides.

Un servidor BOSH dedicat, per tant, podrà connectar-se a una xarxa XMPP a través d’un servidor XMPP federat sense problemes. Sovint el preu de sobrecarrega que això suposa esta més que justificat. Cal pensar que per cada client s’hauran de tenir sovint dues connexions TCP/HTTP més una connexió TCP/XMPP; per tant, tres sockets oberts per cada client connectat al servidor BOSH. Amb això suposo que queda clara la similitut amb un servidor proxy, no?
Com ja he apuntat abans escalar els servidors BOSH a través de ‘load-balancers’ és molt senzill, per exemple ús recomano nginex. Penseu que amb aquest ‘load-balancer’ podem tenir fins a10.000 connexions HTTP i només consumir 2’5Mb de memòria RAM. Per tant, aquesta també és una molt bona raó per usar-los externs els servidors BOSH. De fet, això no només ho penso jo sinó que aquí també ho pensen: BOSH cloud.
De fet, hi ha gent tan agoserada que gosa dir que XMPP és millor si els clients usen BOSH per accedir-hi, de fet, si llegeixes el raonament no sembla tan dolent: XMPP is better with BOSH.

Nota final

Per si algú encara no ho tenia clar, això és el que usen les llibreries d’XMPP implementades en JavaScript, o sigui, els client de xat (Jabber/XMPP) que via Web. Per exemple, el client que podem usar des de la pàgina web de gmail.

Obviament les aplicacions Jabber/XMPP són infinites i no només com a clients de xat. Per tant, podeu aprofitar aquestes llibreries JS que implementen BOSH per mostrar de forma interactiva a les vostres interficies web qualsevol tipus de contingut que obtingueu a través de la xarxa XMPP.

NAT traversal: Com funciona ICE?

Reading time: 5 – 8 minutes

Per tal d’entendre com funciona ICE el millor és explicar-lo conjuntament amb un altre protocol; ja que com es va comentar a la introducció del NAT traversal el protol ICE usa una combinació del protocol TURN i STUN en funció del cas, això és molt senzill d’entendre si parlem d’un cas pràctic d’ús. O sigui, quan s’intenta que per exmple, SIP travessi un firewall/gateway/router per fer arribar una trucada a un telefon IP.

Què són els candidats?

El Caller envia un missatge de SIP INVITE amb informació SDP que descriu per quina IP i per quins PORTS l’aplicació pot rebre audio i/o video. Aquestes adreces i ports es coneixen com candidates. Aquests candidates s’obtenen del servidor ICE (sovint es troba dins el firewall/router/gateway).

Podriem descriure un candidate com una IP i un port a través dels quals un peer pot rebre dades d’un altre peer. Hi ha tres tipus de candidates:

  • Local candidate: IP local del client.
  • Reflexive or STUN candidates: una adreça IP pública del servidor NAT.
  • Relay o TURN candidate: una adreça o un relay server que ha estat reservat pel client.

El tràfic sempre es podrà enviar amb èxit a través dels relay candidates, a menys que un firewall bloquegi l’enllaç, aleshores no hi ha tècnica possible de NAT traversal a aplicar. El problema d’usar relay candidates és que requereix usar recursos d’un servidor, això fa que el tràfic que arriba al peer tingui retards, perdues i problemes de jitter.

Procés d’establiment d’una trucada SIP via ICE

1. Caller aconsegueix els seus candidates

En el següent gràfic es pot veure com el Caller determinada els reflexive i relay candidates per una connexió. El client envia una petició d’ALLOCATE al servidor, llavors el servidor localitza un parell IP/port (el relay candidate). Aquesta informació s’envia altre cop al Caller (reflexive candidate), aquest missatge conté la IP pública que usarà el Caller quan emeti un missatge a internet, sovint això és la IP a través de la qual s’aplicarà el NAT.

stun_turn_candidates

2. Caller envia un SIP INVINTE

El Caller construeix un missatge SIP INVITE usant la informació dels candidates que ha obtingut del seu servidor ICE, després l’envia al seu destí.

3. Callee aconsegueix els candidates

Quan es rep el missatge SIP INVITE, el Callee aconsegueix els candidates de la mateixa manera que ho ha fet el Caller en el punt (1).

4. El Callee envia una resposta 1xx

Seguint amb el protocol SIP, el Callee ha de generar un missatge de resposta al SIP INVITE, per exemple, un SIP 183 (Session Progress). Quan es construeixi aquest missatge dins de l’informació SDP el Callee també hi encapsularà els seus candidates. Fins que aquest missatge no s’hagi rebut i confirmat per part del Caller (200 OK) no es considerarà exitosa la negociació.

5. ICE connectivity checks

Arribats en aquest punt tan el Caller com el Calle saben mutuament els candidates que tenen cadascún i és el moment d’usar el que s’anomena ICE connectivity checks. Això es fa enviant un missatge STUN des del local candidate cap al remote candidate, això es pot fer per tants candidates com hi hagin des del que té més prioritat fins al que en té menys. Això ho faran ambdós costats de l’enllaç si és que tots dos es troven darrera un gateway amb ICE. Quan s’hagi determinat quin dels candidates és el millor per establir cada un dels canals llavors s’escollirà aquest candidate per començar a enviar i rebre media a través seu.

A continuació es poden veure tres exemples de com es fan aquestes proves dels candidates. El primer esquema seria el cas en que ambdós hosts són enrutables directament perquè, per exmple, estan a la mateixa LAN. El segon esquema s’aconseguiria l’enllaç via la metologia STUN i en el tercer via la metodologia TURN.

ICE_connection_check

6. Callee envia SIP 180 (ringing)

En aquest punt el Callee envia el missatge SIP 180 (ringing) al Caller per informar-lo de que el teléfon del Callee esta sonant. Al haver negociat previament el canal de dades a través d’ICE quan el Callee despengi el teléfon ja podrà parlar sense retards, si això es negocies després hi hauria un efecte de retard desagradable pels peers.

7. Accepta la trucada i parlen

Així doncs, quan el Callee despengi s’enviarà un missatge 200 OK i via RTP (per exemple) i usant els canals negociats via ICE el fluxe de dades multimedia (en aquest cas audio) començarà travessant de forma transparent els dos gateways que donen accés a internet als dos peers.

Unes notes per aclarir el tema

En aquest exemple es preten demostrar que podem establir un enllaç RTP a través de dos peers que es troben darrera de NAT gràcies al protocol ICE. Com a protocol per controlar la sessió RTP s’usa SIP, això fa que ambdós peers necessitin una redirecció DNAT al seu gateway cap als ports TCP/UPD 5060. En cas de voler evitar això el que s’hauria d’usar és un altre protocol de senyalització diferent de SIP. Per exemple, si no volem/podem redirigir cap port al gateway es podria usar XMPP.

Glosari

  • Caller: qui fa la trucada
  • Calee: qui rep la trucada
  • SDP: Session Description Protocol
  • SIP: Session Initiation Protocol
  • Peer: un extrem de la connexió

Referències


NAT traversal: Com funciona STUN?

Reading time: 2 – 3 minutes

El servidor STUN ha de publicar la seva IP (3478TCP/UPD o 5349TLS) a un gateway que tingui una IP interna i una externa (privada i pública). La comuniació comença quan el client que esta a la xarxa enmascarada llença una serie de requests contra la IP pública del servidor STUN. El servidor STUN contestarà al client informant dels parells de ports usats a l’exterior del NAT, amb això el client aprent de quin tipus de NAT disposa i quin és el TTL dels bindings que es fan a l’exterior per re-enviar les seves peticions.

Una aplicació client per tal de saber qui és el seu servidor STUN el que fa és buscar al seu domini DNS la resolució del nom _stun_.domini_exemple.com o _stun._udp.domini_exemple.com pels tipus de registre SRV. Després de saber qui és el seu servidor STUN el que fa l’aplicació és buscar l’adreça pública del servidor STUN. Per tal de descobrir quin haurà de ser l’origen dels seus paquets a internet. Així quan construeixi els paquets amb les dades d’aplicació podrà advertir quina és l’adreça pública del seu servidor STUN.

Arribats a aquest punt sovint en tenim prou com per començar la comunicació amb el destí final del nostre enllaç, ja que aquest l’únic que haurà de fer és contestar els paquets pels mateixos ports que el gateway esta fent binding en aquell moment. Aquí és on el STUN server fa la seva feina mantenint els ports oberts. Un dels problemes amb els que ens podem trobar és que el node destí no pugui atacar aquells ports per alguna restricció del seu firewall o similar. Cosa que complica la possibilitat de fer l’enllaç. Si els dos hosts que volem comunicar estan tots dos darrera del NAT-masquerade la cosa és fa molt difícil i sovint fa falta un proxy entre els dos servidors STUN per tal de que la cosa funcioni, o sigui, que es complica moltíssim.

Diagrama de fluxe del protocol:

Esquema NAT
Click for (+) Zoom