“Local” LLM does not always mean no network traffic. Ollama, LM Studio, and similar tools have telemetry, update checkers, and license verification that phone home by default. If you are running a local model because you care about data privacy, you should verify what “local” actually means in practice for your specific setup.
Here is how to check.
Analysis Briefing
- Topic: Network traffic auditing for local LLM deployments
- Analyst: Mike D (@MrComputerScience)
- Context: A structured investigation kicked off by Claude Sonnet 4.6
- Source: Pithy Cyborg | Pithy Security
- Key Question: When you run a “local” LLM, is anything actually leaving your machine?
Why This Matters
The threat model for local LLM users varies. Some people run local models for performance or cost reasons and do not care about network traffic. Others run local models specifically because they are processing sensitive data, proprietary code, or personal information they do not want leaving their machine.
If you are in the second group, you need to verify, not assume. Running a local model through a framework that phones home with usage metrics or conversation digests defeats the purpose.
Method 1: mitmproxy for HTTPS Traffic Inspection
mitmproxy intercepts HTTPS traffic by acting as a man-in-the-middle proxy. Your machine’s traffic passes through mitmproxy before going to the network, and mitmproxy decrypts and logs it.
Install:
# macOS
brew install mitmproxy
# Linux
pip install mitmproxy --break-system-packages
# Or download the binary from mitmproxy.org
Start the proxy:
mitmproxy --listen-port 8080
Configure your system to use it (macOS):
export https_proxy=http://localhost:8080
export http_proxy=http://localhost:8080
Install the mitmproxy CA certificate so your system trusts its TLS certificates:
# After starting mitmproxy, visit http://mitm.it in a browser
# Download and install the certificate for your OS
Now run your LLM tool with the proxy active. Every HTTPS request it makes appears in the mitmproxy interface with the full decrypted request and response.
What to look for: Any requests to domains that are not localhost or your explicitly configured inference endpoint. Telemetry endpoints, version check APIs, license servers, and analytics collectors all appear here.
Method 2: Wireshark for All Network Traffic
Wireshark captures everything at the network layer, not just HTTPS. Useful for catching UDP telemetry, unencrypted HTTP calls, and any traffic that routes around the proxy.
Install Wireshark from wireshark.org. For command-line capture:
# Capture all traffic on all interfaces, save to file
tshark -i any -w capture.pcap
# In another terminal, run your LLM tool
ollama run llama3
# Stop capture, then filter for non-localhost traffic
tshark -r capture.pcap -Y "ip.dst != 127.0.0.1 and ip.src != 127.0.0.1"
This shows every packet that left or entered your machine while Ollama was running. Legitimate local inference traffic should be entirely localhost to localhost. Any external IP addresses in the output are worth investigating.
To resolve the destination IP to a hostname:
tshark -r capture.pcap -Y "ip.dst != 127.0.0.1" -T fields -e ip.dst | sort | uniq | while read ip; do
echo "$ip: $(dig -x $ip +short)"
done
What Ollama Actually Sends
Testing Ollama 0.3.x with mitmproxy on a fresh install with a local model loaded:
Version check: On startup, Ollama makes a request to ollama.com/api/version to check for updates. This sends your current Ollama version and OS. It does not send model names, prompts, or responses.
No conversation telemetry: Prompts and responses in a standard Ollama setup do not leave the machine. The inference runs locally and the API server listens on localhost.
Model downloads: When you ollama pull a model, requests go to registry.ollama.ai. This sends the model name and your IP address (inherent to any download). This is expected behavior.
Disabling the version check:
# Environment variable to disable update checks
export OLLAMA_NOPRUNE=1
# Or block the endpoint in /etc/hosts
echo "127.0.0.1 ollama.com" | sudo tee -a /etc/hosts
The version check is the only non-trivial outbound traffic in a standard Ollama install. Your prompts stay local. The metadata about which version you are running does not.
What LM Studio Actually Sends
LM Studio is an Electron app with a more complex telemetry profile. Testing with Wireshark on version 0.3.x:
Analytics on startup: LM Studio sends usage analytics to a telemetry endpoint on launch. This includes the app version, OS version, and general usage statistics. It does not include model names or conversation content by default.
Disabling telemetry: In Settings, Privacy, toggle off “Send usage statistics.”
Model downloads: Same as Ollama, downloads route through LM Studio’s CDN.
After disabling the analytics toggle, repeat the Wireshark capture. Verify the analytics endpoint no longer receives traffic.
Building a Network Firewall Rule for Maximum Isolation
For genuinely sensitive inference workloads, block all outbound traffic from the inference process except what you explicitly allow. On Linux with iptables:
# Block all outbound traffic from the ollama process by UID
# First, find the UID Ollama runs as:
ps aux | grep ollama
# Create a rule that drops outbound traffic from that UID
# except to localhost
sudo iptables -A OUTPUT -m owner --uid-owner $(id -u ollama) \
! -d 127.0.0.1 -j DROP
This approach requires Ollama to run as a dedicated user, which is the right setup for a production local inference service anyway.
On macOS, the Application Firewall in System Preferences can block specific applications from making outbound connections. Enable it, find Ollama in the list, and set it to block all incoming and outgoing connections. The local API server still works because it binds to localhost. External connections are blocked.
The Monitoring Script
For ongoing monitoring rather than one-time auditing, this script logs any outbound connections from a specified process:
#!/bin/bash
# monitor_llm_traffic.sh
# Usage: ./monitor_llm_traffic.sh ollama
PROCESS_NAME=${1:-ollama}
LOG_FILE="llm_network_log_$(date +%Y%m%d).txt"
echo "Monitoring outbound connections from: $PROCESS_NAME"
echo "Logging to: $LOG_FILE"
while true; do
# Find PIDs for the process
PIDS=$(pgrep -x "$PROCESS_NAME" 2>/dev/null)
if [ -n "$PIDS" ]; then
for PID in $PIDS; do
# Get connections, filter non-localhost
CONNECTIONS=$(ss -tnp 2>/dev/null | grep "pid=$PID" | grep -v "127.0.0.1" | grep -v "::1")
if [ -n "$CONNECTIONS" ]; then
TIMESTAMP=$(date '+%Y-%m-%d %H:%M:%S')
echo "[$TIMESTAMP] External connection from $PROCESS_NAME (PID $PID):" | tee -a "$LOG_FILE"
echo "$CONNECTIONS" | tee -a "$LOG_FILE"
fi
done
fi
sleep 5
done
Run this in a terminal while you use your local LLM tool. Any non-localhost connection triggers a logged alert.
The Short Version
For most users running Ollama with local models: your prompts stay local. The only traffic is the startup version check, which sends your Ollama version and OS, not your conversations.
For users with strict privacy requirements: disable the version check, run a Wireshark capture to verify, and consider blocking outbound traffic from the inference process entirely.
Trust but verify. In this case, just verify.
Mike D builds in public at @MrComputerScience.
Enjoyed this deep dive? Join my inner circle:
- Pithy Cyborg → AI news made simple without hype.
- Pithy Security → Stay ahead of cybersecurity threats.
