J

Piggybacking on container networking for debugging

24 Nov 2022

I regularly need a way of running a container (mitmproxy or tcpdump) against another running container.

Sure, you could stop the container, update the Dockerfile and build in your dependencies but this approach is very cumbersome and slow on most projects. Instead, how about just running a new container and attaching it to the existing Docker network?

To get started, build the container you want to run. Here is a way to build a tcpdump container.

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

Easy right? We have an image we can now use in Docker.

$ docker images --format "table {{.ID}}\t{{.Repository}}" | grep tcpdump
579f886818cc   tcpdump

For examples sake, let’s say we want to inspect some traffic on my Resque container. The container name is resque and we can piggyback onto it using the --net=container:<name> flag on docker run ... <image> command.

$ docker run --tty --net=container:resque tcpdump

And boom, we’re using the image’s default entry point of -i eth0. How easy was that?!?!

tcpdump: verbose output suppressed, use -v or -vv for full protocol decode
listening on eth0, link-type EN10MB (Ethernet), capture size 262144 bytes
03:15:28.835766 IP 130330b90814.44222 > redis.dev-stack.6379: Flags [P.], seq 1560375946:1560375984, ack 3154187234, win 502, options [nop,nop,TS val 1153233662 ecr 4097934334], length 38: RESP "SMEMBERS" "resque:queues"
03:15:28.837174 IP redis.dev-stack.6379 > 130330b90814.44222: Flags [P.], seq 1:18, ack 38, win 509, options [nop,nop,TS val 4097939341 ecr 1153233662], length 17: RESP "default"

What about customising it, so we’re only seeing port 6379 traffic with ASCII output?

$ docker run --tty --net=container:resque tcpdump tcpdump -A 'port 6379'
 
tcpdump: verbose output suppressed, use -v or -vv for full protocol decode
listening on eth0, link-type EN10MB (Ethernet), capture size 262144 bytes
03:18:14.597643 IP 130330b90814.44222 > redis.dev-stack.6379: Flags [P.], seq 1560378553:1560378591, ack 3154187960, win 502, options [nop,nop,TS val 1153399433 ecr 4098100104], length 38: RESP "SMEMBERS" "resque:queues"
E..Z..@.@...... ........].|.........X}.....
D.z..D..*2
$8
SMEMBERS
$13
resque:queues

Astute readers will see the duplication tcpdump in there but it is intentional. The first is the image to use, and the second is the entry point override, here -A (for ASCII output) and then the filter of port 6379.