The setup instructions given will work for containers as well and is by-directional you just need to tweak the proxy address. I used it with curl on my Mac OSX host, and curl inside the containers. I used it with Google Chrome on my Mac OSX host.
My method is a bit more complicated, so feel free to ask any questions.
First: I create a docker network manually. By using a “user defined network” I can avoid most of the messy exposing/mapping of ports.
docker network create br1 --attachable --driver bridge --subnet=172.28.5.0/24 --gateway=172.28.5.1
Next I start up mitmproxy:
mkdir -p ~/.mitmproxy && docker run --rm -it --network=“br1” --name=mitmproxy.test -v ~/.mitmproxy:/home/mitmproxy/.mitmproxy -p 8080:8080 mitmproxy/mitmproxy
Leave that terminal running so you can watch the traffic flow. Open a new terminal for another container:
I run a relatively simple pre-built website via docker-compose. I choose bitnami/apache:latest
Make sure to set a container name, it makes life easier:
Instead of using the docker default network, switch it to use the bridge network:
Just for fun, go ahead and expose port 443 so you can check some really cool features
Here is the real beauty of this system. Because there is an internal dns server, the mitmproxy container can locate the apache server by name, apache.test - you do not need to know what ip addresses have been assigned. And the apache server can find the mitmproxy container by name.
Go to the apache system bash shell using docker-exec. You will probably have to lookup and install networking tools like ping, curl, lynx, etc. I was aiming to verify all of this works and did not care how it worked.
From the apache system:
Following the instructions for the docker image, simply change 127.0.0.1 to mitmproxy.test and try to connect to example.com using http and https. For https experiment with using the -k flag and not using it.
Without the -k flag, curl will refuse to load the over SSL because it does not trust the mitmproxy certificate.
On your HOST system, you can run the same commands. This time you will need to use localhost:8080 as documented. Again play with the -k flag to see how your host machine will also not trust the dynamic certificate.
For extra fun, instead of example.com try connecting from your host system to apache.test . Even though your host system does not know what the ip address is for apache.test, the mitmproxy does know. It is built into the bridge network so it can be routed directly to the internal container. And again you can see how the use of the -k flag affects loading over ssl.
If you exposed and mapped port 443 from the apache.test container, add a line to your /etc/hosts file:
127.0.0.1 apache.test . Go ahead and run the https curl command again and this time include -v.
Then run it a second time, but do not include the http_proxy=… part. You will get a different certificate by connecting directly and connecting through the proxy.
Configure your normal web browser, chrome, firefox, safari, etc so that it uses 127.0.0.1, port 8080 as a proxy for both http and https traffic.
Follow the instructions to add the mitmproxy CA certificate as a trusted CA to your system.
Delete the apache.test line from your hosts file.
You can load the http version of apache.test and it goes through the proxy. You can load the https version of apache.test and not only will it load, it will not generate a certificate error. The out of the box apache server is using a self signed certificate your browser would normally complain about - but mitmproxy generates a “Valid” certificate for your browser to trust. And does not care about the “invalid” certificate installed on apache.test
This is saving me a lot of time with web development. I do not have to maintain my /etc/hosts file with a line for every local dev - as long as I give them a container name and make it look a bit like a real domain, the proxy handles mapping everything. As long as I trust the mitmproxy CA, I can use https for all the dev systems without any more headaches.