É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.