Skip to content

Instantly share code, notes, and snippets.

@olliefr
Created October 7, 2025 14:18
Show Gist options
  • Select an option

  • Save olliefr/1b4302ad71352633693926cbed099d14 to your computer and use it in GitHub Desktop.

Select an option

Save olliefr/1b4302ad71352633693926cbed099d14 to your computer and use it in GitHub Desktop.
Network Traffic Capture and Profiling for Python scripts
#!/bin/bash
# Network Traffic Capture and Profiling for Python scripts
#
# - Runs a Python script in an isolated network namespace and captures all its network
# traffic.
# - Profiles the Python script's performance using cProfile.
# - Captures SSL/TLS keys for decrypting HTTPS traffic in Wireshark.
#
# Usage: ./run.sh <python_script.py>
#
# Outputs:
# - capture_TIMESTAMP.pcap: Network traffic capture
# - profile_TIMESTAMP.prof: Python profiling data
# - sslkeys_TIMESTAMP.log: SSL/TLS keys for decryption
#
# Requirements: sudo, tcpdump, ip, iptables, python with cProfile
#
# Copyright (c) 2025 Oliver Frolovs <[email protected]>
# SPDX-License-Identifier: MIT
set -e
if [ $# -eq 0 ]; then
echo "Usage: $0 <python_script.py>"
exit 1
fi
SCRIPT="$1"
if [ ! -f "$SCRIPT" ]; then
echo "Error: $SCRIPT not found"
exit 1
fi
TIMESTAMP=$(date +%Y%m%d_%H%M%S)
SUBNET="10.200.1.0/24"
CAPTURE_FILE="capture_${TIMESTAMP}.pcap"
PROFILE_FILE="profile_${TIMESTAMP}.prof"
SSLKEY_FILE="sslkeys_${TIMESTAMP}.log"
NAMESPACE="python_ns_$$"
VETH_HOST="veth_py_$$"
ORIGINAL_FORWARD=$(< /proc/sys/net/ipv4/ip_forward)
PYTHON_BIN=$(which python)
cleanup() {
if [ ! -z "$TCPDUMP_PID" ] && ps -p $TCPDUMP_PID > /dev/null 2>&1; then
sudo kill $TCPDUMP_PID 2>/dev/null || true
fi
sudo iptables -t nat -D POSTROUTING -s $SUBNET -j MASQUERADE 2>/dev/null || true
sudo sysctl -w net.ipv4.ip_forward=$ORIGINAL_FORWARD > /dev/null 2>&1 || true
sudo rm -rf /etc/netns/$NAMESPACE 2>/dev/null || true
sudo ip netns delete $NAMESPACE 2>/dev/null || true
sudo ip link delete $VETH_HOST 2>/dev/null || true
}
trap cleanup EXIT INT TERM
# Create network namespace
sudo ip netns add $NAMESPACE
sudo ip netns exec $NAMESPACE ip link set lo up
# Configure DNS
sudo mkdir -p /etc/netns/$NAMESPACE
sudo cp /etc/resolv.conf /etc/netns/$NAMESPACE/
# Create and configure veth pair
sudo ip link add $VETH_HOST type veth peer name veth1
sudo ip link set veth1 netns $NAMESPACE
# Configure interfaces
sudo ip addr add 10.200.1.1/24 dev $VETH_HOST
sudo ip link set $VETH_HOST up
sudo ip netns exec $NAMESPACE ip addr add 10.200.1.2/24 dev veth1
sudo ip netns exec $NAMESPACE ip link set veth1 up
sudo ip netns exec $NAMESPACE ip route add default via 10.200.1.1
# Enable NAT
if ! sudo iptables -t nat -A POSTROUTING -s $SUBNET -j MASQUERADE; then
echo "Error: Failed to add iptables rule"
exit 1
fi
sudo sysctl -w net.ipv4.ip_forward=1 > /dev/null
# Start capture
sudo tcpdump -i $VETH_HOST -w "$CAPTURE_FILE" > /dev/null 2>&1 &
TCPDUMP_PID=$!
# Wait for capture file with exponential backoff
WAIT=1
for i in {1..10}; do
if [ -f "$CAPTURE_FILE" ]; then
break
fi
sleep 0.$(printf "%02d" $WAIT)
WAIT=$((WAIT * 2))
done
if [ ! -f "$CAPTURE_FILE" ] || ! ps -p $TCPDUMP_PID > /dev/null 2>&1; then
echo "Error: tcpdump failed to start"
TCPDUMP_PID=""
exit 1
fi
# Run Python in namespace with profiling
sudo SSLKEYLOGFILE="$SSLKEY_FILE" GOOGLE_APPLICATION_CREDENTIALS="$HOME/.config/gcloud/application_default_credentials.json" ip netns exec $NAMESPACE "$PYTHON_BIN" -m cProfile -o "$PROFILE_FILE" "$SCRIPT"
echo "Capture saved to: $CAPTURE_FILE"
echo "Profile saved to: $PROFILE_FILE"
echo "SSL keys saved to: $SSLKEY_FILE"
@olliefr
Copy link
Author

olliefr commented Oct 7, 2025

@olliefr
Copy link
Author

olliefr commented Oct 7, 2025

  • Tested with Python 3.12.3 on WSL2 Ubuntu 24.04.3 on Windows 11 24H2.
  • Decrypted and analysed the result with Wireshark 4.4.9.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment