Cape Town to London

A blog about tech, ethics & startups

Inspect Docker traffic with tcpdump

I was recently involved in a project deploying a Django application to AWS EC2 Container Service. I had spent a few days building the app into a container alongside a RabbitMQ and Postgres containers. I made use of docker compose to run & tested locally.

There came point where I needed to quickly check the amount of TCP traffic being sent to a specific third-party API.

Basic Compose Network

When you startup your containers with docker compose, a network is automatically created for your containers.

Check all the containers are still running

$ docker-compose ps
         Name      State                    Ports
-------------------------------------------------------------------
django_app_1       Up      0.0.0.0:5000->5000/tcp
django_db_1        Up      5432/tcp
django_rabbit_1    Up      25672/tcp, 4369/tcp, 5671/tcp, 5672/tcp

View the network created for the containers

$ docker network ls
NETWORK ID     NAME                  DRIVER          SCOPE
2106f72737b4   django_default        bridge          local
1c8fc1a172a5   host                  host            local
c0504b7be27b   none                  null            local
bb5f6238e0e9   bridge                bridge          local

The network allows your containers to communicate between each other without affecting the host's network.

You can't just use tcpdump from the host because the docker network is isolated from the host network by default.

Attaching to a Compose network

Instead I can attach to the compose network using the --net parameter in my docker run command. From this new container I can access the network interface for the containers running with docker-compose.
# Run a Debian container attached to the docker-compose network
$ docker run -it --rm --net=container:django_app_1 debian
root@f5d9ed725329:/# apt update && apt install -y tcpdump

TCPDump for Outbound Traffic

Now I can monitor traffic on the network using regular tcpdump commands.
root@f5d9ed:/# # Running tcpdump on the eth0 interface
root@f5d9ed:/# tcpdump -v \
           -i eth0 \
           -n 'dst host 1.2.3.4 and (dst port 80 or dst port 443)'
tcpdump: listening on eth0, link-type EN10MB (Ethernet)...
With this setup I was able to easily inspect the amount of network activity for the container and debug the issue.

What about HTTP Traffic

Although this is okay for TCP and/or UDP traffic there may be a use case where you need to inspect HTTP requests. If this is the case the I would recommend looking into using a proxy tool such as Hovefly.