I seem to do a lot with Virtual Machines and this was no different. I’d started out trying to reverse engineer an otherwise undocumented section of a client for a hosting service I use and I was keen on configuring an isolated environment for it.
mitmproxy is a tool for intercepting HTTP and HTTPS traffic and then allowing you to easily inspect it. In transparent proxy mode, it can sit at the network level and intercept everything without any other configuration.
There’s a few steps to it, and it seemed worth documenting:
1. Configure Two VMs
The first thing to do is to configure two VMs. I used a Ubuntu 14.04 LTS install for the server and an Xubuntu (also 14.04 LTS) for the client. I wanted a GUI on the client (for a web browser) and I had an Xubuntu ISO lying around.
You’ll want to install the virtual machine tools, too. (boxes has a script
which might help). I named the server
proxy-server and the client
proxy-client. Otherwise they’re very standard configurations.
2. Setup the Proxy Server
The proxy server will need two network interfaces, one to the outside world
eth0) and another for clients to connect on (
You’ll need to add a second network interface to the VM itself, with the new one configured to be “internal only”. This sets up an isolated network on the host machine which the VMs are able to communicate through.
Once the virtual adaptor is added, we’ll configure that with a static IP:
# Proxy Server network interface auto eth1 iface eth1 inet static address 192.168.3.1 netmask 255.255.255.0 gateway 0.0.0.0
Then bring it up:
sudo ifup eth1. You can verify it worked by checking the
ifconfig -a. To understand what’s going on, you might find the
Ubuntu Documentation article on Network Configuration
The next step is to configure
dnsmasq to provide us with DHCP and DNS on our
internal network. First install it:
sudo apt-get install dnsmasq
# Listen for DNS requests on the internal network interface=eth1 # Act as a DHCP server, assign IP addresses to clients dhcp-range=192.168.3.10,192.168.3.100,96h # Broadcast gateway and dns server information dhcp-option=option:router,192.168.3.1 dhcp-option=option:dns-server,192.168.3.1
The final step is to configure
iptables to forward incoming traffic on ports
80 and 443 to our
iptables -t nat -A PREROUTING -i eth1 -p tcp --dport 80 \ -j REDIRECT --to-port 8080 iptables -t nat -A PREROUTING -i eth1 -p tcp --dport 443 \ -j REDIRECT --to-port 8080
Then we can install and open
mitmproxy in transparent mode:
$ mitmproxy -T --host
-T enables transparent proxy mode,
--host infers the hostname of the
request and displays that instead of the IP.)
3. Configure the Client
The client will need pointing to the correct network, and then the
certificates installed. Technically, installing the root CA for
optional, but without it you’ll get a lot of SSL warnings you need to jump
First, the network:
- Reconfigure the client’s network adaptor to be “internal only”.
- Set the network configuration to look like (through either the GUI or a similar method to above):
Address: 192.168.3.10 Subnet: 255.255.255.0 Gateway: 192.168.3.1 DNS: 192.168.3.1
You’ll then want to test it all works. A non-HTTPS web page is likely the easiest.
Finally, add the generated
mitmproxy CA root certificate.
generates these on first run, so you’ll want to take these from the
~/.mitmproxy directory on the host. You’re looking for
Take this from the proxy server and place it on the client. You’ll then want to make the certificate known to the OS:
sudo mitmproxy-ca-cert.cer /usr/local/share/ca-certificates/mitmproxy-ca-cert.crt sudo update-ca-certifcates
(Note, as part of this, it’s renamed to have more usual
crt extension, which
update-certificates will pick up.)
In the response you should see that a certificate was added. You can test this
all worked by doing something like:
wget https://nickcharlton.net. The
response should show up in your
Firefox maintains it’s own certificate store and so you’ll want to add this in
in Preferences → Advanced → Certificates. Just add the
file as an authority.
4. Begin Making Requests
You’ll now be able to make requests, both through a terminal or in a browser.
wget https://nickcharlton.net should give you something that
looks like the next two screenshots:
Some of the details of this post comes from the
documentation, but threaded out with a bit more detail that I’d needed
to understand to get it all working. Now hopefully you’ll be able to replicate
a similar setup.