Crear una red IPV6 para pruebas con VoIP

27 Oct

Muchos de vosotros (yo incluido) no tendréis ipv6 de forma nativa en vuestra conexión a internet, aunque en algunos países si que es así, sobre todo del norte de Europa, o al otro lado del charco.

Sin embargo a nivel de CDN y en servidores dedicados es ya una realidad, de hecho hace poco DigitalOcean anunció soporte para #ipv6.

Considerando que tenemos ese primer paso , teniendo un servidor dedicado o virtual con conexión ipv6, usaremos OpenVPN para “traernos” la ipv6 al otro extremo y rutar dicho tráfico ipv6 través de nuestro servidor dedicado.

¿Por qué no usar un tunnel broker como HE o Sixxs.net?

Lo usé en el pasado y aparte de no tener mucho ancho de banda de salida, siempre te cabe la duda de por donde pasa lo que envías. Generalmente son tunnels ofrecidos por operadores pero no siempre es así. Me quedo más tranquilo enviando mi tráfico ipv6 por un sitio que conozco .

Nada me asegura que en el otro extremo alguien lo esté inspeccionado, pero al menos no pasa por tantos sitios. La desventaja es que quizá el POP (Punto de presencia) que será nuestro servidor dedicado puede no estar a una latencia mínima desde nuestra conexión. Pero siempre podemos incluso tener varios hasta que demos con el que mejor nos funcione.

En el caso de online.net os recomiendo esta guía para echar a andar ipv6 (mejor que dibbler).

En el caso de DigitalOcean que comentaba no distará mucho de lo que aquí mostrado. En muchos casos no hay que usar arducias como dibbler, o un dhcpv6 client si no que tendremos la ipv6 directamente en nuestro eth0.

En muchos servidores virtuales, o cloud, como DigitalOcean os asignarán un /64 aunque limitan las ips configurase a 16 en la prueba que yo he hecho, aún así es  más que suficiente  incluso para el más ambicioso (8,446,744,073,709,551,616 direcciones). En Hetzner creo recordar que también asignaban un /64. En Online.net por ejemplo tienes un /48 para ti solito. No obstante creo que a más de uno os sobrará 🙂

Una vez con nuestro servidor con su dirección ipv6 nativa si usáis DigitalOcean este enlace lo explica muy bien, lo primero que haremos será configurar los servidores DNS para resolución ipv6. Algunos de los servidores ipv4 dns resuelven direcciones a ipv6, pero la mayoría no. Para ello usaremos los de google.

Editaremos /etc/resolv.conf

2001:4860:4860::8844 
2001:4860:4860::8888
8.8.8.8
8.8.4.4

Comprobaremos que podemos salir al internet del futuro haciendo un ping6.

root@IPV6:~# ping6 chico.rediris.es

PING chico.rediris.es(chico.rediris.es) 56 data bytes

64 bytes from chico.rediris.es: icmp_seq=1 ttl=53 time=36.2 ms

64 bytes from chico.rediris.es: icmp_seq=2 ttl=53 time=36.4 ms

Para permitir forwarding ipv4 e ipv6 através del servidor editaremos /etc/sysctl.conf

net.ipv6.conf.all.autoconf = 0

net.ipv6.conf.default.autoconf = 0

net.ipv6.conf.eth0.autoconf = 0

net.ipv6.conf.eth0.accept_ra=1

net.ipv6.conf.all.forwarding=1

net.ipv6.conf.all.proxy_ndp=1
net.ipv4.ip_forward=1

Y activaremos los cambios con:

root@IPV6:/etc/openvpn# sysctl -p
net.ipv6.conf.all.autoconf = 0
net.ipv6.conf.default.autoconf = 0
net.ipv6.conf.eth0.autoconf = 0
net.ipv6.conf.eth0.accept_ra = 1
net.ipv6.conf.all.forwarding = 1
net.ipv6.conf.all.proxy_ndp = 1
net.ipv4.ip_forward = 1
root@IPV6:/etc/openvpn# 

Lo siguiente será instalar openvpn para establecer ese tunnel ipv4 a ipv6 que usaremos en el otro extremo y usado en el laboratorio.

root@IPV6:~# apt-get install openvpn
Reading package lists... Done
Building dependency tree       
Reading state information... Done

Una vez instalado el primer paso es crear los certificados que usaremos para nuestros clientes. Para ello podéis seguir este enlace

Generaremos nuestro server.conf para soportar tap ,usaremos tap en vez de tun porque es el que permite una conexión bridge y transporta de una forma más transparente ipv6. Si es cierto que podéis usar tun ya que en las últimas versiones de openvpn también está soportado.

#################################################
# Sample OpenVPN 2.0 config file for #
# multi-client server. #
# #
# This file is for the server side #
# of a many-clients one-server #
# OpenVPN configuration. #
# #
# 
script-security 3 system
tun-mtu 1492
port 6666

# TCP or UDP server?
proto udp
dev tap
;dev tun
;tun-ipv6
#push tun-ipv6

ca /etc/openvpn/certs/ca.crt
cert /etc/openvpn/certs/voipnovatos.crt
key /etc/openvpn/certs/voipnovatos.key # This file should be kept secret

dh /etc/openvpn/certs/dh2048.pem
#tls-auth /etc/openvpn/certs/ta.key 0


server 192.168.20.20 255.255.255.0
ifconfig-pool-persist ipp.txt

#push "route 192.168.10.0 255.255.255.0"
# Sacamos todo internet ipv6 por el tunnel
push "route-ipv6 2000::/3"
topology subnet

#hablitamos opciones particulares a los clientes
client-config-dir ccd
;route 192.168.40.128 255.255.255.248

push "dhcp-option DNS 8.8.8.8"

client-to-client


# Enable compression on the VPN link.
# If you enable it here, you must also
# enable it in the client config file.
comp-lzo

# The maximum number of concurrently connected
# clients we want to allow.
max-clients 10

# The persist options will try to avoid
# accessing certain resources on restart
# that may no longer be accessible because
# of the privilege downgrade.
persist-key
persist-tun

# Output a short status file showing
# current connections, truncated
# and rewritten every minute.
status openvpn-status.log


# Set the appropriate level of log
# file verbosity.
#
# 0 is silent, except for fatal errors
# 4 is reasonable for general usage
# 5 and 6 can help to debug connection problems
# 9 is extremely verbose
verb 4

# Silence repeating messages. At most 20
# sequential messages of the same message
# category will be output to the log.
;mute 20

;keepalive 10 120
log /var/log/openvpn-server.log
log-append /var/log/openvpn.log

ping 15
ping-restart 45
ping-timer-rem

client-connect /etc/openvpn/client-connect.sh
client-disconnect /etc/openvpn/client-disconnect.sh

Crearemos dos script que configuraran el tunnel ipv6 cuando el cliente se conecte y que ahora mostraremos.

#/etc/openvpn/client-connect.sh
#!/bin/bash

BASERANGE="2001:xxx:xxx:1xx"
ifconfig $dev up
ifconfig $dev add ${BASERANGE}:1001::1/64
ip -6 neigh add proxy 2001:xxx:xxx:1xx:1001::2 dev eth0
ip -6 route add 2001:xxx:xxx:2xx::/64 dev tap0
exit 0
#/etc/openvpn/client-disconnect.sh
#!/bin/bash

BASERANGE="2001:xxx:xxx:1xx"
/sbin/ip -6 addr del ${BASERANGE}:1001::1/64 dev $dev
exit 0

De este modo, cuando el cliente  se conecte tendremos la ip :1001:1 en el lado servidor y :1001:2 en el lado cliente

Para el cliente haremos algo parecido

Muestro ahora la configuración del cliente.



script-security 3 system

tun-mtu 1492


client

resolv-retry infinite

nobind

dev tap

;dev tun

;tun-ipv6

proto udp

remote x.x.x.x 6666

resolv-retry infinite

nobind

# Try to preserve some state across restarts.

persist-key

persist-tun


ca ca.crt

cert cliente1.crt

key cliente1.key


comp-lzo

# Set log file verbosity.

verb 3

# Silence repeating messages

;mute 20

ping 15

ping-restart 45

up /etc/openvpn/up.sh

down /etc/openvpn/down.sh

Siendo el script up.sh el siguiente:

#!/bin/bash

IPV6BASE="2001:xx:xxx:1xx"
ifconfig $dev up
ifconfig $dev add ${IPV6BASE}:1001::2/64
ifconfig eth0 add 2001:xxx:xxx:200::1/64
ifconfig tap0 add 2001:xxx:xxx:200::2/64
ip -6 route add default via ${IPV6BASE}:1001::1 dev tap0
ip -6 route del 2001:xxx:xxx:200::/64 dev tap0
/etc/init.d/npd6 start
exit 0

Y el down.sh

#!/bin/bash

IPV6BASE="2001:xxx:xxx:1xx"
/sbin/ip -6 addr del ${IPV6BASE}::2/64 dev $dev
/sbin/ip link set dev $dev down
/sbin/ip route del ::/0 via ${IPV6BASE}::1
exit 0

Lanzaremos openvpn en cliente y servidor y esperaremos hasta que veamos establecido el enlace tap0.

 
tap0      Link encap:Ethernet  HWaddr xx:xx:xx:xx:xx  
          inet addr:192.168.20.2  Bcast:10.0.2.255  Mask:255.255.255.0
          inet6 addr: 2001:xxx:xxx:1xx:1001::2/64 Scope:Global
          inet6 addr: 2001:xxx:xxx:200::2/64 Scope:Global
          inet6 addr: fe80::xxxx:xxxx:xxxx:xxxx/64 Scope:Link
          UP BROADCAST RUNNING ALLMULTI MULTICAST  MTU:1492  Metric:1
          RX packets:280 errors:0 dropped:0 overruns:0 frame:0
          TX packets:347 errors:0 dropped:0 overruns:0 carrier:0
          collisions:0 txqueuelen:100 
          RX bytes:130164 (127.1 KiB)  TX bytes:55111 (53.8 KiB)

y nuestro eth0 del cliente que será la que usemos para conectar nuestros dispositivos de laboratorio. Puede ser una raspberry o lo que queráis:

eth0      Link encap:Ethernet  HWaddr xx:xx:xx:xx:xx:xx  
          inet addr:10.0.1.1  Bcast:10.0.1.255  Mask:255.255.255.0
          inet6 addr: 2001:xxx:xxx:200::1/64 Scope:Global
          inet6 addr: fe80::xxxx:xxxx:xxxx:xxxx/64 Scope:Link
          UP BROADCAST RUNNING MULTICAST  MTU:1500  Metric:1
          RX packets:2134 errors:0 dropped:0 overruns:0 frame:0
          TX packets:1466 errors:0 dropped:0 overruns:0 carrier:0
          collisions:0 txqueuelen:1000 
          RX bytes:472069 (461.0 KiB)  TX bytes:315415 (308.0 KiB)

Probaremos que llegamos al otro extremo:

root@raspberrypi:~# ping6 2001:xxx:xxx:1xx:1001::1
PING 2001:xxx:xxxx:1xxx:1001::1( 2001:xxx:xxxx:1xxx:1001::1) 56 data bytes
64 bytes from 2001:xxx:xxxx:1xxx:1001::1 icmp_seq=1 ttl=64 time=142 ms
64 bytes from 2001:xxx:xxxx:1xxx:1001::1: icmp_seq=2 ttl=64 time=72.7 ms
64 bytes from 2001:xxx:xxxx:1xxx:1001::1 icmp_seq=3 ttl=64 time=73.0 ms
^C
---  2001:xxx:xxxx:1xxx:1001::1 ping statistics ---
3 packets transmitted, 3 received, 0% packet loss, time 2003ms
rtt min/avg/max/mdev = 72.745/96.227/142.891/32.998 ms
root@raspberrypi:~# 

En ipv6 para asignar direcciones tenemos una cosa denominada Autoconfiguración que lo que hará es que el dispositivo que reciba los RA de un router que así lo indique , con la subred, hará que cree una dirección ipv6 temporal con ese prefijo y generalmente las direcciones mac de la tarjeta.

Generalmente la veremos así:

en0: flags=8863<UP,BROADCAST,SMART,RUNNING,SIMPLEX,MULTICAST> mtu 1500
	ether xx:xx:xx:ed:7a:19 
	inet6 2001:xxx:xxx:200:xxxx:xxxx:xxed:7a19 prefixlen 64 autoconf 

Ahora necesitamos nuestro servidor radvd para que los dispositivos que son compatibles con la autoconfiguración así lo hagan.

Instalamos radvd con apt-get install radvd y configuramos en /etc/radvd.conf

interface eth0
{
       AdvSendAdvert on;
       prefix 2001:xxx:xxx:200::/64
       {
               AdvOnLink on;
               AdvAutonomous on;
               AdvRouterAddr on;
       };
};

Ahora si todo va bien arrancando el servicio /etc/init.d/radvd start empezaremos a autoconfigurarse los dispositivos en nuestra red pero falta una cosa.

En IPv6 para que una dirección se vea desde el lado internet se usa ND, Neighbor Discovery que es como el “ARP” en IPV4.. Para saber quien la tiene se lanza un paquete preguntando y cuando responde se hace visible y se mantiene activa durante un tiempo

Para ello en linux es necesario hacer lo que veíamos como:

ip -6 neigh add proxy 2001:xxx:xxx:xxx1::10 dev eth0

Evidentemente no podemos hacer esto para todas y cada una de las direcciones autoconfiguradas por lo que usaremos un proxy NDP que haga ese trabajo por nosotros

Uno de los más conocidos es ndp6.

Lo compilamos y configuramos como sigue:

// npd6 config file

prefix=2001:xx:xxx:200:

interface = tap0

ralogging = off

listtype = none

collectTargets = 100

linkOption = false

ignoreLocal = true

routerNA = true

maxHops = 255

pollErrorLimit = 20

Después de eso deberemos tener ipv6 desde cualquier PC de nuestra red o laboratorio para ahora probar VoIP sobre IPV6 🙂

Leave a Reply

Your email address will not be published. Required fields are marked *