Last active
August 21, 2026 00:31
-
-
Save hereisderek/a2e7eecc1835be2d32e2b0b6f690aa6d to your computer and use it in GitHub Desktop.
mitmproxy installer script
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| #!/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!" |
Author
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
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