There are hundreds of sites that proxy their nginx. In each server section, a file is connected, so that you can quickly register configs for everyone at once.

Until now, I registered various conditions, everything was fine until I came across location and proxy_pass.

The fact is that proxy_pass requires to register a backend. In my case, hundreds of sites have different backends in the form of IP addresses. These IPs, for example, coincide with the listens in the server section. If the value of proxy_pass does not match the listen, then it returns 404 for the specified location.

How can I automatically determine the backend corresponding to the site? Maybe somehow you can pull the IP value out of listen?

Here is the code that includes each site:

location ~ ^/(wp-admin|wp-login\.php|admin|administrator) { limit_req zone=wp burst=4 nodelay; proxy_pass http://IP:81; proxy_redirect http://IP/ /; proxy_set_header Host $host; proxy_set_header Host $host; proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for; proxy_set_header X-Forwarded-Proto $scheme; proxy_set_header X-Real-IP $remote_addr; } 

    2 answers 2

    There is no way to copy the value - generate this config file with a script.

    Common to all server lines of configs can be put in one separate file common_proxy.conf :

    site_N.conf:

     listen 123.123.123.123:80; ... location ~ ^/(wp-admin|wp-login\.php|admin|administrator) { proxy_pass http://123.123.123.123; proxy_redirect http://IP/ /; include common_proxy.conf } 

    common_proxy.conf:

     limit_req zone=wp burst=4 nodelay; proxy_set_header Host $host; proxy_set_header Host $host; proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for; proxy_set_header X-Forwarded-Proto $scheme; proxy_set_header X-Real-IP $remote_addr; 
    • the value of proxy_pass will have to be determined again somehow ... or I did not understand you ... of course you can try to make a script, but for now I would like to search for a solution without this - Alexey Sekretny
    • proxy_pass will proxy_pass to be registered in the config of each server - in the same place as listen . But it remains possible to change everything at once, say, limit_req - it is one for all of one common file. But the IP address will have to register twice. I have not found the nginx variables that are suitable for the solution you want. - Sergiks
    • @Sergiks, tested, I have a variable declaration in the server section, using its value in the included file. see my answer. - aleksandr barakin

    Checked on nginx version 1.4.6 .

    created two server sections listening to different ip-addresses:

     server { listen 127.0.0.1:8001; set $pp "127.0.0.1"; include test.conf; } server { listen 127.0.0.2:8001; set $pp "127.0.0.2"; include test.conf; } 

    the contents of test.conf :

     location / { proxy_pass http://$pp:9001; } 

    in two separate instances of the shell, it launched processes that listened to the necessary ip-addresses and ports:

    1. $ nc -l 127.0.0.1 9001
    2. $ nc -l 127.0.0.2 9001

    restarted nginx , made two requests (since I did not set a timeout, I had to “kill” them by pressing ctrl + c ):

    1. $ wget -qO - http://127.0.0.1:8001/
    2. $ wget -qO - http://127.0.0.2:8001/

    nc processes showed expected information:

    1. the one that listened to the address 127.0.0.1 :

       GET / HTTP/1.0 Host: 127.0.0.1:9001 Connection: close User-Agent: Wget/1.15 (linux-gnu) Accept: */* 
    2. the one that listened to the address 127.0.0.2 :

       GET / HTTP/1.0 Host: 127.0.0.2:9001 Connection: close User-Agent: Wget/1.15 (linux-gnu) Accept: */* 

    that is, it is quite possible to use something like the following:

    1. in the server section, assign the desired value to some variable. if it is not a number, but a string, for example, ip-address, it should be enclosed in quotes. eg:

       set $some_var = "1.2.3.4"; 
    2. in the included file, substitute the name of this variable in the required place. eg:

       proxy_pass http://$some_var:81; 

    and, alas, no any internal variable containing the address to which the request occurred, in the nginx documentation .

    • You also need to prescribe an IP address twice in each config: in the listen and assign it to a variable (I have the 2nd time directly in the proxy_pass directive). It is better to generate config files with some kind of script. I would do that. Ps +1 for a detailed study of the issue and experiment. pps nginx time to upgrade. - Sergiks
    • 1. once: set v="1.2.3.4"; listen $v:81; set v="1.2.3.4"; listen $v:81; (corrected the answer) 2. update is not required. This machine performs completely different tasks, and nginx is exclusively for (my) tests. - aleksandr barakin
    • @Sergiks, rolled back while editing, because listen for some reason did not want to accept a variable. I'm testing more. - aleksandr barakin
    • @Sergiks, in the listen directive does not want to perceive variables. Yes, I agree, then you have to mention the ip-address twice. - aleksandr barakin