Docker for Network Analysis: A Hands-On Tutorial
By Neosb
Published: 2026-02-07 09:00
Last Modified: 2026-02-07 09:00
Tags: dockernetwork analysistutorialmitmproxyrustsecuritydevopsprogramming
Categories: developmentnetworksecuritytutorialdocker
Docker for Network Analysis: A Hands-On Tutorial
Welcome to the world of containerized network analysis! In this tutorial, we'll explore how to use Docker to create isolated, reproducible environments for tinkering with networking tools. Forget cluttering your host machine with dependencies; we're going to build a self-contained lab for capturing, analyzing, and intercepting network traffic.
We will cover:
- Setting up a custom Docker image with
tcpdump,tshark, andmitmproxy. - Building a simple web server with the Rust programming language and running it in a container.
- Creating a dedicated Docker network for our containers to communicate.
- Capturing live traffic between containers with
tcpdump. - Analyzing captured traffic with
tshark, the command-line sibling of Wireshark. - Intercepting and inspecting HTTP requests with the powerful
mitmproxy.
Prerequisites
Before we dive in, make sure you have Docker installed on your system. It's the only dependency you'll need on your host machine.
- Docker: You can download it from the official website: Get Docker.
Basic familiarity with the command line will be helpful, but I'll guide you through every step.
Step 1: The Analyst's Dockerfile
Our first mission is to create a Docker image that will serve as our "analyst" machine. This container will hold all our networking tools.
Create a file named Dockerfile in a new directory for our project.
Language: dockerfile
# Use a recent Fedora base image
FROM fedora:latest
# Install essential networking tools
RUN dnf update -y &&
dnf install -y
tcpdump
wireshark-cli
mitmproxy
curl
tmux
vim-enhanced
&& dnf clean all
# Set a working directory
WORKDIR /app
# Drop into a shell by default
CMD ["/bin/bash"]
What's happening here?
FROM fedora:latest: We're starting with a fresh, up-to-date Fedora Linux distribution.RUN dnf install -y ...: This command installs our toolkit:tcpdump: The classic command-line packet sniffer.wireshark-cli: This package includestshark, the tool we'll use for deep packet inspection.mitmproxy: Our interactive HTTPS proxy.curl: An essential tool for making web requests.tmux: A terminal multiplexer that will let us run multiple commands in one window.vim-enhanced: A powerful text editor, in case we need to edit files inside the container.
WORKDIR /app: This sets a default directory for us to work in when we enter the container.CMD ["/bin/bash"]: This tells Docker to start abashshell when the container runs, so we can interact with it.
Now, let's build the image. Open your terminal in the directory where you saved the Dockerfile and run:
Language: bash
docker build -t analyst-toolbox .
This command builds an image from our Dockerfile and tags it with the name analyst-toolbox.
Step 2: Our Target - A Simple Rust Web App
What's a network analysis session without something to analyze? Let's create a simple "Hello, Docker!" web server in Rust. You don't need Rust installed on your host machine; we'll build it inside a Docker container.
Create a new directory for our Rust app, let's call it rust-webapp. Inside this directory, create the following three files.
rust-webapp/Cargo.toml
This file defines our project and its dependencies.
Language: toml
[package]
name = "rust-webapp"
version = "0.1.0"
edition = "2021"
[dependencies]
actix-web = "4"
rust-webapp/src/main.rs
This is our application's source code. It creates a web server that listens on port 8080 and responds to requests.
Language: rust
use actix_web::{get, App, HttpResponse, HttpServer, Responder};
#[get("/")]
async fn hello() -> impl Responder {
HttpResponse::Ok().body("Hello, Docker!")
}
#[get("/secret")]
async fn secret() -> impl Responder {
HttpResponse::Ok().body("You found the secret endpoint!")
}
#[actix_web::main]
async fn main() -> std::io::Result<()> {
println!("🚀 Server starting on http://0.0.0.0:8080");
HttpServer::new(|| {
App::new()
.service(hello)
.service(secret)
})
.bind(("0.0.0.0", 8080))?
.run()
.await
}
rust-webapp/Dockerfile
This Dockerfile will compile and run our Rust application. It uses a multi-stage build, which is a best practice for creating small, secure production images.
Language: dockerfile
# Stage 1: Build the application
FROM rust:1 as builder
WORKDIR /usr/src/app
COPY . .
RUN cargo build --release
# Stage 2: Create the final, small image
FROM fedora:latest
WORKDIR /app
# Copy the compiled binary from the builder stage
COPY --from=builder /usr/src/app/target/release/rust-webapp .
# Expose the port the app runs on
EXPOSE 8080
# Run the application
CMD ["./rust-webapp"]
Now, from within the rust-webapp directory, build the app's image:
Language: bash
docker build -t rust-webapp .
Step 3: Setting Up the Network
To allow our containers to talk to each other easily by name, we'll create a dedicated virtual network.
Language: bash
docker network create a-net
Simple as that! The network is named a-net.
Scenario 1: Capturing Packets with tcpdump
Time for some action! Let's start our containers and watch the traffic.
-
Start the web server: Run our Rust web app container and connect it to our network. We'll name it
webserverso we can refer to it by that name.Language: bash
docker run -d --rm --network a-net --name webserver rust-webapp-d: Detached mode (runs in the background).--rm: Automatically removes the container when it stops.
-
Start the analyst toolbox: Now, start an interactive session in our analyst container, also connected to the same network.
Language: bash
docker run --rm -it --network a-net --name analyst analyst-toolbox -
Capture the traffic: Inside the
analystcontainer's shell, starttcpdump. We'll tell it to listen on theeth0interface (the default for Docker containers) and write the packets to a file namedcapture.pcap.Language: bash
# Inside the 'analyst' container tcpdump -i eth0 -w capture.pcaptcpdumpis now listening. It won't show any output until it captures packets. -
Generate some traffic: We need another terminal. Don't close the current one! You can open a new terminal window on your host machine. From there, execute a
curlcommand inside our runninganalystcontainer.Language: bash
# From a new terminal on your host machine docker exec analyst curl http://webserver:8080/ docker exec analyst curl http://webserver:8080/secretdocker execruns a command inside an already running container. We're tellingcurlinside theanalystcontainer to make a request to ourwebservercontainer on port 8080. -
Stop the capture: Go back to the terminal where
tcpdumpis running and pressCtrl+Cto stop it. You'll see a summary of how many packets were captured. You now have acapture.pcapfile in the/appdirectory of youranalystcontainer.
Scenario 2: Analyzing with tshark
With our capture.pcap file ready, let's dissect it with tshark.
Still inside the analyst container, run the following commands:
-
Read the capture file: This gives a summary of each packet, similar to
tcpdump.Language: bash
# Inside the 'analyst' container tshark -r capture.pcap -
Filter for HTTP traffic: This is where
tsharkshines. We can use display filters (the same ones as in Wireshark) to see only the traffic we care about.Language: bash
# Inside the 'analyst' container tshark -r capture.pcap -Y "http"You'll see the
GET /andGET /secretrequests and theHTTP/1.1 200 OKresponses. -
Inspect a specific packet: Let's look at the full details of the first HTTP GET request.
Language: bash
# Inside the 'analyst' container tshark -r capture.pcap -Y "http.request.method == GET" -V -c 1-V: Verbose output, showing all packet details.-c 1: Only process the first matching packet.
You can now see the full TCP/IP and HTTP headers, revealing the inner workings of the request.
Scenario 3: Intercepting with mitmproxy
Packet sniffing is passive. What if we want to actively intercept and even modify traffic? That's a job for mitmproxy.
-
Stop and remove old containers: First, let's clean up our previous session. Open a terminal on your host machine and run:
Language: bash
docker stop webserver analyst(The
--rmflag we used earlier ensures they are removed after stopping). -
Start
mitmproxy: We'll runmitmproxyin its own container. It's good practice to mount a local volume to~/.mitmproxyinside the container to persist the generated certificates.Language: bash
# From your host machine docker run -d --rm --network a-net --name proxy -p 8081:8080 mitmproxy/mitmproxy mitmproxyNote: We are using the official
mitmproxy/mitmproxyimage here. We map port8081on the host to8080in the container, which is mitmproxy's default port. -
Start the web server again: Same command as before.
Language: bash
# From your host machine docker run -d --rm --network a-net --name webserver rust-webapp -
Send traffic through the proxy: Now, let's run a one-off
curlcommand in a temporary container, but this time we'll tell it to use ourmitmproxycontainer as a proxy.Language: bash
# From your host machine docker run --rm -it --network a-net analyst-toolbox curl --proxy http://proxy:8080 http://webserver:8080/This command tells
curlto route its request throughhttp://proxy:8080. -
View the intercepted traffic: Attach to the running
proxycontainer to see themitmproxyinterface.Language: bash
# From your host machine docker attach proxy
You are now inside the interactive mitmproxy console! You'll see the GET http://webserver:8080/ request in the flow list. You can select it, view its details, and even replay or modify it. Press q to exit and go back.
HTTPS Traffic: Intercepting HTTPS is more complex as it requires the client to trust
mitmproxy's certificate. Forcurl, you would use the--insecureflag or point it to mitmproxy's CA certificate. For browsers, you need to install the certificate, which you can typically fetch fromhttp://mitm.itwhen your browser is configured to use the proxy.
Conclusion
You've successfully built a portable lab for network analysis! We've only scratched the surface, but you now have a solid foundation. You can package any tool into a Docker container and create complex network topologies to test, analyze, and secure applications.
From here, you could:
- Write
mitmproxyscripts in Python to automate modifications. - Explore more advanced
tsharkfilters. - Containerize other tools like
nmapfor vulnerability scanning within your private Docker networks.
Happy hacking!