Tcpdump and Docker

Often there is a need to run tcpdump when debugging connectivity issues. It might be challenging to install tcpdump on the host or its useful to tap into a container and run tcpdump there.

Tcpdump docker container can be built using the following file:

tcpdump $ cat Dockerfile
FROM ubuntu
RUN apt-get update && apt-get install -y tcpdump net-tools
CMD /usr/bin/tail -f

“CMD /usr/bin/tail -f” is used just as a command to run on the container startup. Any other similar command can be used.

Build a container:

$ docker build . -t tcpdump --tag tcpdump
Sending build context to Docker daemon  2.048kB
Step 1/3 : FROM ubuntu
 ---> 58db3edaf2be
Step 2/3 : RUN apt-get update && apt-get install -y tcpdump net-tools
 ---> Using cache
 ---> f2114ffe1a4a
Step 3/3 : CMD /usr/bin/tail -f
 ---> Using cache
 ---> 973f5bd0a573
Successfully built 973f5bd0a573
Successfully tagged tcpdump:latest

Run tcpdump container, exec into it and run tcpdump:

tcpdump $ docker run -d --network host  tcpdump
0a76ea051cb184d18e32136a583555014c9891361f96f2c0d3014824c0267937
rromanyak@sh-edge-instance-group-1-35w7 ~/docker-composer/tcpdump $ docker ps
CONTAINER ID   IMAGE            COMMAND                  CREATED         STATUS        PORTS     NAMES
0a76ea051cb1   tcpdump          "/bin/sh -c '/usr/bi…"   3 seconds ago   Up 1 second             priceless_dirac
~ $ docker exec -it priceless_dirac /bin/bash
root@sh-edge-instance-group-1-35w7:/#
#  tcpdump -ni any host 192.168.1.100
tcpdump: data link type LINUX_SLL2
tcpdump: verbose output suppressed, use -v[v]... for full protocol decode
listening on any, link-type LINUX_SLL2 (Linux cooked v2), snapshot length 262144 bytes
16:29:41.546456 eth0  In  IP 192.168.1.100.17685 > 34.75.75.75.8080: Flags [S], seq 3065893830, win 65535, options [mss 1460,nop,wscale 6,nop,nop,TS val 3518285460 ecr 0,sackOK,eol], length 0
16:29:41.546508 eth0  Out IP 34.75.75.75.8080 > 192.168.1.100.17685: Flags [S.], seq 200885289, ack 3065893831, win 64768, options [mss 1420,sackOK,TS val 1251209852 ecr 3518285460,nop,wscale 7], length 0
16:29:41.546637 eth0  In  IP 192.168.1.100.7845 > 34.75.75.75.8080: Flags [S], seq 418846665, win 65535, options [mss 1460,nop,wscale 6,nop,nop,TS val 151752502 ecr 0,sackOK,eol], length 0
16:29:41.546651 eth0  Out IP 34.75.75.75.8080 > 192.168.1.100.7845: Flags [S.], seq 3540253616, ack 418846666, win 64768, options [mss 1420,sackOK,TS val 1251209852 ecr 151752502,nop,wscale 7], length

Using Docker’s ability to run a container that attaches to the network of another with the --network=container:<container_name> option we can tap into the network of another container:

$ docker ps
CONTAINER ID   IMAGE            COMMAND   CREATED      STATUS      PORTS     NAMES
4e8a23069308   flowerpot/goif   "/main"   5 days ago   Up 5 days             klt-instance-template-sedge-backend-5-qysi
 $ docker run -d --tty --net=container:klt-instance-template-sedge-backend-5-qysi tcpdump
b7ef3cafa6d82fd5682d7be65c59f1e24868c9ef618d40bbb1404c0fac168739
 ~ $ docker ps
CONTAINER ID   IMAGE            COMMAND                  CREATED         STATUS         PORTS     NAMES
b7ef3cafa6d8   tcpdump          "/bin/sh -c '/usr/bi…"   6 seconds ago   Up 5 seconds             ecstatic_archimedes
4e8a23069308   flowerpot/goif   "/main"                  5 days ago      Up 5 days                klt-instance-template-sedge-backend-5-qysi
$ docker exec -it b7ef3cafa6d8 /bin/bash
# tcpdump -ni any host 1.1.1.1