diff --git a/doc-src/modes.html b/doc-src/modes.html
index 77bd1b056..b78fe3c09 100644
--- a/doc-src/modes.html
+++ b/doc-src/modes.html
@@ -1,210 +1,222 @@
-Mitmproxy comes with several modes of operation, which allow you to use mitmproxy in a variety of scenarios.
-This documents briefly explains each mode and possible setups.
-
-Mitmproxy has four modes of operation:
-
- - Regular Mode (this is what you get by default)
- - Transparent Mode
- - Reverse Proxy Mode
- - Upstream Proxy Mode
-
-Now, which one should you pick? Use this flow chart:
-
+Mitmproxy has four modes of operation that allow you to use mitmproxy in a
+variety of scenarios:
-
+- **Regular** (the default)
+- **Transparent**
+- **Reverse Proxy**
+- **Upstream Proxy**
+
+Now, which one should you pick? Use this flow chart:
+
+
-Mitmproxy's regular mode it the most simple one and the easiest to set up.
+Mitmproxy's regular mode is the simplest and the easiest to set up.
-
- - Start mitmproxy.
- - Configure your client to use mitmproxy. This means that you either adjust the proxy setting of your local browser
- or point an external device to your proxy (which should look like
- this).
- - Quick Check: You can already visit an unencrypted HTTP site over the proxy.
- - Open the magic domain mitm.it and install the certificate for your device.
-
+1. Start mitmproxy.
+2. Configure your client to use mitmproxy. For instance on IOS, the settings might look like this.
+3. Quick Check: You should already be able to visit an unencrypted HTTP site
+through the proxy.
+4. Open the magic domain mitm.it and install the certificate for your device.
- Heads Up: Unfortunately, some applications prefer to bypass the HTTP proxy settings of the system -
- Android applications are a common example. In these cases, you need to use mitmproxy's transparent mode.
+Heads Up: Unfortunately, some applications bypass the
+system HTTP proxy settings - Android applications are a common example. In
+these cases, you need to use mitmproxy's transparent mode.
-If you are proxying an external device, your network will probably look like this:
+If you are proxying an external device, your network will probably look like this:
+
-
-The square brackets signify the source and destination IP addresses. Your client explicitly connects
- to mitmproxy and mitmproxy explicitly connects to the target server.
-
+
+The square brackets signify the source and destination IP addresses. Your
+client explicitly connects to mitmproxy and mitmproxy explicitly connects
+to the target server.
-When a transparent proxy is used, traffic is redirected into a proxy at the network layer, without any client
-configuration being required. This makes transparent proxying ideal for those situations where you can't change client
-behaviour. The basic principle is that mitmproxy sits somewhere on the line from the client to the internet and
-transparently intercepts the request. In the graphic below, a machine running mitmproxy has been inserted between
-the router and the internet:
+In transparent mode, traffic is directed into a proxy at the network layer,
+without any client configuration required. This makes transparent proxying
+ideal for situations where you can't change client behaviour. In the graphic
+below, a machine running mitmproxy has been inserted between the router and
+the internet:
-
-The square brackets signify the source and destination IP addresses. Round brackets mark the next
- hop on the Ethernet/data link layer. This distinction is important to make: When the packet arrives
- at the mitmproxy machine, it must still be addressed to the target server. In other words: A simple IP redirect on
- the router does not work - this would remove the target information, leaving mitmproxy unable to
- determine the real destination.
-
+
+
+
+The square brackets signify the source and destination IP addresses. Round
+brackets mark the next hop on the *Ethernet/data link* layer. This distinction
+is important: when the packet arrives at the mitmproxy machine, it must still
+be addressed to the target server. This means that Network Address Translation
+should not be applied before the traffic reaches mitmproxy, since this would
+remove the target information, leaving mitmproxy unable to determine the real
+destination.
+
Common Configurations
-The first graphic is a little bit idealistic: Usually, you'll have your local wireless lan network and no
-machines between your router and the internet. Fortunately, there are other ways to configure your network:
-(a) Configuring the client to use a custom gateway/router/"next hop", (b) Implementing custom routing on the router
-or (c) setting up a separate wireless network router which gets proxied.
-There are of course other options, but we'll look at these three. In most cases, setting (a) is recommended due to its
-ease of use.
+There are many ways to configure your network for transparent proxying. We'll
+look at three common scenarios:
+
+1. Configuring the client to use a custom gateway/router/"next hop"
+2. Implementing custom routing on the router
+
+In most cases, the first option is recommended due to its ease of use.
(a) Custom Gateway
-Looking at your local home network, it's clear what happens if you enter "example.com" into your address bar: After you
-press enter, your OS sends a packet to your router, which then sends this to your ISP, which then sends it to some
-Tier-1 carrier, which then sends it... I think you get the idea. The important part for us is the first step here:
-Your machine is configured to use your router as the next hop. Your router certainly doesn't host example.com, but your
-machine knows that your router will forward it upstream. On the technical level, your router probably provides a DHCP
-server, which instructs all clients to use his address as the Default Gateway for connections that leave the
-current subnet (your local network).
-
-How does this help us? Here comes our trick: By configuring the client to use our machine as its Gateway, all traffic
-will be sent to our machine, which then forwards it to the router. This provides us with the scenario we'd like to have,
-namely packets on our doorstep that are addressed for someone else:
-
+One simple way to get traffic to the mitmproxy machine with the destination IP
+intact, is to simply configure the client with the mitmproxy box as the
+default gateway.
+
-Given this concept, we can set up mitmproxy:
-
- - Configure your proxy machine for transparent mode.
You can find instructions
- in the Transparent Proxying section of the mitmproxy docs.
- - Configure your client to use your proxy machine's IP as the default gateway. This setting is usually called
- Standard Gateway, Router or something along these lines
- (iOS screenshot).
- - Quick Check: You can already visit an unencrypted HTTP site over the proxy.
- - Open the magic domain mitm.it and install the certificate for your device.
-
+In this scenario, we would:
+
+- Configure the proxy machine for transparent mode. You can find instructions
+in the Transparent Proxying section of the mitmproxy docs.
+
+- Configure the client to use the proxy machine's IP as the default gateway.
+Here is what this would
+look like on IOS.
+
+- Quick Check: At this point, you should already be able to visit an
+unencrypted HTTP site over the proxy.
+
+- Open the magic domain mitm.it and install the certificate
+for your device.
+
+Setting the custom gateway on clients can be automated by serving the settings
+out to clients over DHCP. This lets set up an interception network where all
+clients are proxied automatically, which can save time and effort.
+
Troubleshooting Transparent Mode
-
Wrong transparent mode configurations are a frequent source of
+
+
Incorrect transparent mode configurations are a frequent source of
error. If it doesn't work for you, try the following things:
+
- - Open mitmproxy's event log (press `e`) - can you spot clientconnect messages?
- If not, the packets are not arriving at the proxy. A common source is the occurence of ICMP redirects,
- which means that your machine is telling the client that there's a faster way to the internet by contacting
- your router directly (see the Transparent Proxying section on how to disable them). If in doubt,
- Wireshark may help you to see whether something arrives at your machine
- or not.
+
-
+ Open mitmproxy's event log (press `e`) - do you see clientconnect
+ messages? If not, the packets are not arriving at the proxy. One common
+ cause is the occurrence of ICMP redirects, which means that your
+ machine is telling the client that there's a faster way to the
+ internet by contacting your router directly (see the
+ Transparent Proxying section on how to disable them). If in
+ doubt, Wireshark may help you
+ to see whether something arrives at your machine or not.
-
- Have you explicitly configured an HTTP proxy on your device? You do not need mitmproxy's transparent mode
- then, just start mitmproxy normally. Explicitly setting a proxy and transparent mode contradict each other,
- settle for one. Do not explicitly redirect traffic to mitmproxy anywhere except for the Gateway setting.
+ Make sure you have not explicitly configured an HTTP proxy on the
+ client. This is not needed in transparent mode.
-
Re-check the instructions in the Transparent Proxying section. Anything you missed?
+
If you encounter any other pitfalls that should be listed here, please let us know!
+
(b) Custom Routing
-Custom routing is a fairly advanced setup which we'll only document briefly here.
-First and foremost, it usually requires root on your router. The basic idea is to teach your router a custom routing
-table that says "for requests from ip X, the proxy machine is the next gateway".
+In some cases, you may need more fine-grained control of which traffic reaches
+the mitmproxy instance, and which doesn't. You may, for instance, choose only
+to divert traffic to some hosts into the transparent proxy. There are a huge
+number of ways to accomplish this, and much will depend on the router or
+packet filter you're using. In most cases, the configuration will look like
+this:
-
-
-For this setup, we expect you to have a basic understanding of networking in general. In short, you should get started
-with these routing commands. The Troubleshooting part directly above this
-section might be helpful for you as well.
-
-(c) Separate Network
-
-Setting up a separate network using a cheap router might be a viable option, too. Such a configuration mostly resembles
-the idealistic graphic from the beginning (Variant 1). Take a look at the
-Transparently proxify virtual machines tutorial to see how
-such a network could be implemented. The troubleshooting section for custom gateways may be helpful for you, too.
+
+
-Mitmproxy is usually used with a client that uses the proxy to access the Internet. Using reverse proxy mode, you can
-use mitmproxy to represent a server:
+Mitmproxy is usually used with a client that uses the proxy to access the
+Internet. Using reverse proxy mode, you can use mitmproxy to act like a normal
+HTTP server:
-
+
+
There are various use-cases:
-
--
- Say you have an internal API running at http://example.local/. You could now setup mitmproxy in
- reverse proxy mode at http://debug.example.local/ and dynamically point clients to this new API endpoint,
- which provides clients with the same data and you with debug information. Similarly, you could move your real server
- to a different ip/port and setup mitmproxy at the original place to debug all sessions.
-
--
- Say you're a web developer working on example.com (with a development version running on localhost:8000).
- You can modify your hosts file so that example.com points to 127.0.0.1 and then run mitmproxy in reverse proxy
- mode on port 80. You can test your app on the example.com domain and get all requests recorded in mitmproxy.
-
--
- Say you have some toy project that should get SSL support. Simply setup mitmproxy with SSL termination and you're
- done (
mitmdump -p 443 -R https2http://localhost:80/
). There are better tools for this specific task (we don't
- have C performance obviously), but it's definitely a nice and very quick way to setup an SSL-speaking server.
-
--
- Want to add a non-SSL-capable compression proxy in front of your server? You could even spawn a mitmproxy instance
- that terminates SSL (https2http://...), point it to the compression proxy and let the compression proxy point
- to a SSL-initiating mitmproxy (http2https://...), which then points to the real server. As you see, it's a fairly
- flexible thing.
-
-
-
-Please note that cloning Google by using mitmproxy -R http://google.com/
does not really work
-(as in this screenshot).
-This may work for the first request, but the HTML remains unchanged: As soon as the user clicks on an non-relative URL
-(or downloads a non-relative image resource), they speak with Google directly again.
-
-
- On another note, mitmproxy either supports an HTTP or an HTTPS upstream server, not both at the same time. You can
- simply work around this by spawning a second mitmproxy instance. Each instance listens to one port and talks to one
- port.
-
+- Say you have an internal API running at http://example.local/. You could now
+set up mitmproxy in reverse proxy mode at http://debug.example.local/ and
+dynamically point clients to this new API endpoint, which provides clients
+with the same data and you with debug information. Similarly, you could move
+your real server to a different IP/port and set up mitmproxy at the original
+place to debug all sessions.
+
+- Say you're a web developer working on example.com (with a development
+version running on localhost:8000). You can modify your hosts file so that
+example.com points to 127.0.0.1 and then run mitmproxy in reverse proxy mode
+on port 80. You can test your app on the example.com domain and get all
+requests recorded in mitmproxy.
+
+- Say you have some toy project that should get SSL support. Simply set up
+mitmproxy with SSL termination and you're done (mitmdump -p 443 -R
+https2http://localhost:80/
). There are better tools for this specific
+task, but mitmproxy is very quick and simple way to set up an SSL-speaking
+server.
+
+- Want to add a non-SSL-capable compression proxy in front of your server? You
+could even spawn a mitmproxy instance that terminates SSL (https2http://...),
+point it to the compression proxy and let the compression proxy point to a
+SSL-initiating mitmproxy (http2https://...), which then points to the real
+server. As you see, it's a fairly flexible thing.
+
+Note that mitmproxy supports either an HTTP or an HTTPS upstream server, not
+both at the same time. You can work around this by spawning a second mitmproxy
+instance.
+
+
+ Caveat: Interactive Use
+
+
+One caveat is that reverse proxy mode is often not sufficient for interactive
+browsing. Consider trying to clone Google by using:
+
+mitmproxy -R http://google.com/
+
+This works for the initial request, but the HTML served to the client remains
+unchanged. As soon as the user clicks on an non-relative URL (or downloads a
+non-relative image resource), traffic no longer passes through mitmproxy, and
+the client connects to Google directly again.
+
+
+
+
-
-If you want to add mitmproxy in front of a different proxy appliance, you can use mitmproxy's upstream mode.
-In upstream mode, all requests are unconditionally transferred to an upstream proxy or your choice.
-
+If you want to chain proxies by adding mitmproxy in front of a different proxy
+appliance, you can use mitmproxy's upstream mode. In upstream mode, all
+requests are unconditionally transferred to an upstream proxy or your choice.
-
-mitmproxy supports both explicit HTTP and explicit HTTPS in upstream proxy mode. You could in theory chain multiple
-mitmproxy instances in a row, but that doesn't make any sense in practice (i.e. outside of our tests).
-
\ No newline at end of file
+mitmproxy supports both explicit HTTP and explicit HTTPS in upstream proxy
+mode. You could in theory chain multiple mitmproxy instances in a row, but
+that doesn't make any sense in practice (i.e. outside of our tests).