Could mitmproxy be used for reverse proxy for multi sites?


I saw mitmproxy could be used as reverse proxy for one single site using the following command:

mitmproxy -R -p 80

But I’m not sure could this be used for multi site in one command. For example, I want it as reverse proxy for and and, but when I read the docs, it says: only one site could be used one time.

So, may I do this by the script of mitmproxy?

Thanks very much.


You can re-route requests to different servers in reverse proxy mode. That being said, most of the time you probably want to run mitmproxy as a regular proxy then. If you are unsure, please take a look at :slight_smile:

If you know what you are doing and you still want to run as a reverse proxy, take a look at this:


Hi, Hils.

Thanks for your reply.

The reason I use reverse proxy is that suppose Evil and Victim is in under same route, Evil is able to change the DNS setting of the route. So, Victim got the wrong DNS result of some website like * point to the same IP: Evil’s IP.

So now it’s turn of mitmproxy. I want mitmproxy serve as a website which could response the request of,, and so on. So I think I should use reverse proxy mode as the other modes could not act as a webserver. But I’m not sure whether I am understanding correctly.


The command I run is:

mitmdump -R -p 80 -s

I run it on my computer for experiment. And I set the DNS on my computer:

Then I just visit on my computer, and I was getting the result of

What I want is I visit, mitmproxy give me the result of And when I visit, mitmproxy give me the result of

I tried and found that when I was visiting, the script shows that in request flow.request.pretty_host is not but in the command line.

I tried read the source and found in mitmproxy\protocol\

        # update host header in reverse proxy mode
        if self.config.options.mode == "reverse":
            if six.PY2:
                flow.request.headers["Host"] =
                flow.request.headers["Host"] =
        # set upstream auth
        if self.mode == "upstream" and self.config.upstream_auth is not None:
            flow.request.headers["Proxy-Authorization"] = self.config.upstream_auth

This means before process_request_hook, the host in header was replace by which is So I don’t think the script will work.

So, could I read the raw header in request stub in scripting? So I can replace the host header correctly. I didn’t found a proper way to do this. I’m not sure if flow.client_conn could be used for this.

Thanks very much!


hello @mhils could you help to have a look?

Thanks very much.


Thanks for investigating this. You should still be able to see the original header in requestheaders instead of request. If that’s the case, I’d be more than happy if you could send a quick PR that fixes the example!



Sorry for the late reply.

I searched “requestheaders” in mitmproxy, found the following:

Occurrences of ‘requestheaders’ in Directory Lib\site-packages\mitmproxy with mask '*.py’
yield “requestheaders”, f
def requestheaders(self, f):
Lib\site-packages\mitmproxy\protocol\“requestheaders”, flow)

But requestheaders could not be visited in the context of request function in my custom script.

So is there another way to find the raw header from client in the context of request function?

My script is very simple and looks just like this:

def request(flow):


hello @mhils could you please have a look? Thanks very much.


Hello, is now fixed on mitmproxy master branch :sunglasses: