Trace and Secure a Web Request
Trace a web request from DNS through routing, TCP, TLS, and HTTP with safe commands, then classify failures and review least-privilege security evidence.
Trace one HTTPS request from DNS lookup and local routing through TCP, certificate validation, and the HTTP response. The lab uses bounded, read-only commands to distinguish what each result proves, with separate route lookups for IPv4 and IPv6 and care for approved proxies. It also shows how to collect minimal evidence, protect sensitive output, and choose the next safe check without changing network configuration.
Trace and Secure a Web Request
A browser request can fail before it reaches a server, or succeed at the network layers and still receive an application error. This lab follows one HTTPS request from DNS lookup through route selection, TCP, TLS, and HTTP. You will collect small, read-only pieces of evidence and use them to locate the first failing boundary.
We will use https://example.org/, a reserved example domain, as the public service boundary. Your network may block public access; that is useful evidence, not a reason to disable a control. If you have an approved local HTTPS service, substitute its hostname and port, while keeping the certificate checks enabled.
flowchart TD
A[Hostname] --> B[DNS answer]
B --> C[Route to address]
C --> D[TCP connection to port 443]
D --> E[TLS certificate and handshake]
E --> F[HTTP response]
Introduction
A useful request diagnosis follows evidence in order: name resolution, local route selection, TCP connection, TLS validation, and the HTTP response. Each stage narrows the next question, while an incomplete stage leaves several possible causes open.
This lab turns that sequence into a small, timestamped evidence record using bounded, read-only commands. It keeps certificate checks enabled, treats packet capture as optional and authorized, and helps distinguish observations from hypotheses before handing an issue to another owner.
When to Use
Use this lab when an HTTPS request fails, when a service works from one network but not another, or when you need to explain which layer produced an error. It is also a useful incident drill for practicing evidence collection before asking another team to investigate.
When NOT to Use
Do not use this public example to probe a production incident target without authorization. Do not change routes, firewall rules, resolver configuration, or proxy settings as part of the lab. Avoid broad packet captures: they can collect unrelated traffic and sensitive data. If you need to inspect a production path, follow your incident and data-handling procedures.
Lab phases
Prepare the request
Phase 1: Record the baseline
Confirm the hostname and endpoint that you will test:
HOST=example.org
URL="https://${HOST}/"
printf 'Host: %s\nURL: %s\n' "$HOST" "$URL"
date -Is
Expected: the note contains example.org, its HTTPS URL, and a timestamp with a timezone offset. If your shell does not support date -Is, record the local time and timezone another way.
Phase 2: Ask DNS for an address
Query IPv4 and IPv6 records separately. The command has short time and retry limits so a broken resolver does not leave the lab waiting indefinitely.
dig +time=2 +tries=1 "$HOST" A
dig +time=2 +tries=1 "$HOST" AAAA
Expected: status: NOERROR and possibly one or more A or AAAA answers. An empty answer section with NOERROR can mean there is no record of that type; it is different from NXDOMAIN (the name does not exist) and SERVFAIL (the resolver could not complete the lookup). A timeout means no usable DNS reply arrived before the limit. Record the resolver shown in the output and the answer you will use for the matching IPv4 or IPv6 route check.
Set IP to one address returned by DNS. Use the command for that address family:
IP=203.0.113.10 # Replace with an actual A answer from your dig output.
ip -4 route get "$IP"
# For an AAAA answer, use: ip -6 route get "$IP"
203.0.113.10 is documentation-only and will not be routable as a public test target. Replace it before running the IPv4 route check. Expected output names the selected route, interface, and usually a source address. Network is unreachable or a missing route is evidence at the local route-selection step. A route result says what the kernel would choose; it does not prove the remote host is reachable.
Inspect the local and application path
Phase 3: Check local socket evidence
On the client, inspect current TCP sockets without changing them:
ss -tn state established
This is a snapshot. It may show no connection if the request has already closed. If you operate the server for a local lab, inspect only that server’s listener state:
ss -lnt
Expected: LISTEN rows identify local addresses and ports. A service bound to 127.0.0.1:8443 accepts loopback connections, not connections sent to a different host interface. A listener is only one piece of evidence; it does not prove routing or policy permits a client to reach it.
Phase 4: Observe TCP, TLS, and HTTP with curl
Make one verbose request. Do not add -k/--insecure; certificate verification is part of the test.
curl -v --connect-timeout 5 --max-time 15 "$URL" -o /dev/null
The verbose trace shows whether curl resolved the host, which address it tried, whether TCP connected, whether TLS negotiation completed, and the HTTP status line if the server returned a response. -o /dev/null discards the response body. --connect-timeout bounds connection setup; --max-time bounds the whole request. If curl uses an approved proxy from its configuration or environment, the first TCP peer is the proxy; record that before drawing conclusions about a direct route to the origin. Do not bypass the proxy as part of this lab.
For a headers-only request, use:
curl -I --connect-timeout 5 --max-time 15 "$URL"
Some servers treat HEAD differently from GET, so compare results carefully. A 405 Method Not Allowed from this command can still show that an HTTP server answered. The verbose GET above is the primary observation.
| First observed result | Likely boundary | Evidence and next read-only check |
|---|---|---|
Could not resolve host |
DNS | Compare dig status, answer section, resolver, and time. |
Network is unreachable / no route |
Local route selection | Check the exact destination passed to the family-matched route lookup; do not add a route. |
Connection refused |
TCP reached a host that rejected the port, or an active reject was sent | Check the destination/port and, if authorized, the service’s ss -lnt output. |
| Connect timeout | TCP handshake did not complete in time | Compare route, client network, and authorized server or load-balancer logs. A silent drop can look like this. |
| Certificate or TLS alert error | TCP likely connected; TLS negotiation or validation failed | Read the certificate name, trust, expiry, system clock, and TLS alert. Do not bypass verification. |
HTTP 4xx or 5xx |
DNS, route, TCP, and TLS got far enough to receive HTTP | Record status and response headers; investigate application, authorization, proxy, or upstream behavior. |
HTTP 2xx / 3xx |
Request received an HTTP response | This proves this one request worked from this client at this time; it does not prove every route or user works. |
Collect bounded evidence and report
Phase 5: Optional bounded packet observation
Only capture traffic on a machine and network you are authorized to inspect. A short capture can confirm whether packets appear at one interface, but encrypted payloads remain sensitive metadata and should still be handled carefully. Substitute the real address observed in DNS, then stop automatically after at most ten seconds or twenty matching packets:
sudo timeout 10s tcpdump -ni any -c 20 "host $IP and tcp port 443"
If you do not have timeout, omit this phase rather than running an unbounded capture. Do not broaden the filter. A client-side SYN with no observed reply narrows the question to the path beyond that capture point, but does not identify which router or policy dropped it. A reset indicates a response rejected the connection; correlate timestamps with server-side evidence before assigning cause.
Phase 6: Write the finding
Use this short evidence format:
Target and port:
Client and time (with timezone):
DNS result and resolver:
Selected address and route/interface:
TCP result:
TLS result:
HTTP status, if any:
First failing boundary:
Next safe check and owner:
Sensitive details removed before sharing:
The first failing boundary is the earliest step for which evidence is missing or contradictory. State uncertainty plainly. For example: “DNS returned an address and the local route exists; curl timed out during connect, so TCP completion is unproven. I have not identified where packets were dropped.”
Production Failure Scenarios
- A stale DNS record sends only one office subnet to a retired endpoint. Compare resolver answers and timestamps from an approved working and failing client.
- The route exists, but a network policy silently drops TCP SYN packets. A timeout is consistent with a drop, but it is not proof of the responsible policy; compare authorized captures or flow logs at more than one boundary.
- A service binds to loopback after a deployment. The process is listening, but only on
127.0.0.1; compare the bind address with the intended destination interface. - TCP connects but certificate verification fails after certificate rotation. Preserve the hostname and TLS verification, then check the presented certificate chain and expiry.
- TLS succeeds and the request receives
503. The network path worked far enough to reach an HTTP responder; inspect application and upstream health evidence rather than changing client routes.
Trade-Off Table
| Check | What it tells you | Cost or limit |
|---|---|---|
dig |
Resolver answer, status, and timing | One resolver view; split DNS may produce different answers elsewhere. |
ip route get / ip -6 route get |
Local kernel route decision for an IPv4 or IPv6 address | Does not test a handshake or remote policy. |
ss |
Local socket/listener snapshot | Short lived connections can disappear before inspection; a listener is not proof of reachability. |
curl -v |
Client-side DNS, connect, TLS, and HTTP progress | Shows one client path and one request; output can expose hostnames or addresses. |
Bounded tcpdump |
Packets visible at a selected capture point | Requires authorization and may collect metadata; absence at one point does not locate the drop. |
Observability Checklist
- Record timestamp and timezone, client identity at an approved level, hostname, port, and command.
- Preserve DNS status, resolver, record type, answer, and TTL when present.
- Record the exact destination address and the matching IPv4 (
ip -4 route get) or IPv6 (ip -6 route get) result. - Mark whether TCP connected, was refused, or timed out.
- Record TLS verification outcome without disabling certificate checks.
- Record HTTP status and relevant response headers; omit bodies unless needed and approved.
- Correlate client evidence with authorized server, proxy, load-balancer, or flow logs using timestamps.
- State what the evidence cannot establish and name the next safe check.
Security and Compliance Notes
Use the narrowest test that answers the question. This lab sends a DNS lookup and a small number of HTTPS requests to a reserved example host. Use an approved local or organizational service when public destinations are prohibited.
For least privilege:
- Use read-only inspection commands and the current account.
dig,ip route get/ip -6 route get,ss, andcurldo not need elevated rights for these examples. - Run optional capture only with explicit authorization, a narrow host/port filter, a short duration, and a packet count. Elevation with
sudois needed on some systems; omit capture if approval or tooling is unavailable. - Keep TLS certificate verification enabled. Never use
curl -kas a “fix” for an untrusted, expired, or mismatched certificate. - Do not collect credentials, cookies, tokens, request bodies, unrelated traffic, or more packet data than the investigation requires.
- Store notes and captures only in approved locations, restrict access, redact sensitive values, and follow retention and incident-response rules.
- Do not change firewall, route, DNS, proxy, or service configuration during this diagnostic exercise.
Common Pitfalls / Anti-Patterns
- Testing an IP with
curland concluding the hostname works. Direct-IP requests can change Host headers and TLS SNI; use the hostname for the request. - Treating
ip route getorip -6 route getas an end-to-end reachability test. They report the local route decision only. - Calling every failed
curla DNS problem. Read the last completed stage in the verbose output. - Adding
-k, changing resolvers, or repeatedly retrying until the error disappears. Those actions hide evidence and can violate policy. - Treating a timeout as proof of a firewall drop. A host outage, routing issue, congestion, or silent policy can look similar.
- Capturing on
anywithout a host filter, duration, or packet limit. Broad captures can expose unrelated data and grow quickly. - Sharing raw terminal output without review. Addresses, internal hostnames, usernames, and proxy details may be sensitive.
Quick Recap Checklist
- Reproduce once and note the time and exact target.
- Check A and AAAA DNS answers and their status.
- Check the local route to one resolved address.
- Inspect relevant local sockets or the authorized server listener.
- Use bounded
curl -vwith normal TLS validation. - Classify the first failure as DNS, route, TCP, TLS, or HTTP.
- Collect optional packet evidence only when approved and bounded.
- Write what is known, what remains uncertain, and the next safe check.
Interview Questions
It shows which local route the kernel would use for that destination at that moment. It does not prove that packets leave the host, that a firewall permits them, or that the remote service is listening.
A refusal usually means the client received an explicit rejection, often a TCP reset, because the target port has no accepting listener or a control actively rejected it. A timeout means the expected connection progress did not arrive before the deadline. A silent drop is one possible cause, not a conclusion by itself.
TLS runs after TCP establishes a connection. Once TCP connects, a certificate mismatch, expired certificate, trust-chain problem, protocol mismatch, or TLS alert can stop the request before HTTP. Keep certificate verification enabled so the test preserves that evidence.
An HTTP responder returned a status after the request reached an HTTP-speaking boundary. DNS, routing, TCP, and TLS worked far enough for that response, but the application or an upstream dependency may still be unhealthy. Correlate the status with service-side logs.
An empty answer with NOERROR means the name exists but has no record of the queried type. NXDOMAIN means the name does not exist. SERVFAIL means the resolver could not complete the lookup, while a timeout means no reply arrived before the client deadline. Record the response status and resolver before choosing the next check.
The hostname is used for TLS Server Name Indication and HTTP host routing. A direct-IP request can reach a different virtual host or fail certificate-name validation, so it does not test the same request path as the hostname.
`curl -I` sends HEAD, and some servers or intermediaries handle HEAD differently from GET. A 405 response still shows that an HTTP responder answered the request; use the bounded verbose GET as the main observation for this lab.
It shows the SYN at that capture point and no matching reply was observed there during the capture. It does not identify which router, firewall, host, or policy caused the gap. Compare timestamps with authorized evidence from another boundary before assigning cause.
Further Reading
- RFC 2606: Reserved Top Level DNS Names reserves
example.orgfor documentation and examples. - RFC 1034: Domain Names describes the concepts behind the DNS namespace and resolution.
- RFC 9293: Transmission Control Protocol specifies current TCP behavior.
- RFC 8446: TLS 1.3 documents the TLS handshake and security properties.
- Continue with Packet Capture and Network Troubleshooting for capture interpretation, or Network Security for network controls.
Conclusion
Follow the request in order: resolve its name, inspect the local route, observe TCP, validate TLS, then read the HTTP response. The first stage without supporting evidence is where the next investigation should focus. Keep tests small, preserve certificate checks, and collect only information you are authorized to handle.
Evidence and acceptance rubric
Submit a short lab note with the command outputs or concise excerpts, with sensitive details removed. The lab is complete when the note:
- Identifies the hostname, test time and timezone, resolver answer, and selected address.
- Includes the local route result and classifies the TCP outcome as connected, refused, or timed out.
- Records whether TLS validation completed and the HTTP status if one was returned.
- Names the earliest failing boundary, distinguishes observation from hypothesis, and proposes one safe next check.
- Confirms that no configuration was changed, TLS verification stayed enabled, and any capture was authorized, filtered, and bounded (or omitted).
Score each item as 0 (missing), 1 (partial or unsupported), or 2 (complete and supported by evidence). A passing lab earns at least 8/10, with item 5 required for any capture. Do not include raw captures or sensitive output in a public submission.
Category
Related Posts
SSL, TLS, and HTTPS: Securing Web Communication
Understand TLS handshake, certificates, cipher suites, and how HTTPS works. Learn the differences between SSL and TLS and why encryption matters.
Network Encapsulation: Follow a Packet Across the Stack
Follow an HTTPS request from a browser through transport, IP, and link layers, and learn how headers, MTU, routers, and packet captures fit together.
Forward and Reverse Proxies: Routing, Trust, and Use Cases
Learn how forward and reverse proxies handle HTTP traffic, CONNECT tunnels, TLS termination, caching, routing, trusted headers, and production failures.