Arman Bimatov
Arman Bimatov

Reputation: 1829

How to use NGINX as forward proxy for any requested location?

I am trying to configure NGINX as a forward proxy to replace Fiddler which we are using as a forward proxy. The feature of Fiddler that we use allows us to proxy ALL incoming request to a 8888 port. How do I do that with NGINX?

In all examples of NGINX as a reverse proxy I see proxy_pass always defined to a specific upstream/proxied server. How can I configure it so it goes to the requested server, regardless of the server in the same way I am using Fiddler as a forward proxy.

Example:

In my code:

WebProxy proxyObject = new WebProxy("http://mynginxproxyserver:8888/",true);
WebRequest req = WebRequest.Create("http://www.contoso.com");
req.Proxy = proxyObject;

In mynginxproxyserver/nginx.conf I do not want to delegate the proxying to another server (e.g. proxy_pass set to http://someotherproxyserver). Instead I want it to just be a proxy server, and redirect requests from my client (see above) to the request host. That's what Fiddler does when you enable it as a proxy: http://docs.telerik.com/fiddler/Configure-Fiddler/Tasks/UseFiddlerAsReverseProxy

Upvotes: 37

Views: 127925

Answers (3)

Hairy Ass
Hairy Ass

Reputation: 338

To use nginx as forward proxy for https Need to install proxy_connect

cd /tmp
wget https://nginx.org/download/nginx-1.20.2.tar.gz
tar xzvf nginx-1.20.2.tar.gz

git clone https://github.com/chobits/ngx_http_proxy_connect_module

cd nginx-1.20.2/
patch -p1 < ../ngx_http_proxy_connect_module-master/patch/proxy_connect_rewrite_1018.patch

./configure --add-module=../ngx_http_proxy_connect_module-master --prefix=/usr
make 
sudo make install

Then edit the nginx.conf

nano /usr/conf/nginx.conf
http {
 server {
     listen                         3128;

     # dns resolver used by forward proxying
     resolver                       8.8.8.8;

     # forward proxy for CONNECT request
     proxy_connect;
     proxy_connect_allow            443 563;
     proxy_connect_connect_timeout  10s;
     proxy_connect_data_timeout     10s;

     # forward proxy for non-CONNECT request
     location / {
         proxy_pass http://$host;
         proxy_set_header Host $host;
     }
 }
}

Upvotes: 4

David Asher
David Asher

Reputation: 162

You can run into url encoding problems when using the $uri variable as suggested by Grumpy, since it is decoded automatically by nginx. I'd suggest you modify the proxy pass line to

proxy_pass http://$http_host$request_uri;

The variable $request_uri leaves the encoding in tact and also contains all query parameters.

Upvotes: 11

Grumpy
Grumpy

Reputation: 1478

Your code appears to be using a forward proxy (often just "proxy"), not reverse proxy and they operate quite differently. Reverse proxy is for server end and something client doesn't really see or think about. It's to retrieve content from the backend servers and hand to the client. Forward proxy is something the client sets up in order to connect to rest of the internet. In turn, the server may potentially know nothing about your forward proxy.

fwd vs rev proxy

Nginx is originally designed to be a reverse proxy, and not a forward proxy. But it can still be used as a forward one. That's why you probably couldn't find much configuration for it.

This is more a theory answer as I've never done this myself, but a configuration like following should work.

server {
    listen       8888;

    location / {
        resolver 8.8.8.8; # may or may not be necessary.
        proxy_pass http://$http_host$uri$is_args$args;
    }
}

This is just the important bits, you'll need to configure the rest.

The idea is that the proxy_pass will pass to a variable host rather than a predefined one. So if you request http://example.com/foo?bar, your http header will include host of example.com. This will make your proxy_pass retrieve data from http://example.com/foo?bar.

The document that you linked is using it as a reverse proxy. It would be equivalent to

        proxy_pass http://localhost:80;

Upvotes: 70

Related Questions