LXC containers on a host with wireless

Since you can’t bridge a wireless NIC, you’ll need to create a new bridge for your containers, set up NAT through it to the wireless NIC, and set up dnsmasq to provide ip addresses to your containers. First make sure we have the tools create and configure the bridge and provide dhcp to the containers:

apt-get install bridge-utils dnsmasq-base

and make sure that forwarding is turned on to support NAT:

echo 1 > /proc/sys/net/ipv4/ip_forward
echo "net.ipv4.ip_forward=1" >> /etc/sysctl.conf

Now create the bridge, as usual, using /etc/network/interfaces:

auto lxcbr0
iface lxcbr0 inet static
  address 192.168.30.1
  netmask 255.255.255.0
  post-up /opt/bin/lxcbr0-up

That entry says that when the bridge comes up, run /opt/bin/lxcbr0-up. Create that file, open it with your favorite editor, and paste in:

#!/bin/sh
# This is the address we assigned to our bridge in /etc/network/interfaces
braddr=192.168.30.1
# ip address range for containers
brrange=192.168.30.2,192.168.30.254
iptables -A FORWARD -i lxcbr0 -s ${braddr}/24 -m conntrack --ctstate NEW -j ACCEPT
iptables -A FORWARD -m conntrack --ctstate ESTABLISHED,RELATED -j ACCEPT
iptables -A POSTROUTING -t nat -j MASQUERADE 
dnsmasq --bind-interfaces --conf-file= --listen-address $braddr --except-interface lo --dhcp-range $brrange --dhcp-lease-max=253 --dhcp-no-override

Make sure it is executable by doing

chmod ugo+x /opt/bin/lxcbr0-up

Bring up the bridge:

ifup lxcbr0

My lxc.conf now reads:

lxc.network.type=veth
lxc.network.link=lxcbr0
lxc.network.flags=up

And you can create containers as always using

lxc-create -t natty -f /etc/lxc.conf -n natty1

There are some different games you can play by turning stp on, but that's not for this post.

This entry was posted in Uncategorized and tagged , . Bookmark the permalink.

19 Responses to LXC containers on a host with wireless

  1. Alex Eagar says:

    Thanks so much for posting these instructions!

    The only adjustment I needed to make to get this to work for me on Ubuntu 11.10 amd64 CLI, was to add the following line before the post-up line in /etc/network/interfaces .

    pre-up brctl addbr lxcbr0

  2. Kim C. Callis says:

    Would this work is I am not using the lxcbr0, but just using br0 since I have that in place to handle KVM guests as well?

  3. Kim C. Callis says:

    I made the following change to /etc/network/interface:

    auto lo
    iface lo inet loopback

    auto eth0
    iface eth0 inet manual

    auto wlan0
    iface wlan0 inet manual

    auto br0
    iface br0 inet dhcp
    bridge_ports wlan0
    bridge_stp off
    bridge_fd 0
    bridge_maxwait 0

    When I reboot with this change, NetworkManager fails to start and even after I force start of Network Manager, my lxc container fails to start. Currently, I have my /etc/network/interfaces setup like this:

    auto lo
    iface lo inet loopback

    auto eth0
    iface eth0 inet manual

    auto br0
    iface br0 inet dhcp
    bridge_ports eth0
    bridge_stp off
    bridge_fd 0
    bridge_maxwait 0

    Of course, that requires that I have a wire plugged into the machines. I have not made any changes to my /etc/lxc/lxc.conf since I was unsure of it should be changes to.

    kcc@gallifrey:~$ cat /etc/lxc/lxc.conf
    lxc.network.type=veth
    lxc.network.link=br0
    lxc.network.flags=up

  4. s3hh says:

    Right, you cannot bridge a wireless nic.

  5. Kim C. Callis says:

    You so are saying that I am destined to always be plugged into a cable?

  6. s3hh says:

    No, you just have to forward the traffic as is done with lxcbr0.

    • Kim C. Callis says:

      Then I must be missing the information on how to do the forwarding… Is that in your blog or was it somewhere else?

      • Kim C. Callis says:

        Ok, I did see it on your site. I have my container getting it’s address from my router. Do I need to still set up DNSMASQ on my host or could I do the iptable changes on the router (which is a DD-WRT based router). Of course, now that I look at the look at your script, I realize that my router would not know anything about the my bridge on my host.

        So I need to actually setup DNSMASQ and do port forwarding on my host, although I can still let my router assign the IP address, if I am reading this right and thinking this through.

  7. s3hh says:

    It depends on what you want. If you’re happy with the router giving your container the address, then yeah you can just have the router forward whatever ports you want. Have fun! 🙂

    • Kim C. Callis says:

      Couldn’t I do the ip forwarding on the host, apply the iptables entries and still allow my router to pass the ip address?

  8. s3hh says:

    Yup there are lots of ways you can set it up. But there will have to be rules on the router to forward traffic to either the host (to then be fwded from there) or straight to the container.

  9. Chris says:

    You need to add the following line to your script otherwise DHCP will fail in a Debian Wheezy guest with “5 bad udp checksums in 5 packets”:

    pre-up iptables -t mangle -A POSTROUTING -p udp –dport bootpc -s 10.0.0.1 -j CHECKSUM –checksum-fill

    More details at https://github.com/fgrehm/vagrant-lxc/issues/153 and https://bugs.launchpad.net/ubuntu/+source/isc-dhcp/+bug/930962

    • s3hh says:

      Thanks – really I consider it a bug both in the kernel and dhclient (and showed up long after this blog post) but thanks for commenting, I bet it’ll save others some frutration 🙂

  10. Thanks for this post. Know it’s old, but still relevant. NAT has just been added to systemd-networkd, but it won’t trickle down for awhile. Thought I would post an upgraded script that works. Includes DHCP checksumming fix, and works with archlinux, and doesn’t create redundant rules.

    “`
    # Interfaces
    WAN={{ wan_interface | eth0 }}
    LAN={{ bridge_interface | br0 }}

    # Addresses
    LAN_IP={{ bridge_ip | 10.0.10.1 }}
    LAN_SUBNET={{ bridge_subnet | 10.0.10.0/24 }}
    DHCP_RANGE={{ bridge_dhcp_range | 10.0.10.2,10.0.10.254 }}

    # FIREWALL RULES
    iptables -A POSTROUTING -t nat -o $WAN -j MASQUERADE
    iptables -A FORWARD -m conntrack –ctstate RELATED,ESTABLISHED -j ACCEPT
    iptables -A FORWARD -s ${LAN_SUBNET} -o $WAN -j ACCEPT

    # fix DHCP checksumming
    iptables -A POSTROUTING -t mangle -p udp –dport bootpc -s ${LAN_SUBNET} -j CHECKSUM –checksum-fill

    # masq DHCP server
    dnsmasq –bind-interfaces –conf-file= –listen-address ${LAN_IP} –except-interface lo –dhcp-range ${DHCP_RANGE} –dhcp-lease-max=253 –dhcp-no-override

    “`

  11. not says:

    Why use NAT over simple IP forwarding?

  12. Kim Callis says:

    How does all of this work under systemd-networkd?

  13. 張根源 says:

    Hi , i tried this , but when it come to the command”ifup lxcbr0″, it show the massage ” cannot find device “lxcbr0″
    Failed to bring up lxcbr0”
    what did i missing? i set up lxcbr0 in /etc/network/interfaces the same way, also created lxcbr0-up in
    /opt/bin/, it sill says “cannot find device”…. any advice? thanks!

  14. 張根源 says:

    i think i just solved it, i just added ” bridge_ports none ” in /etc/network/interfaces, like this:
    auto lxcbr0
    iface lxcbr0 inet static
    address xx.xx.xx.xx
    netmask 255.255.255.0
    post-up /opt/bin/lxcbr0-up
    bridge_ports none # <— i put it here

    and boom, i see everything works perfect, now i see a ip address shows up in my container, and i can ping 8.8.8.8 ( google's server for example ) and no package loss, nice! my container really connected to the internet, thank you for sharing this , i just try to solve the container's internet problems for several days, im so happy after solving this problem! Anyway, thanks again!

Leave a comment