Compartir internet Wi-Fi con un contenedor LXC

En el post anterior sobre LXC usamos el comando lxc-device para conectar un dispositivo real de nuestra PC a un contenedor LXC. Esto es una buena solución cuando tenemos, por ejemplo, 2 adaptadores de red o bien cuando todo lo demás falla 😛 ya que nos permite tener internet en el contenedor aún si tenemos que quedarnos momentáneamente sin internet en nuestra PC. La solución ideal sería compartir el internet de nuestra PC con el contenedor, lo que puede ser sencillo creando una conexión de puente si tenemos internet por cable ethernet pero no tan sencillo si tenemos internet por Wi-Fi, como ya lo explicamos también en el post anterior. En este post veremos como compartir internet Wi-Fi usando el comando iptables.

Ya en el post anterior hablamos sobre la opción de usar iptables para compartir internet con un contenedor LXC. El problema es que muchas de las referencias disponibles no están en español y aún en inglés suelen ser crípticas si no se tienen los conocimientos necesarios. En realidad, compartir internet usando iptables es muy fácil cuando no se omite información y se explica de una manera clara y no de una forma críptica.

Para compartir internet Wi-Fi con un contenedor LXC, antes que nada hay que averiguar la dirección IP usada por nuestro adaptador de red inalámbrico:

monstruosoft@PC:~$ sudo ifconfig 
lo        Link encap:Local Loopback  
          inet addr:127.0.0.1  Mask:255.0.0.0
          inet6 addr: ::1/128 Scope:Host
          UP LOOPBACK RUNNING  MTU:65536  Metric:1
          RX packets:137 errors:0 dropped:0 overruns:0 frame:0
          TX packets:137 errors:0 dropped:0 overruns:0 carrier:0
          collisions:0 txqueuelen:0 
          RX bytes:28230 (27.5 KiB)  TX bytes:28230 (27.5 KiB)

wlan0     Link encap:Ethernet
          inet addr:192.168.1.69  Bcast:192.168.1.255  Mask:255.255.255.0
          UP BROADCAST RUNNING MULTICAST  MTU:1500  Metric:1
          RX packets:407829 errors:0 dropped:0 overruns:0 frame:0
          TX packets:291059 errors:0 dropped:0 overruns:0 carrier:0
          collisions:0 txqueuelen:1000 
          RX bytes:481001561 (458.7 MiB)  TX bytes:29315358 (27.9 MiB)

En este caso podemos ver que nuestra interfaz inalámbrica es wlan0 y que tiene la IP 192.168.1.69. Esto es importante ya que el contenedor LXC debe tener una IP en el mismo segmento de red. Para evitar conflictos con otras PCs conectadas en nuestra red local, podemos usar la subred 192.168.2.0 para el contenedor. Así, por ejemplo, el primer paso es editar el archivo de configuración del contenedor y asignarle una IP en esta nueva subred:

monstruosoft@PC:~$ sudo nano /var/lib/lxc/privileged/config 
# Network configuration
lxc.network.type = veth
lxc.network.ipv4 = 192.168.2.69
lxc.network.flags = up

Ahora el contenedor tendrá asignada una IP en el mismo segmento de red que nuestra conexión Wi-Fi. A continuación usaremos iptables para llevar a cabo el proceso de compartir el internet con el contenedor:

monstruosoft@PC:~$ sudo iptables -t nat -A POSTROUTING -s 192.168.2.0/24 -j MASQUERADE
monstruosoft@PC:~$ sudo iptables --list -t nat
Chain PREROUTING (policy ACCEPT)
target     prot opt source               destination         

Chain INPUT (policy ACCEPT)
target     prot opt source               destination         

Chain OUTPUT (policy ACCEPT)
target     prot opt source               destination         

Chain POSTROUTING (policy ACCEPT)
target     prot opt source               destination         
MASQUERADE  all  --  192.168.2.0/24       anywhere

Como recordarán, si iniciamos el contenedor ahora se creará en nuestra PC una interfaz de red virtual que nos permite comunicarnos con el contenedor. Antes de continuar debemos asegurarnos de que la interfaz virtual esté configurada correctamente, en este ejemplo mi interfaz virtual es veth02OSQL y la subred para el contenedor es 192.168.2.0/24:

monstruosoft@PC:~$ sudo lxc-ls -f
NAME       STATE   AUTOSTART GROUPS IPV4 IPV6 
privileged STOPPED 0         -      -    -    
unstable   STOPPED 0         -      -    -    
monstruosoft@PC:~$ sudo lxc-start -n privileged
monstruosoft@PC:~$ sudo lxc-ls -f
NAME       STATE   AUTOSTART GROUPS IPV4         IPV6 
privileged RUNNING 0         -      192.168.2.69 -    
unstable   STOPPED 0         -      -            -    
monstruosoft@PC:~$ sudo ifconfig 
lo        Link encap:Local Loopback  
          inet addr:127.0.0.1  Mask:255.0.0.0
          inet6 addr: ::1/128 Scope:Host
          UP LOOPBACK RUNNING  MTU:65536  Metric:1
          RX packets:140 errors:0 dropped:0 overruns:0 frame:0
          TX packets:140 errors:0 dropped:0 overruns:0 carrier:0
          collisions:0 txqueuelen:0 
          RX bytes:28689 (28.0 KiB)  TX bytes:28689 (28.0 KiB)

veth02OSQL Link encap:Ethernet
          UP BROADCAST RUNNING MULTICAST  MTU:1500  Metric:1
          RX packets:11 errors:0 dropped:0 overruns:0 frame:0
          TX packets:25 errors:0 dropped:0 overruns:0 carrier:0
          collisions:0 txqueuelen:1000 
          RX bytes:1674 (1.6 KiB)  TX bytes:4019 (3.9 KiB)

wlan0     Link encap:Ethernet
          inet addr:192.168.1.69  Bcast:192.168.1.255  Mask:255.255.255.0
          UP BROADCAST RUNNING MULTICAST  MTU:1500  Metric:1
          RX packets:522209 errors:0 dropped:0 overruns:0 frame:0
          TX packets:385964 errors:0 dropped:0 overruns:0 carrier:0
          collisions:0 txqueuelen:1000 
          RX bytes:609054128 (580.8 MiB)  TX bytes:39322304 (37.5 MiB)
monstruosoft@PC:~$ sudo ifconfig veth02OSQL down
monstruosoft@PC:~$ sudo ifconfig veth02OSQL 192.168.2.1 netmask 255.255.255.0 broadcast 192.168.2.255
monstruosoft@PC:~$ sudo ifconfig veth02OSQL up

Ahora podemos comprobar que el contenedor forma parte de nuestra red Wi-Fi gracias a la magia de iptables. Para confirmarlo podemos hacer un ping desde nuestra PC al contenedor:

monstruosoft@PC:~$ ping 192.168.2.69
PING 192.168.2.69 (192.168.2.69) 56(84) bytes of data.
64 bytes from 192.168.2.69: icmp_seq=1 ttl=64 time=0.093 ms
64 bytes from 192.168.2.69: icmp_seq=2 ttl=64 time=0.051 ms
64 bytes from 192.168.2.69: icmp_seq=3 ttl=64 time=0.056 ms
^C
--- 192.168.2.69 ping statistics ---
3 packets transmitted, 3 received, 0% packet loss, time 1999ms
rtt min/avg/max/mdev = 0.051/0.066/0.093/0.020 ms

Dentro del contenedor puede ser necesario verificar la configuración de red, después de lo cual podremos comprobar que también es posible hacer ping desde el contenedor a nuestra red local y al internet:

monstruosoft@PC:~$ sudo lxc-attach -n privileged
[sudo] password for monstruosoft: 
root@privileged:/# ifconfig eth0 192.168.2.69 netmask 255.255.255.0 broadcast 192.168.2.255
root@privileged:/# route add default gw 192.168.2.1 eth0
root@privileged:/# ping 192.168.2.1
PING 192.168.2.1 (192.168.2.1) 56(84) bytes of data.
64 bytes from 192.168.2.1: icmp_seq=1 ttl=64 time=0.063 ms
64 bytes from 192.168.2.1: icmp_seq=2 ttl=64 time=0.050 ms
64 bytes from 192.168.2.1: icmp_seq=3 ttl=64 time=0.046 ms
^C
--- 192.168.2.1 ping statistics ---
3 packets transmitted, 3 received, 0% packet loss, time 1998ms
rtt min/avg/max/mdev = 0.046/0.053/0.063/0.007 ms
root@privileged:/# ping 192.168.1.69
PING 192.168.1.69 (192.168.1.69) 56(84) bytes of data.
64 bytes from 192.168.1.69: icmp_seq=1 ttl=64 time=0.058 ms
64 bytes from 192.168.1.69: icmp_seq=2 ttl=64 time=0.041 ms
64 bytes from 192.168.1.69: icmp_seq=3 ttl=64 time=0.046 ms
^C
--- 192.168.1.69 ping statistics ---
3 packets transmitted, 3 received, 0% packet loss, time 1998ms
rtt min/avg/max/mdev = 0.041/0.048/0.058/0.009 ms
root@privileged:/# ping 192.168.1.254
PING 192.168.1.254 (192.168.1.254) 56(84) bytes of data.
64 bytes from 192.168.1.254: icmp_seq=1 ttl=63 time=316 ms
64 bytes from 192.168.1.254: icmp_seq=3 ttl=63 time=933 ms
64 bytes from 192.168.1.254: icmp_seq=4 ttl=63 time=48.2 ms
^C
--- 192.168.1.254 ping statistics ---
4 packets transmitted, 3 received, 25% packet loss, time 3008ms
rtt min/avg/max/mdev = 48.237/432.613/933.266/370.549 ms
root@privileged:/# ping www.google.com
PING www.google.com 56(84) bytes of data.
64 bytes from dsl-dyn.prod-infinitum.com.mx: icmp_seq=1 ttl=60 time=24.8 ms
64 bytes from dsl-dyn.prod-infinitum.com.mx: icmp_seq=2 ttl=60 time=54.0 ms
64 bytes from dsl-dyn.prod-infinitum.com.mx: icmp_seq=3 ttl=60 time=67.3 ms
^C
--- www.google.com ping statistics ---
3 packets transmitted, 3 received, 0% packet loss, time 2002ms
rtt min/avg/max/mdev = 24.869/48.761/67.393/17.755 ms

En el ejemplo anterior he hecho ping desde el contenedor a la interfaz virtual en mi PC, a la IP de mi PC en la red local, a mi router inalámbrico y a la página de Google respectivamente. Todos los pings fueron exitosos. Una vez que has verificado que puedes hacer ping exitosamente a una página de internet, el contenedor está listo para poder usar internet normalmente desde cualquier otro programa.

Como podemos ver, compartir internet con un contenedor LXC es en realidad bastante simple y sólo requiere verificar unas cuantas opciones de configuracion. Espero que este post resulte útil para los que, como yo, experimentan con LXC.

Nota: Esta misma configuración también funciona para compartir 
internet, por ejemplo, con el Raspberry Pi.
Advertisements

Leave a Reply

Fill in your details below or click an icon to log in:

WordPress.com Logo

You are commenting using your WordPress.com account. Log Out / Change )

Twitter picture

You are commenting using your Twitter account. Log Out / Change )

Facebook photo

You are commenting using your Facebook account. Log Out / Change )

Google+ photo

You are commenting using your Google+ account. Log Out / Change )

Connecting to %s