Skip to content

Container access to wireless network interface

Fran González edited this page Jun 18, 2015 · 8 revisions

Container access to wireless network interface

In my case, I wanted to use the wireless interface of a wireless USB device inside a docker container. At first, I tried the following methods for assigning the USB device to the container:

  • Mount the USB path (e.g. /dev/bus/usb/003/004) inside the container. Example -v /dev/bus/usb/003/004:/dev/bus/usb/003/004:rw
  • By using the --device flag. Example --device=/dev/bus/usb/003/004

Unfortunately, none of them worked. The reason is that if we run the container without --net=host then this container is in a separate namespace, the wlanX interface is in the host namespace and cannot be seen from inside the container.

There are two ways of giving a network interface to a container.

The first method is running the container with the flag --net=host. By doing this, we tell the container to use the host's net namespace. Note the security risks of this approach.

The second method is a bit trickier. The advantage is that we don't need to expose the whole network stack but rather the particular interface that we want to control from inside the container.

$ sudo docker run -i -t --rm --net=none --name=wifi-container ubuntu /bin/bash

At another shell:

$ sudo docker inspect -f '{{.State.Pid}}' wifi-container
2778
$ pid=2778
$ sudo mkdir -p /var/run/netns
$ sudo ln -s /proc/$pid/ns/net /var/run/netns/$pid

Add the interface to the container namespace:

(Important! you must specify the phy interface, not wlanX)

sudo iw phy phy1 set netns $pid

The way to run commands inside the container is through netns exec:

sudo ip netns exec $pid ip link set eth0 up

or...if you want, you could run the container with the --privileged flag and you can work from there.

You should now be able to control the wireless interface from inside the container.

Now, as described at https://docs.docker.com/articles/networking/, you could also create a eth0 interface with internet access:

$ ip addr show docker0
21: docker0: ...
inet 172.17.42.1/16 scope global docker0
...

# Create a pair of "peer" interfaces veth0 and veth1,
# bind the veth0 end to the bridge, and bring it up

$ sudo ip link add veth0 type veth peer name veth1
$ sudo brctl addif docker0 veth0
$ sudo ip link set veth0 up

# Place veth1 inside the container's network namespace,
# rename to eth0, and activate it with a free IP

$ sudo ip link set veth1 netns $pid
$ sudo ip netns exec $pid ip link set dev veth1 name eth0
$ sudo ip netns exec $pid ip link set eth0 address 12:34:56:78:9a:bc
$ sudo ip netns exec $pid ip link set eth0 up
$ sudo ip netns exec $pid ip addr add 172.17.42.99/16 dev eth0
$ sudo ip netns exec $pid ip route add default via 172.17.42.1
Clone this wiki locally