Corrupted IO Stalk this page with RSS github twitter linkedin CC-BY

Inspecting ContainerNet

For various reasons there may be a time that you have to answer the question “What the heck are my containers saying on the network?” The answer I found to how to answer that question was a less than satisfying “well install tcpdump everywhere, dump the contents to a docker volume inspect later”. That felt less than satisfying and produced a lot of work that just didnt feel needed. I know on a traditional network you can dump a machine into promiscuous mode and let the packets roll in so I wondered “Why cant I do that in docker!” turns out the answer was you can, if you know how. So lets walk down that path.

Basic Setup

The reqs are honestly simple and if you are asking the question you likely already have them all.

Setting up the snitch

This part is actually a critical piece to this. You need something that can sit on the same “network” as the containers and capture packets. so the basic example that I can dump here will do that with ubuntu as the base container. Im using docker here for simplicity of things people understand but you could do this with just about any container framework that runs linux containers.

FROM ubuntu 
RUN apt-get update && apt-get install -y tcpdump net-tools
CMD ifconfig eth0 promisc && tcpdump -i eth0 $FILTERS

The rundown of what you have here is grab the ubuntu container, install net-tools and tcpdump to it, set eth0 to promiscuous and then start grabbing packets. That little environment variable on the end, dont worry about ‘em just yet.

Once you have the dockerfile somewhere you can build it like you would any other docker image docker build -t tcpdump:latest - < Dockerfile

Embedding the snitch and running it

From here its like any other container run it, pick the net you want to watch and let the packets fly.

The example I have here connects to the host network and just dumps it to the screen. I’d like to note here it is required that you have at least --privileged putting the network adapter into promisc requires the container to have permissions not normally granted to it so this container has to run in an elevated mode.

docker run -it --rm --privileged --net=host tcpdump

Now its running, and if you are running it like me in something like rancher desktop or you have a chatty program on that network youre going to see a flood. Now even with something like wireshark this flood could be just simply too much, or youre only interested in specific things and gee wouldnt it be nice to use tcpdump filters in there without having to make a new container each time?! Well this is where that environment variable I mentioned earlier comes in. So if we pass it into the container on start up it will apply filters to the TCP dump stream so as an example docker run -it --rm --privileged --net=host --env C_TCPDUMP_FILTER="\!host host.lima.internal" tcpdump will run the container then exclude host.lima.internal from the stream, why, because where I am testing this is a mac that uses rancher desktop, and I dont care about the traffic of the passed through docker sockets.

Now you may be thinking also what if I need to write this to disk. Well that can be handled a few ways. One you could capture the output of the container using pipes docker run -it --rm --privileged --net=host --env C_TCPDUMP_FILTER="\!host host.lima.internal" tcpdump > capture.pcap you could modify the CMD line of the docker file to be something like CMD ifconfig eth0 promisc && tcpdump -i eth0 -w /data/capture.pcap $FILTERS then docker run -it --rm --privileged --net=host -v ~/caps:/data --env C_TCPDUMP_FILTER="\!host host.lima.internal" tcpdump and youll start getting the capture written ~/caps

Its ultimately as flexible as you can think of so long as you are comfortable dealing with tcpdump directly.