An interactive, SSL/TLS-capable intercepting proxy for HTTP/1, HTTP/2, and WebSockets.
—
Comprehensive configuration system with type-safe options for proxy behavior, TLS settings, network configuration, and addon parameters. Provides both programmatic and file-based configuration management.
Main configuration management class providing type-safe option handling and validation.
class Options:
"""
Main configuration class for mitmproxy.
Manages all proxy settings with type validation and change notifications.
Supports loading from files, command-line arguments, and programmatic updates.
"""
def __init__(self, **kwargs) -> None:
"""
Initialize options with default values.
Parameters:
- **kwargs: Initial option values to override defaults
"""
def set(self, key: str, value: Any) -> None:
"""
Set an option value with validation.
Parameters:
- key: Option name
- value: New option value
Raises:
- OptionsError: If key is invalid or value type is wrong
"""
def get(self, key: str, default: Any = None) -> Any:
"""
Get an option value.
Parameters:
- key: Option name
- default: Default value if option not set
Returns:
- Current option value or default
"""
def update(self, **kwargs) -> None:
"""
Update multiple options at once.
Parameters:
- **kwargs: Option key-value pairs to update
"""
def load_paths(self, *paths: str) -> None:
"""
Load options from configuration files.
Parameters:
- *paths: Configuration file paths to load
"""
def save(self, path: str) -> None:
"""
Save current options to a configuration file.
Parameters:
- path: File path to save configuration
"""
def __getattr__(self, name: str) -> Any:
"""Access options as attributes."""
def __setattr__(self, name: str, value: Any) -> None:
"""Set options as attributes."""Key configuration constants and default values.
# Default configuration directory
CONF_DIR: str = "~/.mitmproxy"
# Configuration file basename
CONF_BASENAME: str = "mitmproxy"
# Default key size for certificate generation
KEY_SIZE: int = 2048
# Content view line cutoff for performance
CONTENT_VIEW_LINES_CUTOFF: int = 512
# Default proxy ports
DEFAULT_PROXY_PORT: int = 8080
DEFAULT_WEB_PORT: int = 8081
# TLS configuration
DEFAULT_TLS_PORT: int = 443Key configuration options organized by category.
# Network Options
class NetworkOptions:
"""Network-related configuration options."""
listen_host: str = "127.0.0.1"
listen_port: int = 8080
mode: str = "regular" # regular, transparent, socks5, reverse, upstream
upstream_cert: bool = True
# TLS/SSL Options
class TLSOptions:
"""TLS/SSL configuration options."""
certs: List[str] = []
cadir: str = "~/.mitmproxy"
ssl_insecure: bool = False
ssl_verify_upstream_trusted_ca: Optional[str] = None
ssl_verify_upstream_trusted_confdir: Optional[str] = None
# Proxy Behavior Options
class ProxyOptions:
"""Proxy behavior configuration options."""
allow_hosts: List[str] = []
ignore_hosts: List[str] = []
tcp_hosts: List[str] = []
intercept: Optional[str] = None
modify_body: List[str] = []
modify_headers: List[str] = []
# Interface Options
class InterfaceOptions:
"""User interface configuration options."""
console_eventlog: bool = False
console_focus_follow: bool = False
web_open_browser: bool = True
web_debug: bool = Falsefrom mitmproxy import options
def setup_basic_proxy():
"""Set up basic proxy configuration."""
opts = options.Options()
# Set basic proxy options
opts.listen_host = "0.0.0.0" # Listen on all interfaces
opts.listen_port = 8080
opts.mode = "regular"
# Enable upstream certificate verification
opts.upstream_cert = True
# Set custom certificate authority directory
opts.cadir = "/path/to/custom/ca"
return opts
def setup_transparent_proxy():
"""Set up transparent proxy configuration."""
opts = options.Options()
# Configure for transparent mode
opts.mode = "transparent"
opts.listen_port = 8080
# Allow specific hosts only
opts.allow_hosts = ["*.example.com", "api.service.com"]
# Ignore certain hosts (don't proxy)
opts.ignore_hosts = ["localhost", "127.0.0.1", "*.local"]
return opts
def setup_reverse_proxy():
"""Set up reverse proxy configuration."""
opts = options.Options()
# Configure reverse proxy to specific upstream
opts.mode = "reverse:https://api.backend.com"
opts.listen_port = 8080
# Modify headers for backend
opts.modify_headers = [
"/~s/Host/api.backend.com", # Set Host header
"/~s/X-Forwarded-Proto/https" # Add forwarded protocol
]
return optsfrom mitmproxy import options
import os
def setup_custom_tls():
"""Configure custom TLS settings."""
opts = options.Options()
# Custom certificate directory
ca_dir = os.path.expanduser("~/custom_mitmproxy_ca")
opts.cadir = ca_dir
# Custom certificates for specific domains
opts.certs = [
"example.com=/path/to/example.com.pem",
"*.api.com=/path/to/wildcard-api.pem"
]
# Disable upstream certificate verification (testing only!)
opts.ssl_insecure = True
# Custom trusted CA for upstream verification
opts.ssl_verify_upstream_trusted_ca = "/path/to/custom-ca.pem"
return opts
def setup_client_certificates():
"""Configure client certificate authentication."""
opts = options.Options()
# Client certificate for upstream authentication
opts.client_certs = [
"api.secure.com=/path/to/client-cert.pem"
]
# Configure TLS versions
opts.tls_version_client_min = "TLSv1.2"
opts.tls_version_server_min = "TLSv1.2"
return optsfrom mitmproxy import options
import yaml
def load_configuration_from_file():
"""Load configuration from YAML file."""
opts = options.Options()
# Load from custom configuration file
config_path = "mitmproxy_config.yaml"
try:
with open(config_path, 'r') as f:
config = yaml.safe_load(f)
# Apply configuration options
for key, value in config.items():
if hasattr(opts, key):
setattr(opts, key, value)
print(f"Loaded configuration from {config_path}")
except FileNotFoundError:
print(f"Configuration file {config_path} not found, using defaults")
return opts
def setup_development_proxy():
"""Configuration optimized for development work."""
opts = options.Options()
# Development-friendly settings
opts.listen_host = "0.0.0.0"
opts.listen_port = 8080
opts.web_open_browser = True
opts.web_debug = True
# Enable console event logging
opts.console_eventlog = True
opts.console_focus_follow = True
# Ignore common development URLs
opts.ignore_hosts = [
"localhost:*",
"127.0.0.1:*",
"*.local",
"webpack-dev-server",
"hot-reload"
]
# Intercept API calls for debugging
opts.intercept = "~u /api/"
# Modify CORS headers for development
opts.modify_headers = [
"/~s/Access-Control-Allow-Origin/*",
"/~s/Access-Control-Allow-Methods/GET,POST,PUT,DELETE,OPTIONS",
"/~s/Access-Control-Allow-Headers/Content-Type,Authorization"
]
return opts
def setup_security_testing():
"""Configuration for security testing and analysis."""
opts = options.Options()
# Security testing configuration
opts.listen_port = 8080
opts.ssl_insecure = True # Allow invalid certificates
# Save all flows for analysis
opts.save_stream_file = "security_test_flows.mitm"
# Enable detailed logging
opts.verbosity = 2
# Don't ignore any hosts
opts.ignore_hosts = []
# Intercept all HTTPS traffic
opts.intercept = "~secure"
# Add security headers for testing
opts.modify_headers = [
"/~s/X-Security-Test/enabled"
]
return optsfrom mitmproxy import options
import threading
import time
class ConfigurationManager:
"""Manages dynamic configuration updates."""
def __init__(self, initial_opts=None):
self.opts = initial_opts or options.Options()
self.lock = threading.Lock()
def update_proxy_mode(self, new_mode):
"""Dynamically update proxy mode."""
with self.lock:
old_mode = self.opts.mode
self.opts.mode = new_mode
print(f"Proxy mode changed from {old_mode} to {new_mode}")
def toggle_interception(self, pattern=None):
"""Toggle request interception on/off."""
with self.lock:
if self.opts.intercept:
# Turn off interception
old_pattern = self.opts.intercept
self.opts.intercept = None
print(f"Interception disabled (was: {old_pattern})")
else:
# Turn on interception
self.opts.intercept = pattern or "~all"
print(f"Interception enabled: {self.opts.intercept}")
def add_ignore_host(self, host_pattern):
"""Add host to ignore list."""
with self.lock:
if host_pattern not in self.opts.ignore_hosts:
self.opts.ignore_hosts.append(host_pattern)
print(f"Added {host_pattern} to ignore list")
def remove_ignore_host(self, host_pattern):
"""Remove host from ignore list."""
with self.lock:
if host_pattern in self.opts.ignore_hosts:
self.opts.ignore_hosts.remove(host_pattern)
print(f"Removed {host_pattern} from ignore list")
def update_upstream_proxy(self, upstream_url):
"""Update upstream proxy configuration."""
with self.lock:
if upstream_url:
self.opts.mode = f"upstream:{upstream_url}"
print(f"Upstream proxy set to: {upstream_url}")
else:
self.opts.mode = "regular"
print("Upstream proxy disabled")
# Usage example
config_manager = ConfigurationManager()
# Dynamic updates
config_manager.update_proxy_mode("transparent")
config_manager.toggle_interception("~u /api/")
config_manager.add_ignore_host("*.cdn.com")from mitmproxy import options
from mitmproxy.exceptions import OptionsError
def validate_proxy_configuration(opts):
"""Validate proxy configuration for common issues."""
issues = []
# Check port conflicts
if opts.listen_port == opts.web_port:
issues.append("Proxy and web interface ports cannot be the same")
# Validate mode-specific settings
if opts.mode.startswith("reverse:"):
upstream_url = opts.mode.split(":", 1)[1]
if not upstream_url.startswith(("http://", "https://")):
issues.append("Reverse proxy upstream must be a valid URL")
# Check certificate paths
for cert_spec in opts.certs:
if "=" in cert_spec:
domain, cert_path = cert_spec.split("=", 1)
if not os.path.exists(cert_path):
issues.append(f"Certificate file not found: {cert_path}")
# Validate TLS settings
if opts.ssl_insecure and not opts.upstream_cert:
issues.append("ssl_insecure=True with upstream_cert=False may cause issues")
# Check host patterns
for pattern in opts.allow_hosts + opts.ignore_hosts:
if not pattern:
issues.append("Empty host pattern found")
return issues
def apply_safe_configuration(opts):
"""Apply configuration with validation and error handling."""
try:
# Validate configuration
issues = validate_proxy_configuration(opts)
if issues:
print("Configuration issues found:")
for issue in issues:
print(f" - {issue}")
response = input("Continue anyway? (y/N): ")
if response.lower() != 'y':
return False
# Apply configuration (this would typically be done by the master)
print("Configuration applied successfully")
return True
except OptionsError as e:
print(f"Configuration error: {e}")
return False
except Exception as e:
print(f"Unexpected error applying configuration: {e}")
return False
# Usage
opts = options.Options()
opts.listen_port = 8080
opts.web_port = 8081
opts.mode = "reverse:https://api.example.com"
if apply_safe_configuration(opts):
print("Proxy configured and ready")
else:
print("Configuration failed")Install with Tessl CLI
npx tessl i tessl/pypi-mitmproxy