En un arrebato, estas navidades me he comprado un teclado Magicforce de 68 teclas.

Mi tesoro teclado

Es un teclado mecánico y cuesta unos 60€, de ahí su encanto. Los teclados mecánicos suelen ser caros, y aunque éste cuesta más de lo que pagarías por un teclado "estándar" (es decir, un asco de teclado), no es demasiado para lo que podrías pagar por un teclado mecánico de otras marcas (alrededor de 100€). Aparte, no sé tú, pero yo apenas uso el teclado numérico, y quería un teclado sin él.

Pero hay un problema: la distribución del teclado no es ISO, sino ANSI. Para entendernos, el ISO es el formato al que estamos acostumbrados en Europa, con una tecla "Enter" que ocupa dos filas y la tecla para los símbolos "mayor que" y "menor que" a la derecha de un "Shift" izquierdo de tamaño mínimo. La distribución ANSI es el normal en los EEUU, y tiene algunas diferencias: la tecla ENTER ocupa sólo una fila, y hay dos teclas para "mayor que" y "menor que" donde nosotros tenemos las teclas para el punto y la coma.

A continuación un esquema, para que se vea la diferencia.

Fuente: wooting.nl


Hay varias versiones de teclados ANSI, para diferentes idiomas, como hay en ISO. Un teclado ISO puede ser español, francés, alemán o de otros idiomas europeos; un teclado ANSI puede ser inglés de los EEUU o inglés de UK (son ligeramente diferentes), por ejemplo. En mi caso es un ANSI americano, como todos los Magicforce.

Escribir en un idioma distinto al inglés de los EEUU en un teclado de éstos es posible, aunque hace falta adaptarse. Hay dos opciones: usar un mapa en español, y mapear de forma manual las teclas que son diferentes, o aprender a usar un mapa americano.

Teclado ANSI y mapa en español

Antes de seguir, un breve repaso de cómo funciona un teclado de ordenador. Tu teclado no envía letras ni números, sino códigos (scancodes). Linux convierte esos códigos a otros, los keycodes, que son interpretados según un mapa de teclado para convertirlos en los caracteres que acabamos viendo en la pantalla.

Se puede usar un mapa de español sobre un teclado ANSI. Sólo tienes que cargarlo en consola con loadkeys o en X con setxkbmap. Lo malo es que las teclas estarán cambiadas de sitio: donde pone un punto y coma estará la eñe, los paréntesis estarán una tecla más a la izquierda de lo que pone en el teclado, y las comillas estarán donde pone que está la arroba, entre otros cambios. Incluso para esto hay solución: los teclados Magicforce usan keycaps (tapas de teclas) estándar, y hay muchos juegos de recambio en Internet que podemos usar para alterar su aspecto y, de paso, poner los caracteres españoles donde están en un teclado normal. La mayor parte de los keycaps están en inglés, pero los hay en español ... dicen por ahí. Yo no los he encontrado. Puede que los venda un unicornio en una tienda al final del arcoiris.

Hay algunas teclas que no podremos mapear porque, simplemente, no existen en el teclado. En un teclado ISO hay una tecla para "mayor que" y "menor que", pero en el ANSI no existe. Para solucionarlo podemos seguir usando el mapa en español y asignar esos valores a alguna combinación de teclas exótica, como AltGr con "z" y "x". Para eso usaremos xmodmap.

xmodmap sirve para establecer combinaciones de teclas y modificadores (como "Shift", o "AltGr"). Aunque no lo sepas, ya lo estás usando: tu entorno de escritorio lo llama al arrancar la sesión para configurar el mapa de teclado que vas a usar. En Gnome se puede configurar el teclado para que la combinación de teclas Windows+Espacio cambie el mapa de teclado entre varios predefinidos, y lo que hace "por debajo" es usar xmodmap para cargar un mapa u otro.

Como lo que queremos es cambiar las combinaciones de las letras "z" y "x", lo primero que tenemos que hacer es ver la configuración actual para ellas. Podemos ver toda la configuración actual de xmodmap con este comando:

$ xmodmap -pke

Cada línea tiene esta forma:

keycode XX: valor1 valor2 valor3 valor4 valor5 valor6 valor7 valor8 valor9 valor10

Donde:

  • XX es el número del keycode
  • valor1-valor10 son los caracteres o valores especiales (como "página arriba", "página abajo", etc.) asignados a cada keycode según el modificador que se está usando

El primer valor es el del keycode sin ningún tipo de modificador. Por ejemplo, si pulsamos la letra "z". El segundo es el del keycode aplicando el modificador "Shift": al pulsar "z" y "Shift", el resultado sería la "Z". A partir del segundo valor la cosa se complica: cada valor es el de la tecla con uno de los modificadores de X ("mode_switch", "Alt", "Meta", "Hyper" ...), y a su lado el mismo con la tecla "Shift".

El par de valores que nos interesa es el tercero, que corresponde a las combinaciones con "AltGr" (puedes fiarte de mí o ir a este enlace, donde lo explican con más detalle). Para buscar los keycodes que corresponden a la "z" y a la "x" podemos buscar los pares "z Z" y "x X" con grep en la salida del comando que te puse antes:

$ xmodmap -pke | grep "z Z"
$ xmodmap -pke | grep "x X"

Que tendrá que darte una salida parecida a esto:

$ xmodmap -pke | grep "z Z"
keycode  52 = z Z z Z guillemotleft less
$ xmodmap -pke | grep "x X" 
keycode  53 = x X x X guillemotright greater

Como puedes ver, las letras y números tienen una representación evidente (ellos mismos: "z" es "z"), pero para otros caracteres hay nombres especiales. "guillemotleft" es una comilla angular izquierda («), "guillemotright" es su equivalente derecha (»), "less" es el símbolo "menor que" y "greater" es el símbolo "mayor que".

Te habrás dado cuenta de que  "menor que" y "mayor que" ya están entre las combinaciones de teclas disponibles para "z" y "x". En concreto, como es la segunda opción del tercer par, estarían accesibles usando AltGr+Shift+"z" y AltGr+Shift+"x", respectivamente. Podrías dejarlo así; pero personalmente, uso mucho más a menudo esos dos caracteres que las comillas angulares, y prefiero ahorrarme la pulsación de un modificador. Por lo tanto, podemos intercambiar sus valores para que los símbolos de "menor que" y "mayor que" salgan sólo con AltGr. Los comandos para hacerlo serían éstos:

$ xmodmap -e "keycode 52 = z Z z Z less guilllemotleft"
$ xmodmap -e "keycode 53 = x X x X greater guillemotright"

¡Tachán! Ahora al pulsar AltGr+"z" saldrá el símbolo "<", y al pulsar AltGr+"x" saldrá ">".

Todavía se podrían hacer más cosas con xmodmap. Otra tecla que no existe en un teclado ANSI es la del símbolo "primero/primera" que tenemos en el ISO español, y podríamos buscarla en el mapa actual y asociarla a otra combinación de teclas. Las posibilidades son infinitas.

Teclado ANSI con mapa "nativo"

Hay otra opción si tienes un teclado ANSI americano, aunque requiere más esfuerzo: usarlo como tal. Para eso vas a necesitar activar un mapa de teclado especial, que cubre las teclas estándar de un teclado ANSI americano pero añade cambios que hacen posible usarlo con caracteres internacionales. Este mapa se llama, apropiadamente, "US International". Y hay dos variantes, de la que vamos a usar la que usa dead keys.

Las dead keys son las teclas que no muestran ningún caracter por sí solas, sino que lo hacen al combinarlas con otra. El ejemplo más sencillo son las vocales con tilde. Para escribir "á", pulsas primero la tecla de la tilde y luego la tecla "a". El mapa de teclado internacional de US con "teclas muertas" hace eso mismo, con lo que teclear letras con tilde se hace igual que en el teclado ISO español.

Otras combinaciones de teclas habituales para nosotros son algo más complicadas: por ejemplo, para la letra eñe hay que usar AltGr+"n". Si nos molesta podemos usar xmodmap para algo más cómodo. He visto gente en Internet que cambia la combinación de tilde y n (que por defecto muestra "ń") por la eñe. Dejo otros ejemplos como ejercicio para el lector.

En Gnome o KDE podemos cambiar la configuración del teclado para alternar entre varios mapas, y lo único que tendríamos que hacer es añadir el internacional US con teclas muertas para usarlo siempre que quisiéramos usar el teclado ANSI. En Unity (Ubuntu) el cambio está vinculado por defecto a la tecla Windows y la barra espaciadora, y el mapa usado se muestra en un pequeño icono de la barra de estado.

Si lo queremos hacer por las bravas, también podemos abrir una consola y usar setxkbmap:

$ setxkbmap us -variant intl

Pero es lo mismo que conseguirás con el "switcher" de tu escritorio.

Personalmente, yo he optado por la segunda opción. Sigo usando un teclado ISO en español en el trabajo, porque tampoco quiero convertirme en un paria a base de usar un teclado que no usa nadie a mi alrededor, pero me parece que alternar entre mapas de teclado es una buena gimnasia mental. Tecleo un poco más despacio, pero a cambio puedo usar un teclado con un tacto fantástico. Y eso me recuerda una estrofa de una canción que recordarás si eres un viejo como yo:

Dicen que tienes veneno en la piel
y es que estás hecha de plástico fino.
Dicen que tienes un tacto divino
y quien te toca se queda con él.

No tiene veneno ni piel, está hecho de plástico pero no especialmente fino, tiene un tacto divino ... y no sé si quien lo toca se queda con él, pero mi mujer ya ha hecho varios comentarios que me inducen a pensar que pronto habrá otro teclado como éste en casa.

Referencias






TL;DR


Telefónica ha hecho un uso "creativo" del DNS, que implica que quien tenga soporte IPv6 podría no acceder a www.agenciatributaria.es.

El problema


Imagínate esto: quieres consultar algún dato para hacer la declaración de la renta 2013/2014, o quizás confirmar tu borrador. Lanzas tu navegador favorito y pones www.agenciatributaria.es en la barra de navegación. Para tu sorpresa, pasa una de estas cosas:


  • Da un error de "conexión rechazada"
  • Sale una página por defecto de Apache, nginx o algún otro servidor web
  • Una tercera opción que desvelaré luego, para no estropear la historia

Lo más probable es que te pase esto si usas Linux. Puede que tengas algún amigo o compañero al que no le pase, y que usa OSX o Windows. Desde tu móvil tampoco pasa. ¿Por qué? ¿Es por usar Linux?

La explicación


En parte, sí. Es por usar Linux, pero no por algún tipo de discriminación fascista o conspiración judeo-masónica, sino por una cuestión tecnológica: Linux prefiere conectarse a sitios accesibles por IPv6 antes que por IPv4. Un ejemplo práctico: mi otro blog está en un VPS con IPv6, y cuando haces una consulta DNS obtienes dos resultados: un registro A con la IP en IPv4 y un registro AAAA con IPv6. Así, si sólo tienes IPv4, te conectas a la IP indicada por el registro A; pero si tienes conexión a Internet con IPv6, te conectas a la IP indicada por el registro AAAA.

"¡Pero yo no tengo conexión a Internet con IPv6!", exclamas. Es cierto, pero sí que tienes conexión a ciertas IPs IPv6. Como mínimo, dos:


  • La IP link-local de tu interfaz de red (la que empieza por fe80). Vete un momento al primer artículo sobre IPv6 que escribí para ver cuál es.
  • La IP ::1, que es la IP en IPv6 del interfaz "lo". O, dicho de otra forma, el equivalente de 127.0.0.1 en IPv6.


Veamos ahora qué pasa cuando le preguntas a un servidor DNS por www.agenciatributaria.es. Esto es lo que sale con el comando host www.agenciatributaria.es:

www.agenciatributaria.es is an alias for b7123.cdn.telefonica.com.
b7123.cdn.telefonica.com is an alias for b7123.1.cdn.telefonica.com.
b7123.1.cdn.telefonica.com has address 81.45.8.14
b7123.1.cdn.telefonica.com has address 81.45.8.8
b7123.1.cdn.telefonica.com has IPv6 address ::

www.agenciatributaria.es es un CNAME (un alias) que apunta a b7123.cdn.telefonica.com, que por el nombre es una parte de la Content Delivery Network (CDN) de Telefónica. Para entendernos, la versión de Telefónica de lo que hace Akamai. A su vez, este registro es un CNAME que apunta a b7123.1.cdn.telefonica.com. El registro b7123.1.cdn.telefonica.com apunta a dos direcciones IP, 81.45.8.14 y 81.45.8.8. Cada vez que preguntes, te dirá una de ellas. Es una forma fácil y común de repartir carga.

Lo interesante viene en la última línea: el registro b7123.1.cdn.telefonica.com también tiene una entrada AAAA (IPv6), apuntando a  ... ¿"::"? ¿Qué es "::"?

Lo mismo que ::1. Es decir: localhost. Telefónica tiene un registro IPv6 apuntando a localhost.

Cuando lanzas el navegador y te conectas a www.agenciatributaria.es, el navegador resuelve el nombre y eso le lleva primero a b7123.cdn.telefonica.com y luego a b7123.1.cdn.telefonica.com. Si no tienes soporte de IPv6, irás a una de las dos IPs apuntadas por este registro. Pero si tienes IPv6, irás a la IP "::", que es lo mismo que "::1". O sea, que te conectarás al servidor web de tu equipo.

Ahora podrás imaginarte la tercera opción que no desvelé antes: puede que cuando te conectas a www.agenciatributaria.es aparezca en tu navegador la página web que tengas configurada en tu servidor local (si existe). Puede que aparezca la página por defecto del servidor. O puede que no tengas ningún servidor web y te dé un error de "Conexión rechazada". He ahí nuestras tres posibilidades.

Todo porque alguien en Telefónica configuró mal un registro DNS.

La solución


La solución, obviamente, es que Telefónica corrija ese registro. Es más: sólo con quitar el registro AAAA ya se arreglaría el problema. Así no habría respuestas IPv6, y todo el mundo iría a las dos IPs balanceadas por el registro b7123.1.cdn.telefonica.com. Si realmente quieren usar IPv6, que pongan una IP de verdad, y no el equivalente de "localhost". Si tu equipo recibe una IP IPv6, seguirá intentando conectarse a ella antes que a la de IPv4; pero como no tienes conexión a Internet con IPv6, la conexión no funcionará y Linux intentará la conexión IPv4. Todo de forma transparente, sin que te enteres.

La chapuza


La forma más chapucera y sencilla de arreglar este problema es añadir una entrada en /etc/hosts para www.agenciatributaria.es con una de las dos IPs a las que resuelve b7123.1.cdn.telefonica.com. Es decir, algo así:

81.45.8.8    www.agenciatributaria.es

De esa forma, no pasarás por los servidores DNS de Telefónica para resolver el nombre, evitando el problema.

Otra solución es que el servidor DNS que usas no te devuelva registros AAAA. Si sólo tienes IPv4, no te hacen falta. Si no controlas el servidor DNS (porque usas el de tu ISP, por ejemplo), no es una solución válida. Pero si es tuyo, y usas Bind, y ha sido compilado con la opción --enable-filter-aaaa , puedes añadir esto a la sección options:

filter-aaaa-on-v4 yes;

De esta forma, Bind no devolverá registros AAAA a clientes que hayan hecho la consulta usando IPv4.

Conclusión


Niños, no dejéis a un becario configurar vuestro DNS. De este servicio dependen cosas importantes, y si no podéis pagar a alguien con conocimientos para que lo administre, es mejor que no os dediquéis a esto.



Volvemos con IPv6, después de demasiado tiempo sin decir nada sobre el tema. Hoy, redes privadas. O dicho de otra forma, la respuesta a la pregunta: ¿qué red escojo para mis pruebas?

RFC 1918: redes privadas en IPv4

El RFC 1918 define las redes privadas que todos conocemos. En orden de menor a mayor tamaño, son:

  • 192.168.0.0/16 (65 mil IPs)
  • 172.16.0.0/12 (un millón de IPs)
  • 10.0.0.0/8 (16 millones de IPs)

Los números no son exactos por eso de que trabajamos con 1024 y no con 1000, pero sirven para ilustrar las cantidades de las que estamos hablando.

En IPv6 existieron un tipo de direcciones llamadas site-local, destinadas a las redes de una organización (un site). Pero como explicaba en el anterior artículo sobre IPv6, fueron marcadas como "deprecated" por la dificultad de definir qué era un site. El verdadero equivalente de las redes privadas IPv4 en IPv6 son las unique local addresses (RFC 4193).

Las unique local addresses son direcciones no rutables globalmente en IPv6. Eso significa que un router no las mandará a Internet, sino que las descartará y te mirará extrañado preguntándose por qué le estás enviando esa porquería. Luego le contará al resto de routers lo patoso que eres. Los routers, por definición, son unos cotillas de cuidado.

El espacio asignado para estas direcciones es fc00::/7, que a su vez se divide en dos redes con máscara de 8 bits: fc00::/8 (pendiente de definición, y reservada) y fd00::/8, que es la que podemos usar.

Uso de la red fd00::/8

La red fd00::/8 nos da chorrocientos miles de millones de direcciones IP (millón arriba, millón abajo). Debería llegar para cualquier red privada del mundo. De hecho, toda la red IPv4 cabría varias veces dentro de ésta: en IPv4 podemos usar 2^32 direcciones IP, y en una red IPv6 con máscara de 8 bits podemos usar 2^(128-8)  = 2^120 direcciones IP.

Si siguiéramos las reglas de asignación de IPs que usamos en IPv4, podríamos definir una subred dentro de fd00::/8 para nuestra LAN casera, y asignar secuencialmente las direcciones para nuestros dispositivos. Por ejemplo: fd00::/120 equivaldría a una clase C en IPv4 (máscara 24, 256 IPs); o, si tuviéramos una red corporativa, podríamos usar fd00::/112 para tener las mismas IPs que en una clase B (máscara 16, 65536 IPs). La dirección de red sería la fd00::0, la primera IP sería la fd00::1 y la IP de broadcast sería la fd00::00ff para la máscara 120 y fd00::ffff para la 112. Pero no es así cómo se hace en IPv6.

En IPv4 podíamos dividir cada dirección IP en dos partes: un prefijo (o "identificador de red") y un sufijo (o "identificador de host"). Ejemplo: en la dirección 192.168.1.50, asumiendo que está en una clase C, el prefijo sería 192.168.1 y el sufijo 50. Una dirección IPv6, en cambio, se divide en más partes:

  • Un prefijo de 8 bits (7+1, en realidad)
  • Un identificador global de 40 bits (que podría ser el ISP)
  • Un identificador de red de 16 bits
  • Un identificador de interfaz de 64 bits

El primer campo son las letras "fd", y no podemos tocarlos (nos saldríamos de la red fd00::/8). Éste y el siguiente campo (los primeros 48 bits) forman lo que se llama el "prefijo de rutado". En algunos sitios verás que se le llama identificador de red a los primeros 64 bits, no sólo los 16 que he puesto aquí; y en otros verás que se llama "prefijo de rutado" a esos mismos 64 bits. Tengan el nombre que tengan, son los que se van a usar para rutar el paquete hasta el dispositivo final.

El identificador único del dispositivo final es la parte de "identificador de interfaz". Puede ser generado de varias formas (a partir de la MAC del dispositivo, por ejemplo), y sólo importa que sea único. Podría repetirse en otra red, pero entonces los primeros 64 bits serían distintos y se mantendría su exclusividad.

En una dirección privada como la que buscamos podemos asignar nosotros los identificadores globales y de red. Podemos generarlos aleatoriamente para cada dispositivo, si queremos. El rutado no será un problema: si hemos definido fd00::/8 como nuestra red casera, cualquier cosa que esté ahí valdrá como dirección IP.

Sin embargo, sin darnos cuenta acabamos de responder a la pregunta inicial de "qué red uso". Podemos mantener la fd00::/8 como red local y generar todo menos los primeros 8 bits aleatoriamente, pero sería como usar la red 10.0.0.0/8 para la red de tu casa. Una opción mejor es buscar unos valores que nos gusten para los primeros 64 bits (teniendo en cuenta que los primeros 8 serán "fd"), y usarlos como nuestro "identificador de red". Tendríamos así una red privada con máscara de 64 bits, en la que cada dispositivo sería identificado por 64 bits generados como nos venga en gana.

Un ejemplo

Una ventaja de las direcciones IPv6 es que puedes usar unas pocas letras, lo que permite cierta creatividad. ¿Qué prefijos de red podríamos crear empezando por "fd" y añadiendo 6 bytes más? Para ver qué ha hecho otra gente en casos parecidos, buscad en Google "funny ipv6 addresses".

Personalmente, como soy un tío aburrido, voy a usar fded:dead::/64, porque se parece a "Red Dead" y así no me olvido de ella.

Próximamente: Asignación de direcciones públicas

Las direcciones IPv6 públicas se dividen en las mismas partes que las privadas: 48 bits de rutado, 16 de identificador de red, y 64 de identificador de dispositivo. Los ISPs tendrán asignadas redes con máscaras de 32 bits, y asignarán a sus usuarios redes con máscaras de 48 bits, que podrán dividirlas hasta en 65536 redes con máscara de 64 bits.

Es un lío, pero un lío interesante que queda para el siguiente artículo. Hasta entonces, espero haberte dejado suficiente para que juegues en casa durante un rato.