Skip to content

Instantly share code, notes, and snippets.

@reegnz
Last active October 22, 2021 13:28
Show Gist options
  • Save reegnz/3d3b8a742b498dfa7f1b7ad3de1a5969 to your computer and use it in GitHub Desktop.
Save reegnz/3d3b8a742b498dfa7f1b7ad3de1a5969 to your computer and use it in GitHub Desktop.
mitmproxy on MacOS with Keychain integration

mitmproxy on MacOS with Keychain integration

Root certificate generation

You need to get a root certificate in place for mitmproxy. The easy way to do that is to just run mitmproxy and exit. The certificate can then be found at ~/.mitmproxy/mitmproxy-ca.pem.

Putting the root certificate into the MacOS Keychain

After having generated the certificate you can import it into MacOS keychain and then syncing the Keychain with the openssl cert.pem

You can do that by running ./install-cert.sh that is found in this gist.

Now you can launch mitmproxy in one terminal. Opening up another terminal set the appropriate proxy and CA_CERT environment variables with eval "$(./mitmproxy-env.sh)"

Now running a command you will see the requests the command is making in the mitmproxy tui.

Have browsers pick up the Keychain certificates

  • Chrome: automatically picks up certificates from the MacOS keychain.
  • Firefox: accoring to the support docs you need to set security.enterprise_roots.enabled=true in about:config
    • you can also do it with enterprise policies:
      mkdir /Applications/Firefox.app/Contents/Resources/distribution
      jq --null-input '.policies.Certificates.ImportEnterpriseRoots |= true' > /Applications/Firefox.app/Contents/Resources/distribution/policies.json
      
#!/usr/bin/env bash
keychain=/Library/Keychains/System.keychain
ca_cert="$HOME/.mitmproxy/mitmproxy-ca-cert.pem"
if security find-certificate -c mitmproxy -p "$keychain" &>/dev/null; then
sudo security delete-certificate -c mitmproxy "$keychain"
echo "mitmproxy certificate removed from Keychain." >&2
fi
sudo security add-trusted-cert -d -p ssl -p basic -k "$keychain" "$ca_cert"
echo "mitmproxy certificate added to keychain." >&2
if ! which brew &>/dev/null; then
echo "Homebrew not found. Exiting." >&2
exit 1
fi
if ! brew ls --versions openssl@1.1 &>/dev/null; then
echo "Openssl is missing. Exiting." >&2
exit 1
fi
brew postinstall openssl
OPENSSL="$(brew ls openssl@1.1 | grep bin/openssl)"
cert_file="$("$OPENSSL" version -d | cut -d'"' -f2)/cert.pem"
echo "Certificates in Keychain synced to $cert_file" >&2
#!/bin/sh
cert_file="$($(brew ls openssl@1.1 | grep bin/openssl) version -d | cut -d'"' -f2)/cert.pem"
cat <<EOF
# Generic
export HTTP_PROXY="http://127.0.0.1:8080"
export HTTPS_PROXY="http://127.0.0.1:8080"
# JAVA
# Java doesn't respect the HTTP_PROXY and HTTPS_PROXY environment variables, but it is
# still possible to have it use a proxy.
# It is also possible for java to use the MacOS Keychain directly.
export JAVA_TOOL_OPTIONS="-Djavax.net.ssl.trustStoreType=KeychainStore"
export JAVA_TOOL_OPTIONS="$JAVA_TOOL_OPTIONS -Dhttp.proxyHost=localhost -Dhttp.proxyPort=8080"
export JAVA_TOOL_OPTIONS="$JAVA_TOOL_OPTIONS -Dhttps.proxyHost=localhost -Dhttps.proxyPort=8080"
# For tools not using Keychain
# The python requests library doesn't respect the Keychain, so
# you need to have it using openssl cert.pem bundle instead.
export REQUESTS_CA_BUNDLE="$cert_file"
# AWS CLI also doesn't use the keychain so have it use openssl certs.pem instead.
export AWS_CA_BUNDLE="$cert_file"
EOF
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment