Éste es uno de esos artículos que escribes para acordarte de cómo has hecho algo.

Hace unos meses me quedé sin conexión IPv6 en casa, porque SixXs cerró su broker IPv6 y no hay otro proveedor que ofrezca túneles que se puedan usar con NAT. Aparte de SixXs, el otro gran broker de IPv6 es Hurricane Electric (de ahora en adelante, "HE"). Pero no es posible establecer un túnel con HE desde un equipo que sale a Internet por NAT sin tocar la configuración del router (lo que no puedo ni quiero hacer); y si no tienes IP fija, también hay que hacer un par de apaños.

Por suerte tengo un pequeño VPS por ahí adelante, y se me ocurrió usarlo como mi broker personal. El plan es conectarme a él con OpenVPN, que estará configurado para usar un rango IPv6 público con sus clientes, y luego rutar el tráfico desde ellos hacia Internet.

He hecho un esquema algo cutre pero que debería ayudar a hacerse una idea:



Todo esto no es trivial. No sabía si era posible hasta que lo probé, aunque había visto gente en Internet que había hecho cosas parecidas. Por el siempre digno motivo de saciar mi vanidad y, si acaso, ayudar a alguien en mi misma situación, pongo por aquí cómo lo hice. He usado CentOS 6, pero la configuración para otras distribuciones es casi igual. La única parte que cambia es la configuración del túnel con HE.

Es posible que me deje algo, y que tras leer las tropecientas palabras de este artículo encuentres que nada funciona. Si es así, deja un comentario, por favor.

La parte de registrarse en HE y pedir un túnel IPv6

Vas a https://www.tunnelbroker.net/. Te registras. Das de alta un nuevo túnel. Ya está.

La parte de configurar el túnel en CentOS

Para configurar el túnel con HE en CentOS hay que:
  • Crear el fichero /etc/sysconfig/network-scripts/ifcfg-sit1 con la configuración del interfaz de red
  • (opcional) Añadir una entrada al fichero /etc/iproute2/rt_tables con la nueva tabla de rutado que usaremos
  • Crear el fichero en /etc/sysconfig/network-scripts/rule6-sit1 para una regla de rutado que use la tabla anterior
  • Crear el fichero en /etc/sysconfig/network-scripts/route6-sit1 para la ruta por defecto a través de HE
Los dos últimos pasos hacen falta porque vamos a hacer policy routing: le vamos a decir al VPS que sólo envíe al gateway de HE el tráfico que tenga como origen nuestras direcciones IPv6. Hay una introducción al policy routing en Linux aquí, y un libro online aquí.

Mi fichero /etc/sysconfig/network-scripts/ifcfg-sit1 tiene este contenido:
DEVICE=sit1
BOOTPROTO=none
ONBOOT=no
IPV6INIT=yes
IPV6TUNNELIPV4=114.86.64.216
IPV6TUNNELIPV4LOCAL=65.183.45.17
IPV6ADDR=2001:948:cd:84::2/64
Donde:

  • IP de HE para el túnel es la que aparece en la página del túnel de HE como Server IPv4 Address. Es la IP (v4) a la que enviaremos el tráfico IPv6 desde el VPS, encapsulado en IPv4, para que desde allí salga a la red nativa IPv6.
  • IP local es la que aparece en la página del túnel de HE como Client IPv4 Address. Es la IP (v4) pública del VPS.
  • IPv6 local en el túnel es la que aparece en la página del túnel de HE como Client IPv6 Address. Hay que incluir la máscara también. Normalmente será /64, que es lo que he puesto ahí arriba, pero podrías pedir un rango más grande (/48, por ejemplo).

Como verás, he puesto ONBOOT=no. Eso significa que tendrás que levantar el túnel a mano después de un reinicio. Recomiendo que lo dejes así hasta que tengas todo funcionando y entiendas cada parte. Si pasara algo raro y levantar el túnel te dejara sin conexión, podrías reiniciar el equipo y recuperarla. No debería pasar nunca, pero cosas veredes, amigo Sancho.

Vamos a necesitar una nueva tabla de rutado para el tráfico que queramos enviar a través de HE. Podemos referirnos a ella con un número (entre el 2 y el 252; los demás están reservados), pero si añadimos una entrada en /etc/iproute2/rt_tables podremos referirnos a ella con un nombre. Yo he escogido el número 100, y le he puesto el nombre de he-ipv6. Para eso sólo hay que añadir esta línea al fichero mencionado:
100    he-ipv6
Si quieres comprobar que lo has hecho bien, puedes usar este comando:
ip route show table he-ipv6
Que, como de momento no hemos puesto ninguna ruta ahí, no devolverá ningún resultado, pero dará error si la tabla con ese nombre no está dada de alta. Podrías no hacer esto y usar "100" en lugar de "he-ipv6" en todos los comandos a continuación, pero así es más fácil.

El contenido del fichero /etc/sysconfig/network-scripts/rule6-sit1 es éste:
from 2001:948:cd:84::/64 table he-ipv6
from 2001:fa57:33:44::/64 table he-ipv6
La primera red es la que estamos usando en la configuración del túnel. Siempre será la misma que la IPv6 pública de IPV6ADDR menos el último dígito, como en el ejemplo de ahí arriba. La segunda es la de la red que usarán tus dispositivos. De momento no te preocupes, lo veremos en la parte de OpenVPN.

El contenido del fichero /etc/sysconfig/network-scripts/route6-sit1 es éste:
default table he-ipv6 via 2001:948:cd:84::1
La IPv6 del extremo de HE es lo que aparece como Server IPv6 Address en la página de configuración del túnel. Esta vez, no debe llevar la máscara de red, y salvo excepción, será la dirección "1" de la red que has usado en el fichero rule6-sit1.

Con todo esto sólo queda hacer "ifup sit1" y tendremos un túnel IPv6 listo. Podemos comprobar que funciona haciendo ping al otro extremo del túnel, el que pusimos como gateway por defecto:
ping6 2001:948:cd:84::1
Si funciona, ¡felicidades! Ya tienes acceso a IPv6 a través de HE.

La parte de OpenVPN

Ahora viene la parte difícil. Sí, la anterior era la fácil.

Tenemos que configurar OpenVPN para que asigne a sus clientes direcciones de la red IPv6 que nos ha asignado HE, la que aparece como Routed /64 (bajo Routed IPv6 Prefixes). La red IPv6 que estamos usando en el túnel es sólo una red "de distribución", que nos sirve para rutar el resto del tráfico. La red que vamos a usar ahora es la red a la que pertenecerán nuestros dispositivos, la que tendrá las direcciones con las que podremos llegar a ellos usando IPv6. Para este ejemplo voy a usar la 2001:fa57:33:44::/64. A partir de ahora, cuando hable de "nuestra red IPv6", siempre me referiré a ésta. Olvida la otra como si nunca la hubieras visto.

Configurar OpenVPN daría para otro post, y hay "howtos" por todos los sitios. Recomiendo el "quick start" del howto oficial, y el howto sobre OpenVPN con IPv6. Mi configuración de servidor, que usa certificados, es ésta:
port 1194
proto udp
dev tun
topology subnet
ca /etc/easy-rsa-openvpn-2.0/keys/ca.crt
cert /etc/easy-rsa-openvpn-2.0/keys/server.crt
key /etc/easy-rsa-openvpn-2.0/keys/server.key
dh /etc/openvpn/dh1024.pem
tls-server
server 192.168.235.128 255.255.255.224
server-ipv6 2001:fa57:33:44::/64
ifconfig-pool-persist ipp.txt
client-to-client
user nobody
group nobody
persist-key
persist-tun
Asusta un poco, pero es una configuración bastante sencilla. Lo más destacable es:

  • client-to-client: para que los clientes de la VPN puedan verse entre sí
  • ifconfig-pool-persist ipp.txt: para que las asignaciones de IP sean permanentes, y se guarden en el fichero ipp.txt

No tienes que copiar toda esta configuración. Si ya tienes un servidor OpenVPN funcionando, lo único que hay que añadir para servir direcciones IPv6 además de las IPv4 es esta línea:
server-ipv6 2001:fa57:33:44::/64
OpenVPN se configurará en la primera IP de esta red y usará IPs de toda la red para los clientes. Puedes modificar la asignación cambiando las entradas del fichero ipp.txt. Así sabrás a qué IP corresponde cada dispositivo.

Para la configuración del cliente he usado esto:
client
dev tun
proto udp
remote  mivps.en.internet 1194
resolv-retry infinite
nobind
user nobody
group nogroup
persist-key
persist-tun
Con todo esto funcionando vamos a conseguir que el cliente se conecte al servidor y éste le asigne una IPv6 en la red 2001:fa57:33:44::/64. Desde ese momento, el cliente estará casi conectado a Internet por IPv6.

Algunas comprobaciones para saber si la configuración funciona:
  • Hacer ping a la IP del servidor OpenVPN: ping6 2001:fa57:33:44::1
  • Comprobar que hay una ruta activa para la red IPv6: ip -6 route show | grep 2001:fa57:33:44 (debería salir una entrada como mínimo)
Configurar el cliente OpenVPN es todo lo que tienes que hacer en el cliente. Yo uso Gnome, y he configurado la VPN con el asistente de configuración de redes. Si usas algo distinto, espero que sea igual de fácil; si no, siempre queda la opción de usar OpenVPN en línea de comandos.

¿Todo bien hasta aquí? Pon un comentario si te has atascado en algún sitio. A lo mejor no contesto nunca porque no lo veo a tiempo, o porque me caes mal, o lo que sea, pero eso no debería arredrarte.

La parte de hacer visibles los clientes OpenVPN en Internet

Lo que nos queda por hacer ahora tampoco es fácil. Tenemos que hacer que el tráfico que venga desde Internet para nuestra red IPv6, a través del interfaz sit1, sea rutado a través del interfaz tun0 (el que creará OpenVPN) hacia nuestros clientes. Además, también tenemos que hacer posible el tránsito opuesto: desde nuestros clientes OpenVPN hacia Internet.

Para empezar tenemos que activar el forwarding IPv6. Esto sirve para que Linux permita el paso de paquetes entre interfaces; o dicho de otra forma, para permitir el rutado entre las redes a las que está conectado el equipo.

Podemos hacerlo con este comando:
sysctl -w net.ipv6.conf.all.forwarding=1
Esto no es lo más limpio del mundo. Lo correcto sería activarlo sólo para los interfaces necesarios. Pero como en mi VPS no hay mucho más, y luego vamos a limitar el tráfico usando ip6tables, no es importante.

Recuerda que este cambio no es permanente. Si quieres que lo sea, tienes que añadir esta línea a /etc/sysctl.conf (o a un fichero en /etc/sysctl.d, si tu distribución lo soporta):
net.ipv6.conf.all.forwarding=1
Ahora tenemos que permitir el tráfico en el firewall. ¿No tienes firewall? Es el momento de ponerlo. Es peligroso tener un equipo en Internet y no limitar quién puede acceder a sus servicios.

Breve inciso sobre iptables (e ip6tables, que es el comando equivalente para IPv6): hay tres "cadenas" a las que se distribuye el tráfico según su origen y destino. La primera es INPUT (así, en mayúsculas), para el tráfico que va al propio equipo; luego viene OUTPUT, para el tráfico que sale del equipo; y por fin tenemos FORWARD, que es para el tráfico que pasa a través del equipo (para el que no es ni origen ni destino). Ésta es la cadena que vamos a tener que "tunear" para limitar y permitir el tráfico entre Internet y nuestros clientes OpenVPN.

Cada cadena tiene una política por defecto, que se llama target. Puede ser ACCEPT (aceptar todo el tráfico) o DROP (no aceptar nada). El equipo arranca con todas las cadenas en ACCEPT, pero lo recomendable es cambiarlas a DROP y luego añadir reglas para permitir sólo el tráfico deseado. En redes "de confianza" no merece la pena y se puede dejar todo a ACCEPT, pero si vas a poner un equipo en Internet es mejor que permitas sólo el tráfico que necesites.

Lo que necesitamos para permitir el tráfico entre Internet y nuestra red OpenVPN es poner a DROP la política de la cadena FORWARD y añadir algunas reglas para permitir el paso de cierto tráfico. Si ponemos la política a ACCEPT, todos los dispositivos que conectemos a la red OpenVPN serán accesibles desde Internet. Como no queremos eso, vamos a permitir (de momento) sólo el tráfico que sale de nuestra red OpenVPN y va hacia Internet.

Cuidado si haces estos cambios en un equipo al que no tienes acceso físico. Una equivocación podría dejarte sin acceso. Caveat lector!

Los comandos para esto serían:
ip6tables -P FORWARD DROP
ip6tables -I FORWARD -i tun0 -o sit1 -j ACCEPT
Análisis de estos dos comandos:

  • El primero pone la política de FORWARD a DROP, para no permitir ningún tráfico entre redes
  • El segundo inserta (-I) una regla en FORWARD (por encima de todas las demás, para que se evalúe de primera) permitiendo (-j ACCEPT) todo el tráfico que entre por nuestro interfaz de OpenVPN (-i tun0) y salga por el túnel con HE (-o sit1)
En CentOS 6 puedes guardar estas reglas en el fichero /etc/sysconfig/ip6tables. Puedes añadir las reglas a mano, pero tendrás que usar el formato de ip6tables-save; es mejor que uses este comando:
service ip6tables save
Que guardará todas las reglas actuales en ese fichero, por si tuvieras alguna más. Para que se carguen durante el arranque, ejecuta este comando:
chkconfig ip6tables on
El servicio ip6tables (que no es lo mismo que el comando ip6tables; es un tanto confuso, lo siento) se encarga de cargar las reglas de ip6tables (ahora sí, el comando), pero también puedes ejecutarlo con otros argumentos:
service ip6tables status # Muestra un volcado de las reglas actuales
service ip6tables stop # Pone todas las políticas a ACCEPT y elimina todas las reglas
service ip6tables start # Carga las reglas definidas en /etc/sysconfig/ip6tables
Con esto ya debería estar todo. Si conectas un cliente OpenVPN y haces un ping a Google, por ejemplo (ping6 ipv6.google.com), debería funcionar. Hay varias razones por las que podría fallar. Pongo las más sencillas a continuación.

La parte de los problemas más frecuentes

Tu cliente OpenVPN no ha insertado una ruta por defecto para IPv6

La configuración de VPN de Gnome siempre hace que todo el tráfico vaya a través de ella, tanto para IPv4 como para IPv6, pero puede que tu cliente no active esa opción por defecto. Si es así, puedes hacer como dicen en el howto de OpenVPN para IPv6 y añadir esta línea a la configuración del servidor:
push "route-ipv6 2000::/3"
Yo no la he puesto porque, como dije, Gnome lo ha hecho por mí. Aparte, creo que es mejor que sea el cliente quien decida si quiere conectarse a Internet a través de la VPN o sólo a los otros clientes de la VPN.

Tu cliente OpenVPN ha insertado una ruta por defecto para IPv4

El opuesto del anterior: a lo mejor después de conectarte te funciona IPv6, pero nada de IPv4. Puede ser que tu cliente insertara una ruta por defecto para IPv4, además de la de IPv6. Puede que el servidor OpenVPN lo haga con un "push", como lo que ponía antes para IPv6. Me temo que tendrás que pelearte con el cliente OpenVPN para que deje de hacerlo, no hay una solución universal.

"ipv6.google.com" no resuelve

La mayor parte de los equipos actuales usan "dual stack", es decir, tanto IPv4 como IPv6. Si llegas a los servidores DNS a través de IPv4, y no hay uno que filtre las direcciones IPv6 por medio, deberías poder obtener la dirección IPv6 de ipv6.google.com de ellos. Si no, puedes añadir a los servidores DNS que estás usando el que proporciona HE: 2001:470:20::2 (éste es el que uso en mi túnel, a lo mejor a ti te da otro). O mejor aún, puedes usar esa IP para comprobar si llegas a Internet usando IPv6 (ping6 2001:470:20::2).

Vale, ya funciona; ¿y ahora qué?

Pues ... más o menos, lo mismo que hacías con IPv4. Personalmente, yo quería una forma rápida de poder navegar por IPv6 desde cualquier sitio y poder acceder a los dispositivos de mi red casera de forma cómoda. En estos tiempos puedes configurar OpenVPN en cualquier cosa, y montarte tu propia VPN con dispositivos tirados por aquí y por allá. Que además la VPN lleve IPv6 es un plus.

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.