How to TCPdump effectively in Docker

How to TCPdump effectively in Docker !

15 June 2022
Security
Networking
cni
tcpdump
kubernetes
docker

A TCPdump primer for containers

Containers can use the network stack in a few different ways. It all depends on how they connect to the network. A couple of options are:

  • docker bridge
  • host (ex. docker run --rm -it --net=host ...)
  • container networks (ex. docker run --rm -it --net=container:id ...)
  • overlay

Building a container and run good old stuff like tcpdump or ngrep would not yield much interesting information, because you link directly to the bridge network or overlay in a default scenario.

The good news is, that you can link your tcpdump container to the host network stack or even better, to the container network stack directly.

In the --net=host scenario, you can capture all traffic between the host and the physical network.

In the --net=container:id usecase, all traffic in/out a specific container can be captured.

So let’s get started !

Install Docker

apt update; apt install -y docker.io
docker version

Creating a tcpdump container image

First create a tcpdump container image.

docker build -t tcpdump - <<EOF 
FROM ubuntu 
RUN apt-get update && apt-get install -y tcpdump 
CMD tcpdump -i eth0 -n
EOF

Create a demo environment

Now let's create a network and a nginx webserver container… and run some traffic !

docker network create demo-net
docker run -d --network demo-net --name wwwnginx nginx

You can note the ip address of wwwnginx for later reference.
The ipaddress is in the range of the docker network: ex. 172.18.0.2

docker inspect -f '{{range.NetworkSettings.Networks}}{{.IPAddress}}{{end}}' wwwnginx

In this example we are using siege (https://github.com/JoeDog/siege) to generate some traffic. siege is an open source regression test and benchmark utility. It can stress test a single URL with a user defined number of simulated users (amongst many other interesting features).

docker run -it --network demo-net dockersec/siege \
      -c 1 http://wwwnginx/

Let's run the capture

Add a tcpdump container and connect to the nginx networking stack.
Now open a new Terminal2 and link the tcpdump container.

docker run -it --net=container:wwwnginx tcpdump

or if you want to pass some more specific tcpdump parameters.

docker run -it --net=container:wwwnginx tcpdump tcpdump port 80 -A -n

If everything works out, you can now see the traffic flows inside the nginx container !!

When we look closer into the traffic capture, we can see:
- traffic is send between the ip address of the siege (172.18.0.3) and 
  nginx (172.18.0.2)  container
- -n will print the ip addresses instead of the fully quafilied domain name

- -A will print the tcp payload in readable format

- port 80 will filter tcp packets send to and from this port

Of course, all the tcpdump parameters, filtering capablities and flags can be used in order to further inspect the traffic flow.

Conclusion

How easy was that?  Have fun sniffing.
Watch out for the next lab, explaining how we can extend this technique to Kubernetes.

How likely are you going to recommend this lab to your friends or colleagues?

Unlikely
Likely

Leave a comment:

About the Author

Philippe Bogaerts

Philippe Bogaerts

Co-founder of https://brucon.org

Senior Solutions Architect Security, DevSecOps and Kubernetes. Co-founder of https://brucon.org.