-
Notifications
You must be signed in to change notification settings - Fork 38
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 for accessing the internet:
$ 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