This is an analysis of how Claude Code initiates web scraping requests. You might be surprised to find that claude code could scrape from an API endpoint, or from the host that’s running claude code. In this series, you will learn how to use network namespaces, tcpdump and MITMproxy to isolate a client’s network traffic and experimentally discover whether claude code is scraping content from an api endpoint or from the host that’s running claude code. Code for this project is available at my github.
You installed Claude Code. It ships with built-in network tools (WebFetch & WebSearch) that can reach out to the internet on your behalf. Each use requires your explicit approval (unless you’ve configured auto-approve policies). But here’s the question nobody answers in the documentation:
What exactly does it send and where is it sending requests from?
Inspecting Claude Code’s Network Traffic with Linux Namespaces and MITM Proxying

In the proxied fetch model, the request would route through Anthropic’s servers. The target system sees Anthropic’s IP, and Anthropic’s infrastructure handles the fetched content:

These two models have very different privacy and security implications. Which one does Claude Code actually use? This guide answers that question empirically.
When claude code “searches the web,” whose IP address does the search engine see- yours or Anthropic’s? What telemetry does it send home?
These aren’t hypothetical concerns. If you’re running an AI agent that has built-in network tools on a machine that can reach internal services, you need to know its traffic pattern. This guide shows you how you can discover this behavior directly and what I found during my analysis.
What you’ll learn
By the end of this guide, you’ll be able to:
- Isolate a single process’s network traffic on Linux using network namespaces: this technique ensures you won’t have other process’s packets in the capture
- Extract destination hostnames from encrypted TLS traffic using SNI and DNS metadata
- Decrypt HTTPS traffic for a specific process using MITM proxying with mitmproxy, scoped so only that one process is affected
- Classify all traffic the Claude CLI generates: API calls, web fetches, web searches, telemetry, and MCP connections
- Understand the security implications of a local-fetch model: What it means for your LAN and internal services
Prerequisites
You should be comfortable with:
- Linux terminal and shell scripting
- Basic networking concepts (IP addresses, ports, TCP, DNS)
- What tcpdump does (even if you don’t use it daily)
- What TLS/HTTPS provides (encrypted transport)
You’ll need installed:
- Linux with kernel namespace support (any modern distro)
tcpdump,iproute2(ipcommand),iptables- Python 3 (for the analysis scripts)
mitmproxy(pipx install mitmproxyorpip install mitmproxy) for the decryption sections- The
claudeCLI on your PATH slirp4netnsfor the rootless approach to collecting packets (available in most distro repos)
git clone git@github.com:CaptainMcCrank/claude-netns.git
cd claude-netns
chmod +x claude-sandbox.sh claude-mitm.sh rootless-capture.sh mitm-capture.sh
Key Concepts Before We Start
This guide relies on Linux networking and TLS concepts that may be unfamiliar or counterintuitive.
There is no per-process packet capture on Linux. Linux’s packet capture mechanism (AF_PACKET) attaches to interfaces, not processes. There is no tcpdump --pid. If you capture on an interface shared by every process on the box, you get everything mixed together. The first half of this guide builds a workaround for this using network namespaces.
HTTPS does not hide all metadata. TLS encrypts the payload. The payload includes the URL path, headers, and body. But the destination hostname leaks in plaintext via the TLS SNI extension in every ClientHello, and DNS queries leak it again via standard unencrypted lookups. You can’t read the content, but you can see where traffic goes. That partial visibility turns out to be enough to answer the most important question (where does WebFetch connect?) without any decryption at all.
MITM proxying is a standard debugging technique. The same TLS interception mechanism used by attackers on hostile networks is used every day by Burp Suite, Charles Proxy, Fiddler, mitmproxy, and corporate TLS inspection appliances. Despite the fact that these tools have legitimate applications, many corporate security tools treat them as hacking tools. Only perform MITM Proxying on networks and clients you’re authorized to inspect. Do not proceed if you have any doubts about your authorization for such techniques. While this is all legitimate debugging and auditing, there’s no way for a 3rd party to independently distinguish if this work is an attack or authorized. Many corporate security teams configure monitoring tools to alarm when they see tools such as MITM proxy installed.
Where WebFetch actually connects is an empirical question. Does the request go through Anthropic’s servers, or does it connect directly from your machine? This guide answers that with packet captures rather than assumptions.
Why a general tcpdump of all traffic fails
The straightforward approach is to capture traffic on your main interface:
sudo tcpdump -i eth0 -n -c 100 -w everything.pcap
Running this while using claude in another terminal produces a capture, but it contains a wall of noise: browser tabs, system update checks, NTP syncs, SSH keepalives, DNS queries from every application on the box. Claude’s traffic is in there somewhere, but finding it requires picking apart hundreds of flows by hand.

You might try filtering by destination:
sudo tcpdump -i eth0 -n host api.anthropic.com -w filtered.pcap
Better- but this requires you to know every destination in advance (e.g. api.anthropic.com). If claude contacts a URL you didn’t predict, you miss it. Additionally- other processes might also contact api.anthropic.com if you have other Anthropic integrations running.
Why this happens
tcpdump filters by network interface, not by process. There is no tcpdump --pid 12345 on Linux. The kernel’s packet capture mechanism (AF_PACKET sockets) attaches to interfaces and your main interface (eth0, wlan0, etc.) carries traffic from every process on the system.
Example analogy:
Trying to record one person’s phone calls by tapping the entire building’s phone line. You hear every tenant: browsers, updaters, background services. There’s no way to isolate one voice because they all share the same wire.
We need a way to give claude its own private network interface that carries only its traffic and nothing else. In Part 2, we’ll explore creating a Linux Namespace that enables us to isolate all network traffic for a specific process.

