Capçaleres IPv6
Basant-me en un parell d’articles de Network Systems Design Line vaig escriure l’article IPv6: repassant les novetats tècniques, doncs bé s’han publicat les parts 3 i 4 que continuen amplicant la introducció feta a les parts 1 i 2 que vaig repassar en el meu article. La part número 3 parla específicament de les característiques de les capçaleres IPv6. Part realment important i interessant en aquesta nova versió IP. Així doncs dedicaré aquest article a resumir la part 3 de l’article de Networki System Design Line que parla sobre les capçaleres IPv6.
IPv6 vs IPv4 formats de capçalera
Per entendre quines són les motivacions que han provat els canvis en la capçalera IPv6 cal tenir clar quins eren els camps de la capçalera IPv4.
- Version (4bits) obviament conté la versió del protocol en aquest cas fixarem la versió a 4.
- Header Length (4bits) llargada en octets de la capçalera.
- Type of Service (ToS) identificador usat en QoS per tal de poder classificar els paquets segons la prioritat que li volem donar.
- Total length (16bits) llargada en octets del paquet sencer, capçalera més dades. La llargada màxima serà 65.535 octets, que és el màxim que podem definir amb 16 bits.
- Identification (16bits) Flags (3bits) Fragment Offset (13bits) a través d’aquests tres camps IPv4 implementa el suport de la fragmentació de paquets.
- Time to Live (TTL) (8bits) número màxim de salts que pot fer un paquet abans d’arribar al seu destí. Amb aquest camp s’evita que si hi ha un problema d’enrutament els paquets saltin infinitament en cercle, sense arribar mai al destí. En cada salt que fa el paquet es decrementa el valor del camp i si aquest arriba a 0 es descarta el paquet.
- Protocol Number (8bits) indica el codi del protocol que encapsula IP en la capa superior, o sigui, la capa 4. Els números que identifiquen aquests protocols (TCP, UDP, ICMP, etc) els defineix la IANA.
- Header Checksum (16bits) serveix per comprobar la integritat de les dades de la capçalera.
- Source IPv4 address (32bits) adreça IP origen.
- Destination IPv4 Address (32 bits) adreça IP destí.
- Options (mida variable) s’acostuma a guardar-hi informació necessària per interpretar les dades que transporta el paquet.
- Padding (mida variable) aquest camp s’usa per ajustar la mida del camp Options a 32 bits totals.
La nova capçalera IPv6 intenta millor els principals problemes de la IPv4 a través de:
- Mida fixa de la capçalera. Sempre de 40bytes, això afavoreix el poder processar-la de forma més ràpida perquè els routers poden buscar les direccions origen i destí de forma més eficient. Les funcionalitats que tenia IPv4 a través del camp de mida variable, Options ara la obtindrem a través de les extensions de la capçalera, concepte del que es parlarà després.
- La fragmentació deixa de tenir sentit ja que a través del PMTU discovery els routers ajusten la mida de les trames per tal de que no hi hagi fragmentació en els paquets. Així els camps de Identification, Flags, i Fragment Offset deixen de tenir sentit.
- Les comprobacions de la capçalera (header checksums) s’eliminen. Aquesta tasca ara és deixa per les capes superiors.
Així doncs, les capçaleres d’IPv6 es defineixen al RFC 2460 i queden com segueix:
- Version (4bits) versió del protocol IP, sempre fixe a 6.
- Traffic Class (8bits) fa el mateix que el ToS del IPv4.
- Flow Label (20bits) a través d’aquest camp identifiquem un fluxe de paquets informant al router que els següents ‘n’ paquets seràn iguals a aquest i per tant, no cal que els processi. Aquesta idea es desenvolupa al RFC 3697. Aquesta informació es fixa en l’origen del paquet i no la poden modificar els routers.
- Payload Lengh (16bits) com que la capçalera sempre té 40bytes amb 16bits en tenim prou per delimitar la mida de les dades. És important recordar que les extensions de la capçalera es consideren part de les dades.
- Next Header (8bits) definim quin tipus de extensió de la capçalera segueix a la capçalera bàsica.
- Hop Limit (8bits) és l’equivalent al TTL. Només se li ha canviat el nom perquè sigui més descriptiu del funcionament del camp.
- Adreça origen IPv6 (128bits)
- Adreça destí IPv6 (128bits)
Extensions de capçalera IPv6
Bàsicament les extensions de capçalera són una segona capçalera, opcional, que s’usa per donar les funcions que es donava en IPv4 a través del camp, de mida variable i màxim de 40bytes, Otpions. En IPv6 podem fer aquestes extensions de capçalera tran grans com ens interessin, sempre que respectem la mida màxima del paquet.
A continuació podem veure un exemple d’una capçalera bàsica, i d’una capçalera amb uan extensió de capçalera.
A l’RFC 2460 podem trobar les definicions de les extencions de capçalera. Podem trobar-hi, una descripció, el format i la funcionalitat.
Hop-by-Hop Options Header
La capçalera Hop-by-Hop és una extenció de la capçalera bàsica, es defineix en el camp Next Header, de la capçalera bàsica, amb el codi 0. És la única extenció de capçalera que s’ha de processar per tots els nodes del camí entre l’origen i el destí del paquet. S’úsa per exemple per facilitar la expedició de dels Jumbograms (després s’explica què és això), o també facilita que els routers es passin informacions d’expedició (forwarding).
Les opcions que transporta aquesta extenció de capçalera es codifiquen en un format que es diu TLV, a continuació es pot veure un diagrama del format.
Tots els nodes que hi ha en el camí rebran aquesta capçalera i la processaran. Si algún dels nodes no entengues les opcions que conté la capçalera i que ha de processar generaria un paquet de tipus ICMP. Tot i que no totes les opcions han de generar forçosament aquest missatge ICMP, amb això s’eviten problemes d’atacs de denegació de serveig per inundació de paquets ICMP.
És important tenir en compte l’impacte en el rendiment que té el fet de processar les capçaleres hop-by-hop en cada un dels routers. Una de les funcionalitats que té és el fet de suportar paquets molt grans. La capçalera bàsica només permet una mida que es pugui definir en 16bits, o sigui, de com a molt 65.536 octets.
Les extensions hop-by-hop contenen un camp de 32 bits de llargada que pot representar paquets molt grans, anomenats Jumbograms. Quan volguem usar el camp de 32bits de la capçalera hop-by-hop el camp Payload length de la capçalera bàsica el posarem a 0, amb això s’idenfica un paquet Jumbogram.
A través de l’RFC 2711 es defineix l’opció Router Alert que a través de la caçalera hop-by-hop permet enviar intruccions d’expedició (forwarding instructions). Per exemple, per fer reserves d’amplada de banda amb RSVP. O per alertar als routers que han de processar paquets multicast, això es fa a través dels paquets Multicast Listener Discovery.
Destination Options Header
Com el propi nom indica, aquesta extenció de la capçalera bàsica es refereix nomes a les Option de la direcció de destí. Per exemple s’usen amb MIPv6. El codi usat en el camp Next Header a la capçalera bàsica és el 60.
Routing Header
Identificada amb el codi 43, al camp Next Header. S’usa per reforçar el camí a seguir per alguns paquets. El camí el defineix l’origen, i podria no coincidir amb el camí calculat pels routers intermitjos.
La capçalera routing header conté un camp de tipus (type) que permet saber amb exactitut a funcionlitat d’aquesta capçalera. En aquest moment hi ha dos tipus de funcionalitats definides:
- Type 0 (RFC 2460) especifica tots els salts que ha de fer el paquet per viatjar fins al seu destí. El que faràn els routers intermitjos és anar canviant la direcció destí de la capçalera bàsica en funció de la capçalera extesa per forçar el salt cap al següent node, si haguessin de fer algún salt no contemplat aquest no modificaria la direcció destí d’aquell moment ni apareixeria ni s’afegiria a la capçalera extesa. Per tant, aquests salts no contemplats serien transparents al procés.
- Type 2 (RFC 3775) usat amb MIPv6. Conté una única adreça unicast, l’adreça del home, i habilita al node corresponent perquè re-envii el tràfic directament a un node mòbil.
Fragment Header
La fragmentació requereix molt de procés en els nodes. Per tal d’evitar les necessitats de sobrecarregar els processadors dels nodes a IPv6 no s’admet la fragmentació de paquets. Abans d’enviar un paquet, l’origen ha de passar per un procés de descobriment de PMTU. Això determinarà quina és la màxima mida que pot tenir un paquet per aquell camí sense que es fragmentin els paquets. Malgrat els routers ja no han de controlar el problema de la fragmentació els nodes destí si que han de saber recomposar un paquet fragmentat. Per tal de poder-ho fer, s’usen les extensions de capçalera Fragment Option Header.
Authentication Header
Aquesta capçalera s’assembla a la capçalera IPSec AH (RFC 2402) usada en IPv4. Aquest sistema autentica l’origen d’una transmissió i assegura la integritat del paquet. El camp Next Header l’identifica amb el codi 51.
Encapsulating Security Payload Header
S’assembla a la idea implmentada en IPSec ESP (RFC 2406) en IPv4. Identificat amb el codi 50 al camp next header.
Mobility Header
Definit a l’RFC 3775 i usat en les comunicacions entre nodes mòbils, nodis corresponents (correspondent nodes) i amb agents domèstics (home agents) en l’establiment i el control de bindings. Identificat amb el codi 135 al next header field.
Acabant…
Amb aquest article n’hi ha prou per veure que el tema de la capçalera s’ha cuidat moltíssim i que hi ha infinitat de combinacions que permeten extendre la capçalera bàsica per gaire bé qualsevol necessitat que se’ns ocurreixi. A més si ens cal fins hi tot podem crear noves extencions per les nostres necessitats. Sota el meu punt de vista aquest és un dels avantatges més potents en IPv6.
Diferents formes de lligar-se els cordons de les sabates
Recordo que quan tenia 16 anys li vaig explicar a algú que a internet hi havia uns foros on la gent tenia converses absolutament de qualsevol tema, fins hi tot hi havia discusions de com s’havia de col·locar el paper de wc: penjant pel cantó de la paret, o per l’altre cantó. Doncs als més populars del delicious m’he trobat un web on es parla d’una cosa gairebé tan rebuscada com la que us he comentat, o sigui, podeu veure una recopilació de desenes de formes diferents de cordar-se les sabates amb les seves avantatges i desavantatges. Realment hi ha gent per tot, fins hi tot gent per referenciar fets així.
Si com jo no podeu evitar perdre-hi 10min llegint totes les formes com uns autistes: 31 Different Ways To Lace Shoes (local).
Substituts wireless dels cables USB
Actualment s’esta treballant en tres línies a l’hora d’elminar els cables del PC, normalment USB, el típic cable de ratolí, telcat, impresora, escaner, camara de fotos, etc. Totes les solucions són usant com a tecnologia de radio el UWB (wikipedia: UWB). De fet, durant aquest gener la IEEE va decidir desistir en l’estandarització d’aquesta tecnologia que havia de ser l’estàndard 802.15.3a. Però múltiples desacrods en el grup de treball van acabar en la conclusió de que no s’entandaritzaria.
Doncs bé les tendències en les que s’estan treballant per tal de substituir els cables del PC als periferics són:
- 1. Convertir directament les dades serie de l’USB en senyals de radio d’Ultra-Wideband(UWB). Ni els dispositius USB ni els host USB necessiten cap canvi ja que tot és completament transparent a nivel d’USB.
- 2. Usar només els connectors USB, però re-empaquetar totes les dades amb un altre protocol, per exemple TCP/IP. Així doncs la comunicació per aire es fa sobre aquest nou protocol, quan arriba al destí es re-converteix a USB. Així es manté compatibilitat amb els dispostius. Excepte les que usen el mode isochronous.
- 3. Consisteix en redissenyar l’USB internament fins hi tot els sistemes electrònics. Només mantenint compatibilitat en les aplicacions però re-fent tots els drivers de host i de dispositius.
Si voleu aprofundir més en la discusió podeu llegir l’article Making USB without wires work for consumers (local).
Hardware
Alguns dispositius que ja implementen alguna de les tècniques explicades anteriorment:
- CableFree USB Hub and Dongle (set) (F5U301) (~130$)
- Y-E Data HUB USB inal·làmbric (~200). 100Mbps a una distància màxima de 10m.
- USB Server (~129$)
Transistor LM3940 – de 5v a 3’3v
No sé d’on el puc treure que no sigui a l’estranger però l’hauré de buscar, el tinc al cap des de fa dies i per casualitat acabo de trobar la seva pàgina. Què té d’especial aquest transistor? doncs simplement que és el que passa de 5v a l’entrada a 3’3v a la sortida. Serveix per exemple, per alimentar a través d’USB un transmissor FM que tinc i així no he d’estar posant-li piles cada 2×3. Quan m’animi a fer l’inventillo ja el penjaré aquí.
A continuació podeu veure un simple gràfic de com usar-lo:
I fins hi tot un esquema de com és físicament, de fet, no té més. Simplement un transistor lineal.
Web on l’he trobat: LM3940 – IA Low Dropout Regulator for 5V to 3.3V Conversion.
symfony: protegint els entorns de desenvolupament, integració i producció
A l’article symfony: entorns de desenvolupament, integració i producció es pot entendre el perquè de treballar amb aquests tres espais de noms (environment) així doncs el que es preten explicar és:
- Impedir accés a les aplicacions en entorns de ‘dev’ i ‘int’ des de llocs no controlats. O sigui, que una IP d’internet no pugui executar myapp_dev.php o myapp_int.php però encanvi una IP de la xarxa del desenvolupador si que pugui.
- Impedir accés a aplicacions de backend des de l’entorn de producció. Si hem desenvolupat alguna aplicació per tal de fer el manteniment de l’aplicació principal, una part d’administració o backend aquesta no sigui accessible des d’IPs no controlades.
- Separar el fitxer de configuració config/cofnig.php per cada un dels entorns. Així podem definir constants o d’altres tasques de forma particular per cada un dels entorns.
Per tal d’aconseguir aquests objectius he creat el fitxer config/config.lib.php:
<?php /** * Comproba si la IP amb la que s'accedeix a l'aplicació permet connectar en aquest environment * * @param string $env nom de l'environment * @param array $ips ips des de les que podem accedir a l'environment * @param string $clientip ip del client que vol accedir al recurs */ function envCorrecte ($env,$ips,$clientip) { if (SF_ENVIRONMENT==$env) { $acces=0; foreach($ips as $ip) { $ipclient=substr($clientip,0,strlen($ip)); if ($ipclient==$ip) { $acces=1; } } if ($acces==0) { echo "You are not in '".$env."' environment! (".$ipclient."<>".$ip.")"; exit; } } } /** * Comproba si l'aplicació amb la que s'accedeix al projecte és publica o no * * @param array $apps llista d'aplicacions no públiques * @param array $ips llista d'IP amb les que es pot accedir a les apps no públiques * @param string $clientip ip del client que vol accedir al recurs */ function appCorrecte ($apps,$ips,$clientip) { // solucionem problema de la clau '0' $apps_aux[0]=''; $apps = $apps_aux + $apps; // if (array_search(SF_APP,$apps)!=false) { $acces=0; foreach($ips as $ip) { $ADR=$HTTP_SERVER_VARS['REMOTE_ADDR']; $ipclient=substr($clientip,0,strlen($ip)); if ($ipclient==$ip) { $acces=1; } } if ($acces==0) { echo "Keep away! ".SF_APP." is not a public application!"; exit; } } } ?>
Llavors des del fitxer config/config.php cal que cridem aquesta petita llibreria de funcions que he creat. La resta és més que lògica, aquí en teniu un exemple:
<?php include("config.lib.php"); /** * Controlem accés als 'environments' de 'env' i 'int' */ $ip_dev=array("10.138.0.","192.168."); $ip_int=array("10.138.0.","192.168."); envCorrecte('env',$ip_env,$HTTP_SERVER_VARS['REMOTE_ADDR']); envCorrecte('int',$ip_int,$HTTP_SERVER_VARS['REMOTE_ADDR']); /** * Controlem accés a les 'apps' d'ús privat */ $ip_apps=array("10.138.0.","192.168.","w.x.y.z"); $apps=array('myapp_1','myapp_2','myapp_n'); appCorrecte($apps,$ip_apps,$HTTP_SERVER_VARS['REMOTE_ADDR']); /** * Carreguem el fitxer de configuració propi de l'"environment". */ include("config.".SF_ENVIRONMENT.".php"); /** * Part comú en els 3 entorns */ ?>
Com podeu veure el codi és molt senzill i la potència i el dinamisme, excepcionals.
Aquest codi també l’he publicat com un snippet a Access control to environment and applications and custom global config file for an environment.
symfony: entorns de desenvolupament, integració i producció
Al desenvolupar un projecte de software m’agrada treballar en 3 entorns. Mentre s’esta desenvolupant el projecte esta bé tenir un espai de variables (o entorn de noms) a l’aplicació que correspongui als ajustaments del servidor de desenvolupament (normalment una màquina pròpia), per exemple, els path, urls, dades de la bbdd, etc. tot això ha d’estar el màxim separat possible del codi per tal de poder crear les configuracions pels entorns d’integració i producció.
L’entorn d’integració és una màquina en l’entorn de desenvolupament del client, amb les característiques el més semblants possibles a l’entorn de producció. O sigui, les dades de configuració de l’espai de noms han d’apuntar a serveis si pot ser de la mateixa versió que l’entorn de producció. Així podem provar l’aplicació i millores de l’aplicació abans de passar-la a producció. Finalment hem de tenir l’entorn de noms per producció amb les dades de treball.
Per tal de suportar tot això symfony suporta en moltíssims fitxers de configuració la possibilitat de definir l’environment, en el cas que plantejo, ‘dev’, ‘int’ i ‘prod’. En el front controller de cada aplicació podem definir aquest entorn de noms així després s’accedirà a la part dels fitxers de configuració que pertoca.
Per exemple, si mirem el fixer config/databases.yml on symfony defineix els sistemes de BBDD que usa la nostre aplicació en cada un dels environments podriem tenir algo així:
dev: nombbdd: class: sfPropelDatabase param: phptype: mysql hostspec: localhost database: nombbdd username: userbbdd password: passbbdd int: nombbdd: class: sfPropelDatabase param: phptype: oracle username: nombbdd password: nombbdd hostspec: hostint database: NULL prod: nombbdd: class: sfPropelDatabase param: phptype: oracle username: nombbdd password: nombbdd hostspec: hostprod database: NULL
Al cridar el front controller és quan symfony diu amb quin environment treballarem, per exemple, per una aplicació anomenada myapp podriem tenir aquests tres front controllers un per cada entorn:
Entorn de desenvolupament web/myapp_dev.php:
<?php define('SF_ROOT_DIR', realpath(dirname(__FILE__).'/..')); define('SF_APP', 'myapp'); define('SF_ENVIRONMENT', 'dev'); define('SF_DEBUG', true); # require_once(SF_ROOT_DIR.DIRECTORY_SEPARATOR.'apps'.DIRECTORY_SEPARATOR.SF_APP.DIRECTORY_SEPARATOR.'config'.DIRECTORY_SEPARATOR.'config.php'); # sfContext::getInstance()->getController()->dispatch(); ?>
Entorn de integració web/myapp_int.php:
<?php define('SF_ROOT_DIR', realpath(dirname(__FILE__).'/..')); define('SF_APP', 'myapp'); define('SF_ENVIRONMENT', 'int'); define('SF_DEBUG', true); # require_once(SF_ROOT_DIR.DIRECTORY_SEPARATOR.'apps'.DIRECTORY_SEPARATOR.SF_APP.DIRECTORY_SEPARATOR.'config'.DIRECTORY_SEPARATOR.'config.php'); # sfContext::getInstance()->getController()->dispatch(); ?>
Entorn de producció web/myapp.php:
<?php define('SF_ROOT_DIR', realpath(dirname(__FILE__).'/..')); define('SF_APP', 'myapp'); define('SF_ENVIRONMENT', 'prod'); define('SF_DEBUG', false); # require_once(SF_ROOT_DIR.DIRECTORY_SEPARATOR.'apps'.DIRECTORY_SEPARATOR.SF_APP.DIRECTORY_SEPARATOR.'config'.DIRECTORY_SEPARATOR.'config.php'); # sfContext::getInstance()->getController()->dispatch(); ?>
Com es pot veure, tan desenvolupament com integració ens mostraran informació de debug i producció amagarà els missatges d’error i reportarà sempre l’error “internal server error”. A més podem veure que tots tres entorns criden el mateix fitxer de configuració global config/config.php.
Si voleu més informació sobre aquest tema us recomano els següents enllaços de la documentació de symfony: