ViewRevisions

IPv6 en cualquier lugar con tinc

Ya hace tiempo describí cómo usar 6to4 para proporcionar una conexión IPv6 estable a una máquina dotada de una dirección pública IPv4 fija, un procedimiento realmente simple (al menos en su configuración básica) que nos permite acceder a una nueva Internet donde hay abundancia de direcciones y todos pueden ofrecer sus propios servicios.

No obstante, el procedimiento es prácticamente una entelequia porque si la máquina dispone de una dirección pública IPv4 fija ya es capaz de ofrecer servicios en Internet. En cambio, ¿qué hay de los ordenadores que tenemos en casa tras un dispositivo que hace NAT (y por lo tanto tienen direcciones privadas), o de aquellos que llevamos con nosotros (y por lo tanto tienen direcciones variables)?

En este artículo describo cómo usar tinc para extender la conectividad IPv6 de una máquina con una red IPv6 propia (nativa o 6to4) a ordenadores domésticos y móviles, de forma que éstos tengan direcciones públicamente accesibles de esta red con independencia de su ubicación.

Topología de la red

Tinc es software libre destinado a construir redes privadas virtuales (VPN) que se diferencia de otros productos de VPN en que hace muy sencilla la configuración de redes de topología distribuida sin necesitar nodos centrales para el encaminamiento o la autenticación. Cada nodo tinc define su propia subred y el sistema se encarga de intercambiar las rutas y claves necesarias para que la comunicación tenga lugar de forma directa (si es posible) y segura entre nodos que no se conocen explícitamente.

Asumiremos que tenemos un nodo al que llamaremos pasarela con una dirección pública IPv4 fija y una red IPv6 propia. Para seguir con el ejemplo del artículo anterior, éstas serán 1.2.3.4 y su red 6to4 respectiva 2002:0102:0304::/48 (pero podría ser cualquier otra red IPv6 pública). También asumiremos que el resto de nodos no tienen conexión a la Internet IPv6 ni una dirección IPv4 pública y fija.

Configuraremos tinc para que cada nodo de la red dé acceso a su propia subred 2002:0102:0304:N::/64 (con N = 0 para la pasarela). Los nodos se conectarán a la pasarela, que se encargará así de conectar entre ellas a todas las subredes y de dar acceso a la Internet IPv6 a los nodos que escojan la red tinc como ruta por defecto.

Redes IPv4 y IPv6.

Observad cómo cada nodo tendrá la misma dirección en la red tinc y en la red local a la que dará acceso, cosa que conseguimos usando dos máscaras de red diferentes. En este sentido, el manual es una combinación de este ejemplo y este artículo.

Configuración de la pasarela

Para configurar una pasarela con Debian o similar, en primer lugar instalaremos en ella el paquete tinc. A continuación crearemos el directorio /etc/tinc/inet6 que contendrá los ficheros de configuración de nuestra red, que aquí llamaremos inet6 (tinc puede gestionar varias de ellas al mismo tiempo).

Ahora crearemos el fichero de configuración del servidor tinc para este nodo, /etc/tinc/inet6/tinc.conf:

AddressFamily = ipv4
BindToAddress = gateway.example.net 655
Name = gateway

La única opción realmente necesaria es Name, que aquí establece a gateway el nombre único de este nodo en la red tinc. La opción AddressFamily hace que tinc sólo use conexiones IPv4, cosa razonable para proporcionar IPv6 sobre él. La opción BindToAddress fija la dirección y puerto (TCP y UDP, 655 por defecto) donde escuchará tinc, y puede ser útil si la pasarela tiene múltiples direcciones IPv4 o si vamos a gestionar más de una red con tinc, ya que cada una necesita un puerto diferente.

Para que dos nodos tinc se puedan conectar de forma segura deben conocer con anterioridad sus respectivos nombres y claves públicas, así como las subredes a las que dan acceso. Si un nodo quiere conectar con otro, necesitará saber también la dirección y puerto donde escucha el servidor tinc de éste. Cada nodo define todos estos parámetros en un fichero de configuración de la estación que debe ser copiado a los nodos con los que se quiera conectar.

A continuación crearemos el fichero de configuración de la estación para la pasarela, /etc/tinc/inet6/hosts/gateway. Será necesario crear primero el subdirectorio hosts y es importante que usemos para el fichero el nombre indicado anteriormente en Name.

Address = gateway.example.net 655
Subnet = 2002:0102:0304:0000:0:0:0:0/64
Subnet = 0:0:0:0:0:0:0:0/0

Naturalmente los valores de Address son los indicados más arriba. La subred anunciada es 2002:0102:0304:0000::/64 (tinc no admite notación compacta) como muestra el diagrama así como ::/0, es decir, toda la Internet IPv6.

Completaremos el fichero con la clave pública del nodo, que generaremos ejecutando tincd -n inet6 -K y aceptando las respuestas por defecto. Esto añadirá al final del fichero un bloque BEGIN/END RSA PUBLIC KEY.

Tinc no añade automáticamente ninguna dirección ni ruta a la estación, sino que delega en una serie de scripts para la configuración de la red. En nuestro caso, suponiendo que la pasarela ya tiene configuradas las interfaces y rutas IPv6, crearemos los siguientes scripts /etc/tinc/inet6/tinc-up

#!/bin/sh
ip -6 link set "$INTERFACE" up mtu 1400
ip -6 addr add 2002:0102:0304:0000::1/48 dev "$INTERFACE"

y /etc/tinc/inet6/tinc-down

#!/bin/sh
ip -6 addr del 2002:0102:0304:0000::1/48 dev "$INTERFACE"
ip -6 link set "$INTERFACE" down

que se ejecutarán al iniciar y detener la red inet6 de tinc (no olvidéis hacerlos ejecutables con chmod a+rx SCRIPT). Observad cómo se limita el tamaño máximo (MTU) del datagrama IPv6 a 1400 bytes: tenemos en cuenta la sobrecarga introducida por 6to4 (en nuestro caso) o tinc para reducir la probabilidad de encontrarnos con problemas durante el proceso de descubrimiento de la MTU entre dos estaciones IPv6. El valor más seguro (y un poco menos eficiente) es 1280. Leed este artículo para más información.

Finalmente añadiremos inet6 al fichero /etc/tinc/nets.boot que lista las redes a iniciar automáticamente con el script de arranque de tinc y la pondremos en marcha ejecutando invoke-rc.d tinc restart. Esto completa la configuración del propio tinc.

Si la pasarela tiene configurado un cortafuego aún necesitaremos unos retoques. Dado que recibirá conexiones de otros nodos tinc es importante abrir en el cortafuego los puertos TCP y UDP indicados arriba con las reglas equivalentes a los comandos siguientes:

# iptables -A INPUT -p udp -m udp --dport 655 -j ACCEPT
# iptables -A INPUT -p tcp -m tcp --dport 655 -j ACCEPT

La pasarela también encaminará tráfico IPv6, así que deberemos permitir en el cortafuego el reenvío IPv6 con la regla equivalente a:

# ip6tables -P FORWARD ACCEPT

Y también deberemos habilitar el reenvío IPv6 en el núcleo vía sysctl, por ejemplo:

# cat > /etc/sysctl.d/local-forwarding.conf << EOF
net.ipv6.conf.all.forwarding=1
EOF
# sysctl -p /etc/sysctl.d/local-forwarding.conf

Configuración del resto de nodos

Como he comentado antes tinc es un sistema distribuido y por lo tanto no hay servidores y clientes, sólo nodos que se conectan entre ellos. En nuestro caso los nodos sin direcciones IPv4 públicas y fijas iniciarán las conexiones hacia el nodo pasarela. Pero como veremos las configuraciones son prácticamente las mismas.

Instalaremos el paquete tinc y crearemos el directorio /etc/tinc/inet6. En el fichero de configuración del servidor /etc/tinc/inet6/tinc.conf escribiremos:

AddressFamily = ipv4
BindToAddress = * 655
Name = my_pc
ConnectTo = gateway

Como este nodo iniciará las conexiones con otros (y no a la inversa) no importa la dirección donde escuchará tinc (por eso el *). No obstante, como cada red de tinc necesita un puerto diferente no está de más hacerlo explícito, y en nuestro caso lo usaremos más adelante. Lo más importante aquí vuelve a ser el nombre de este nodo (my_pc) y también las apariciones de opciones ConnectTo que indican por su nombre hacia qué nodos se iniciaran conexiones.

Crearemos el fichero de configuración de la estación /etc/tinc/inet6/hosts/my_pc con las subredes a las que este nodo dará acceso

Subnet = 2002:0102:0304:0004:0:0:0:0/64

e invocaremos tincd -n inet6 -K para crear las claves del nodo. Por cierto, si sólo queremos dar acceso a esta estación podemos usar una máscara /128, p.e. 2002:0102:0304:0004:0:0:0:1/128.

Como conectaremos con el nodo pasarela, deberemos copiar a su directorio hosts el fichero de estación de este nodo, y también copiar al directorio hosts de este nodo el fichero de estación de la pasarela. Compartir los ficheros de estación puede ser el paso más molesto de montar una red tinc, y si hay muchos nodos con una topología de conexiones compleja lo más sencillo es distribuir todos los ficheros de estación de la red juntos (p.e. usando algún sistema distribuido de control de versiones), cosa que también puede ayudar a escoger nuevos nombres y subredes únicos.

Los scripts de configuración de red sólo difieren de los de la pasarela (además de en la dirección asignada, naturalmente) en que añaden una ruta por defecto a la Internet IPv6 vía la red tinc. Así /etc/tinc/inet6/tinc-up:

#!/bin/sh
ip -6 link set "$INTERFACE" up mtu 1400
ip -6 addr add 2002:0102:0304:0004::1/48 dev "$INTERFACE"
ip -6 route add default dev "$INTERFACE"

y /etc/tinc/inet6/tinc-down:

#!/bin/sh
ip -6 route del default dev "$INTERFACE"
ip -6 addr del 2002:0102:0304:0004::1/48 dev "$INTERFACE"
ip -6 link set "$INTERFACE" down

Observad cómo no se indica la dirección del encaminador por defecto, sólo la interfaz por donde enviar los paquetes. Al recibir un paquete, tinc se encarga de encontrar el nodo que da acceso a la subred de destino adecuada (y recordemos que el nodo pasarela anuncia la subred ::/0).

Después de habilitar con chmod la ejecución de los scripts, añadiremos inet6 a /etc/tinc/nets.boot y reiniciaremos tinc con invoke-rc.d tinc restart. A los pocos segundos deberíamos ser capaces de hacer ping a la pasarela:

$ ping6 2002:0102:0304:0000::1
PING 2002:0102:0304:0000::1(2002:102:304::1) 56 data bytes
64 bytes from 2002:102:304::1: icmp_seq=1 ttl=64 time=141 ms
64 bytes from 2002:102:304::1: icmp_seq=2 ttl=64 time=141 ms
64 bytes from 2002:102:304::1: icmp_seq=3 ttl=64 time=142 ms
64 bytes from 2002:102:304::1: icmp_seq=4 ttl=64 time=142 ms

--- 2002:102:304::1 ping statistics ---
4 packets transmitted, 4 received, 0% packet loss, time 3004ms
rtt min/avg/max/mdev = 141.617/142.174/142.737/0.505 ms

Si hay algún problema, revisad /var/log/daemon.log. Si funciona, podéis probar vuestra conectividad con el resto de la Internet IPv6 visitando ipv6-test.com o test-ipv6.com (:D), o SubnetOnline.com a quien podéis indicar vuestra dirección para que le haga ping. Recordad pues que vuestro ordenador estará públicamente accesible vía IPv6, así que más os vale preparar una buena configuración de cortafuego. Y hablando de cortafuego, si vais a dar acceso a más ordenadores en vuestra red IPv6 local, recordad habilitar el reenvío IPv6 en el cortafuego y en el núcleo como se indica anteriormente.

Conexión directa en la red local

Si miráis el diagrama de la red veréis que my_laptop se encuentra en la misma red local que my_pc. Aún así, como no son accesibles desde Internet, si quieren comunicarse entre ellos vía la red IPv6 el tráfico deberá pasar forzosamente por gateway, cosa no muy eficiente. Tinc 1.0.17 o superior permite buscar nodos conocidos en la red local, evitando saltos innecesarios mientras se mantiene la seguridad de los datos. Esto puede ser interesante en redes locales WiFi sin cifrado.

Para habilitar esta búsqueda añadiremos al fichero tinc.conf del nodo la opción LocalDiscovery = yes. Esto hará que tinc difunda por la red local paquetes UDP dirigidos al puerto configurado en el mismo fichero (por esto conviene fijar en él el valor del puerto), lo que significa que este mecanismo sólo funcionará si todos los nodos de la red local usan el mismo puerto.

Por supuesto será necesario que los nodos contactados tengan este puerto abierto en el cortafuego y que los nodos a conectar tengan los ficheros de estación de los otros. De nuevo lo más cómodo es que todos los nodos tengan los ficheros de estación de todos los nodos de la red.