After having successfully installed an unprivildged linux container, I wanted to use my WLAN interface for the network but I could not create a bridge due to security restricition of the protocol. So I had to configure NAT over my wireless to make it working. I want to show here the steps to achieve this.
My first idea was to bridge the WLAN interface to my lxc bridge but this doesn't work:
sudo brctl addif lxcbr0 wlp2s0 can't add wlp2s0 to bridge lxcbr0: Operation not supported
At first glance it might look weird but here is some more detailed explanation:
It's no longer possible to add an interface in the managed mode to a bridge. You should run hostapd first to pure the interface to the master mode. Bridging doesn't work on the station side anyway because the 802.11 header has three addresses (except when WDS is used) omitting the address that would be needed for a station to send or receive a packet on behalf of another system. -- Regards, Pavel Roskin
I didn't want to use hostap to solve this problem, I choosed the NAT alternative.
Preparing the host system
First you need prepare your host system to activate NAT. We will need to configure a bit the firewal, install iptables if you don't have it already:
sudo xbps-install iptables
Then I activate the NAT at the kernel level where wlp2s0 is the name of my wireless interface:
echo 1 | sudo tee /proc/sys/net/ipv4/ip_forward sudo iptables -t nat -A POSTROUTING -o wlp2s0 -j MASQUERADE
Now you have to set an IP to your bridge so it can communicate, I will use the range 10.0.0/24 and assign the first IP available:
sudo brctl addbr lxcbr0 sudo ifconfig lxcbr0 10.0.0.1/24 up
Now your host system is ready for NATing!
Configuring the container
Now we still will have to configure the newtork within the container. Some would prefer installing a DHCP server on the host but I like setting a static IP to each container, so I know how to reach them.
First you will need to know the IP of your DNS server, that is your router most of the time but to be sure, check the /etc/resolv.conf file of your host, that is 192.168.0.1 for me:
cat /etc/resolv.conf # Generated by dhcpcd from wlp2s0.dhcp # /etc/resolv.conf.head can replace this line domain local nameserver 192.168.0.1 # /etc/resolv.conf.tail can replace this line
Now the network configuration is dependent on the distribution you have in your container but the Debian way that also work with Ubuntu is to edit the /etc/network/interfaces file:
lxc-attach -n ubuntu-xenial root@ubuntu-xenial:/# vim /etc/network/interfaces
Now assign a new IP in the range defined previously, I choosed 10.0.0.100 for this container where the gateway is the IP of your bridge and the name server the one found in /etc/resolv.conf of your host system:
auto eth0 iface eth0 inet static address 10.0.0.100 netmask 255.255.255.0 gateway 10.0.0.1 dns-nameservers 192.168.0.1
Now apply the configuration and test with ping:
root@ubuntu-xenial:/# /sbin/ifdown eth0 root@ubuntu-xenial:/# /sbin/ifup eth0 root@ubuntu-xenial:/# ping www.google.com PING www.google.com (126.96.36.199) 56(84) bytes of data. 64 bytes from ham02s15-in-f196.1e100.net (188.8.131.52): icmp_seq=1 ttl=51 time=38.6 ms ^C --- www.google.com ping statistics --- 1 packets transmitted, 1 received, 0% packet loss, time 0ms rtt min/avg/max/mdev = 38.678/38.678/38.678/0.000 ms
Now you can open an ssh connection to your container from your host:
ssh email@example.com firstname.lastname@example.org's password: Welcome to Ubuntu 16.04.2 LTS (GNU/Linux 4.9.11_1 x86_64) * Documentation: https://help.ubuntu.com * Management: https://landscape.canonical.com * Support: https://ubuntu.com/advantage Last login: Wed Feb 22 11:24:13 2017 from 10.0.0.1 $
That was easy!
Start lxc script
Now as my network configuraton has changed a bit, here is how my script to start the container looks like:
#!/bin/sh echo 1 | sudo tee /proc/sys/net/ipv4/ip_forward sudo iptables -t nat -A POSTROUTING -o wlp2s0 -j MASQUERADE sudo brctl addbr lxcbr0 sudo ifconfig lxcbr0 10.0.0.1/24 up sudo cgm create all $USER sudo cgm chown all $USER $(id -u) $(id -g) cgm movepid all $USER $$ lxc-start -n ubuntu-xenial
Some pointers that helped me solving this issue: