Understanding AWS Network Flow: Following a Request from User to EC2
When troubleshooting applications hosted on AWS, we often ask questions such as:
Is DNS working correctly?
Is traffic reaching AWS?
Is the Load Balancer receiving requests?
Is the EC2 instance receiving packets?
Is the application responding successfully?
Instead of looking at these components in isolation, let's follow a real HTTP request from a user's machine all the way to a Dockerized application running on an EC2 instance.
In this article, we will use three simple but powerful networking tools:
nslookup
traceroute
tcpdump
By the end of this article, you'll understand how packets move through AWS and how to troubleshoot network issues using real-world packet captures.
Architecture
The sample application used in this article is available here:
Step 1: DNS Resolution
Before any network connection can be established, the client must determine where the application is hosted.
nslookup seqas.online
In this example, DNS resolves seqas.online to two IP addresses belonging to an AWS Application Load Balancer.
Once the browser receives these IP addresses, it can begin establishing a network connection to the application.
At this stage, we have verified that:
The domain name exists.
DNS resolution is functioning correctly.
The client can obtain the destination IP address of the application.
However, nslookup only confirms name resolution. It does not verify whether the application is reachable or whether traffic can successfully travel through the network. To understand the path packets take to reach AWS, we can use traceroute.
Step 2: Tracing the Route
Next, we inspect the path packets take through the Internet.
traceroute seqas.online
Each hop in the traceroute output represents a network device forwarding packets towards the destination. The traffic typically traverses your local network, your ISP's infrastructure, Internet backbone providers, and finally AWS's network before reaching the application.
Entries displayed as * * * are usually routers configured not to respond to traceroute requests. This is common and does not necessarily indicate a connectivity issue.
At this stage, we have verified:
✅ The domain resolves to a valid IP address (DNS is working)
✅ Packets can reach the AWS network
What we have not yet verified is whether the request reaches the EC2 instance or the application itself. To confirm that, we'll capture packets directly on the server using tcpdump.
Step 3: Capturing Traffic on EC2
So far, we have verified that:
DNS resolution is working.
Traffic can reach the AWS network.
However, we still haven't confirmed whether the request actually reaches our EC2 instance and application.
To validate this, we can capture network traffic directly on the EC2 instance using tcpdump.
sudo tcpdump -i any -nn port 80
Command Breakdown
| Option | Description |
|---|---|
| -i any | Capture traffic on all network interfaces |
| -nn | Disable hostname and port resolution |
| port 80 | Capture HTTP traffic |
The packet capture allows us to observe the entire journey of a request after it enters AWS.
Understanding the Flow
The following diagram summarizes the network flow observed in the packet capture.
When a user accesses the application, the request first reaches the Application Load Balancer, which forwards the traffic to the EC2 instance hosting our application.
The EC2 instance receives the request on its primary network interface (ens5). Since the application is running inside a Docker container, the request is then routed through Docker's internal networking (docker0) and delivered to the container.
Before any application data is exchanged, the client and server establish a TCP connection using the TCP three-way handshake:
The client sends a SYN packet to initiate the connection.
The server responds with SYN-ACK.
The client replies with ACK.
Once the connection is established, the browser sends an HTTP GET request for the application.
The request then follows this path:
Client
│
▼
Application Load Balancer
│
▼
EC2 Instance (ens5)
│
▼
Docker Network (docker0)
│
▼
Container
│
▼
Application
The application processes the request and returns an HTTP 200 OK response, indicating that the request was handled successfully.
The response then travels back through the same path in reverse:
Application
│
▼
Container
│
▼
Docker Network
│
▼
EC2 Instance
│
▼
Application Load Balancer
│
▼
Client
Because the capture was performed using -i any, the same packet appears multiple times in the output. This is expected, as tcpdump captures the packet at different stages while it traverses the Linux networking stack and Docker networking components.
At this point, we have verified:
✅ The request reached the EC2 instance.
✅ The request was forwarded to the Docker container.
✅ The application successfully processed the request.
✅ An HTTP 200 OK response was returned to the client.
This confirms that the entire request path—from the user’s browser to the application running inside the container—is functioning correctly.
What We Proved
Using only three commands, we verified the complete request lifecycle.
Tool | What It Verified |
nslookup | Domain resolved correctly |
traceroute | Traffic reached AWS |
tcpdump | Traffic reached the EC2 instance |
HTTP 200 OK | Application successfully responded |
This simple exercise demonstrates the fundamental building blocks of network troubleshooting and provides a practical understanding of how traffic flows through AWS-hosted applications.
Further Reading
To keep the discussion focused, we intentionally treated the AWS infrastructure as a black box and concentrated on understanding how traffic flows from a user's machine to the application.
If you'd like to dive deeper into the underlying AWS architecture—including the VPC design, subnets, route tables, Application Load Balancer configuration, security groups, Docker deployment, and networking components used in this walkthrough—check out the companion article below:
📖 Understanding the AWS Network Architecture Behind This Demo

