Skip to content

Instantly share code, notes, and snippets.

@hereisderek
Last active August 21, 2026 00:31
Show Gist options
  • Select an option

  • Save hereisderek/a2e7eecc1835be2d32e2b0b6f690aa6d to your computer and use it in GitHub Desktop.

Select an option

Save hereisderek/a2e7eecc1835be2d32e2b0b6f690aa6d to your computer and use it in GitHub Desktop.
mitmproxy installer script
#!/bin/sh
# Exit immediately if a command exits with a non-zero status
set -e
UPDATE_ONLY=0
AUTO_UPDATE=0
INSTALL_SERVICES=""
ROOT_DIR=""
show_help() {
echo "Usage: $0 [OPTIONS]"
echo "Install or update mitmproxy (Native package on Alpine, Latest Binary on other Linux)."
echo ""
echo "Options:"
echo " --update-only Only update if mitmproxy is already installed."
echo " --auto Update existing services and remove unspecified ones."
echo " --install [SVC:PORT:PW] Symlink binaries and setup auto-start services."
echo " Examples: --install mitmdump:8080 mitmweb:8081:secret"
echo " --install mitmweb::secret (default port)"
echo " --root-dir DIR Specify the installation root directory."
echo " -h, --help Print all command-line options."
}
# Parse command-line arguments
while [ "$#" -gt 0 ]; do
case "$1" in
--update-only) UPDATE_ONLY=1; shift ;;
--auto) AUTO_UPDATE=1; shift ;;
--install)
shift
while [ "$#" -gt 0 ]; do
case "$1" in
-*) break ;;
*) INSTALL_SERVICES="$INSTALL_SERVICES $1"; shift ;;
esac
done
if [ -z "$INSTALL_SERVICES" ]; then
echo "Error: --install requires at least one service name."
exit 1
fi
continue ;;
--root-dir)
if [ -n "$2" ]; then ROOT_DIR="$2"; shift 2
else echo "Error: --root-dir requires a directory argument."; exit 1; fi ;;
-h|--help) show_help; exit 0 ;;
*) echo "Unknown option: $1"; show_help; exit 1 ;;
esac
done
if [ -z "$ROOT_DIR" ]; then
DEFAULT_DIR="$(dirname "$(realpath "$0" 2>/dev/null || echo "$PWD")")"
printf "Enter installation root directory [%s]: " "$DEFAULT_DIR"
read -r user_dir
ROOT_DIR="${user_dir:-$DEFAULT_DIR}"
fi
OS="$(uname -s | tr '[:upper:]' '[:lower:]')"
ARCH="$(uname -m)"
case "$ARCH" in
x86_64|amd64) ARCH="x86_64" ;;
aarch64|arm64) ARCH="aarch64" ;;
*) echo "Error: Unsupported architecture $ARCH"; exit 1 ;;
esac
echo "Detected OS: $OS | Architecture: $ARCH"
mkdir -p "$ROOT_DIR"
# ==========================================
# INSTALLATION ROUTINE
# ==========================================
if command -v apk >/dev/null 2>&1; then
# --- ALPINE LINUX NATIVE INSTALL ---
if [ "$UPDATE_ONLY" -eq 1 ] && ! command -v mitmproxy >/dev/null 2>&1; then
echo "mitmproxy is not installed. --update-only specified. Exiting."
exit 0
fi
echo "Alpine Linux detected. Installing native musl-compiled mitmproxy via apk..."
apk update -q
apk add --no-cache mitmproxy
ln -sf /usr/bin/mitmproxy "$ROOT_DIR/mitmproxy"
ln -sf /usr/bin/mitmdump "$ROOT_DIR/mitmdump"
ln -sf /usr/bin/mitmweb "$ROOT_DIR/mitmweb"
else
# --- DEBIAN/UBUNTU/FEDORA BINARY INSTALL ---
if [ "$UPDATE_ONLY" -eq 1 ] && [ ! -f "$ROOT_DIR/mitmproxy" ]; then
echo "mitmproxy is not installed in $ROOT_DIR. --update-only specified. Exiting."
exit 0
fi
if ! command -v curl >/dev/null 2>&1 || ! command -v tar >/dev/null 2>&1; then
echo "Checking/Installing required system dependencies..."
if command -v apt-get >/dev/null 2>&1; then
export DEBIAN_FRONTEND=noninteractive
apt-get update -qq && apt-get install -y -qq curl tar
elif command -v dnf >/dev/null 2>&1; then
dnf install -y -q curl tar
elif command -v yum >/dev/null 2>&1; then
yum install -y -q curl tar
elif command -v pacman >/dev/null 2>&1; then
pacman -Sy --noconfirm --noprogressbar curl tar
fi
fi
echo "Fetching the latest release version from GitHub..."
LATEST_TAG=$(curl -sI https://github.com/mitmproxy/mitmproxy/releases/latest | awk -F '/' '/^[Ll]ocation:/ {print $NF}' | tr -d '\r')
if [ -z "$LATEST_TAG" ]; then
echo "Error: Failed to determine the latest version."; exit 1
fi
VERSION="${LATEST_TAG#v}"
LATEST_URL="https://downloads.mitmproxy.org/${VERSION}/mitmproxy-${VERSION}-${OS}-${ARCH}.tar.gz"
echo "Downloading mitmproxy version $VERSION..."
if ! curl -s -f -I "$LATEST_URL" >/dev/null; then
echo "Error: The download URL is not reachable ($LATEST_URL)."; exit 1
fi
curl -L -s "$LATEST_URL" | tar -xz -C "$ROOT_DIR"
echo "Binaries extracted to: $ROOT_DIR"
fi
# ==========================================
# SERVICE CONFIGURATION ROUTINE
# ==========================================
if [ -n "$INSTALL_SERVICES" ]; then
echo "Symlinking binaries to /usr/local/bin..."
ln -sf "$ROOT_DIR/mitmproxy" /usr/local/bin/mitmproxy
ln -sf "$ROOT_DIR/mitmdump" /usr/local/bin/mitmdump
ln -sf "$ROOT_DIR/mitmweb" /usr/local/bin/mitmweb
mkdir -p /etc/mitmproxy
if [ "$AUTO_UPDATE" -eq 1 ]; then
echo "Auto-cleaning unspecified services..."
for old_svc in mitmdump mitmweb; do
if ! echo "$INSTALL_SERVICES" | grep -q "$old_svc"; then
if command -v systemctl >/dev/null 2>&1 && [ -f "/etc/systemd/system/${old_svc}.service" ]; then
systemctl stop "$old_svc" 2>/dev/null || true
systemctl disable "$old_svc" 2>/dev/null || true
rm -f "/etc/systemd/system/${old_svc}.service"
systemctl daemon-reload
echo "Removed Systemd service: $old_svc"
elif command -v rc-update >/dev/null 2>&1 && [ -f "/etc/init.d/${old_svc}" ]; then
rc-service "$old_svc" stop 2>/dev/null || true
rc-update del "$old_svc" default 2>/dev/null || true
rm -f "/etc/init.d/${old_svc}"
echo "Removed OpenRC service: $old_svc"
fi
fi
done
fi
# String to track used ports to dynamically resolve conflicts
USED_PORTS=" "
for ITEM in $INSTALL_SERVICES; do
# Parse the SVC:PORT:PASSWORD syntax using awk
SVC=$(echo "$ITEM" | awk -F: '{print $1}')
PORT=$(echo "$ITEM" | awk -F: '{print $2}')
PASSWORD=$(echo "$ITEM" | awk -F: '{for(i=3;i<=NF;i++){printf "%s%s", $i, (i==NF?"":":")}}' )
if [ -z "$PORT" ]; then PORT="8080"; fi
if [ "$SVC" != "mitmdump" ] && [ "$SVC" != "mitmweb" ]; then
echo "Warning: '$SVC' is not a standard service name. Skipping."
continue
fi
# Dynamically bump proxy port if there is a conflict with another service
ORIG_PORT=$PORT
while echo "$USED_PORTS" | grep -q " $PORT "; do
PORT=$((PORT + 1))
done
if [ "$ORIG_PORT" != "$PORT" ]; then
echo "Notice: Port conflict detected. Auto-shifted $SVC proxy port to $PORT."
fi
USED_PORTS="${USED_PORTS}${PORT} "
echo "Configuring auto-start service for $SVC on port $PORT..."
EXEC_ARGS="--set confdir=/etc/mitmproxy --set listen_port=$PORT"
if [ "$SVC" = "mitmweb" ]; then
EXEC_ARGS="$EXEC_ARGS --set web_open_browser=false --set web_host=0.0.0.0"
# Append password if one was supplied
if [ -n "$PASSWORD" ]; then
EXEC_ARGS="$EXEC_ARGS --set web_password=${PASSWORD}"
echo "Notice: Configured mitmweb with the provided password."
fi
# Dynamically bump web GUI port if it conflicts with a proxy port
WEB_PORT=8081
while echo "$USED_PORTS" | grep -q " $WEB_PORT "; do
WEB_PORT=$((WEB_PORT + 1))
done
USED_PORTS="${USED_PORTS}${WEB_PORT} "
EXEC_ARGS="$EXEC_ARGS --web-port=$WEB_PORT"
if [ "$WEB_PORT" != "8081" ]; then
echo "Notice: Shifted mitmweb GUI to port $WEB_PORT to avoid collision."
fi
fi
# Detect Systemd
if command -v systemctl >/dev/null 2>&1 && [ -d /run/systemd/system ]; then
cat <<EOF > /etc/systemd/system/${SVC}.service
[Unit]
Description=${SVC} proxy service
After=network.target
[Service]
Type=simple
ExecStart=$ROOT_DIR/$SVC $EXEC_ARGS
Restart=on-failure
User=root
LimitNOFILE=65536
[Install]
WantedBy=multi-user.target
EOF
systemctl daemon-reload
systemctl enable "$SVC"
systemctl restart "$SVC"
echo "Systemd service '$SVC' enabled and started."
# Detect OpenRC (Alpine Linux)
elif command -v rc-update >/dev/null 2>&1 && [ -d /etc/init.d ]; then
cat <<EOF > /etc/init.d/${SVC}
#!/sbin/openrc-run
name="${SVC}"
description="${SVC} proxy service"
command="$ROOT_DIR/${SVC}"
command_args="$EXEC_ARGS"
command_background="true"
pidfile="/run/\$name.pid"
output_log="/var/log/\${name}.log"
error_log="/var/log/\${name}_err.log"
depend() {
need net
}
EOF
chmod +x /etc/init.d/${SVC}
rc-update add "$SVC" default
rc-service "$SVC" restart
echo "OpenRC service '$SVC' enabled and started."
fi
done
fi
echo "Done!"
@hereisderek

hereisderek commented Aug 21, 2026 •

Copy link
Copy Markdown
Author

you can execute this script directly with the following command

curl -sL https://gist.githubusercontent.com/hereisderek/a2e7eecc1835be2d32e2b0b6f690aa6d/raw/install_mitmproxy.sh | sh -s -- --root-dir /opt/mitmproxy --install mitmdump:8080 mitmweb:8081:mysecretpassword --auto

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