Nginx limit_req simply doesn't work (rate limiting) - nginx

I have a very simple nginx.conf nginx configuration to test Nginx limit_req rate limiting,
here the below is the part of the config,
limit_req_zone $binary_remote_addr zone=req_zone:10m rate=1r/s;
server {
listen 8012;
location / {
limit_req zone=req_zone burst=2 nodelay;
proxy_pass "http://127.0.0.1:3001";
proxy_http_version 1.1;
proxy_set_header Upgrade $http_upgrade;
proxy_set_header Connection "upgrade";
}
location ^~ /api/ {
limit_req zone=req_zone burst=1 nodelay;
proxy_pass "http://127.0.0.1:8000";
}
location ^~ /accounts/ { proxy_pass "http://127.0.0.1:8000"; }
location ^~ /comments/ { proxy_pass "http://127.0.0.1:8000"; }
location = /api/ { return 401; }
location = /api/comments/ { return 401; }
}
Then open up http://localhost:8012/, trying a many set of requests through chrome dev console. i.e. I run the below like 10 times a second
axios.get('/api/comments/22')
But nothing happens, no 503 error, just succeeds to get the response.
Since the setup is pretty simple, I have really no idea what's missing (or a nginx bug?) here. Thanks for your help.

Related

When using Nginx reverse proxy, how can I set IP whitelist based on request URI parameter?

My url like this:
http://myserver/app/inf?ConId=Obj%3Acom.aaa.bbb%3A3712 # Only IP in whitelist can access
http://myserver/app/...... # all user can access
When the parameter of ConId is Obj%3Acom.aaa.bbb%3A3712, I need to restrict only specific IP can access my server.
I tried the following Nginx configuration but not working.
location / {
if ( $arg_ConId = "Obj%3Acom.aaa.bbb%3A3712" ) {
allow 192.168.1.104;
deny all;
}
proxy_pass http://192.168.234.130:80;
add_header Access-Control-Allow-Origin *;
proxy_set_header Host $host;
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
proxy_http_version 1.1;
allow all;
}
Please help, thanks!
Thanks #araisch,my final working Nginx Configuration is:
worker_processes 1;
events {
worker_connections 1024;
}
http {
include mime.types;
default_type application/octet-stream;
sendfile on;
#keepalive_timeout 0;
keepalive_timeout 65;
server {
listen 80;
server_name localhost;
error_page 403 /403.html;
location = /403.html {
root html;
}
if ($arg_ConId = "Obj%3Acom.aaa.bbb%3A3712") {
set $BLOCKING A;
}
if ($remote_addr != "192.168.3.11") {
set $BLOCKING "${BLOCKING}B";
}
if ($BLOCKING = AB) {
return 403;
break;
}
location / {
proxy_pass http://192.168.234.130:80;
add_header Access-Control-Allow-Origin *;
proxy_set_header Host $host;
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
proxy_http_version 1.1;
allow all;
}
}
}
Could use something like:
if ($arg_ConId = "Obj%3Acom.aaa.bbb%3A3712") {
set $BLOCKING A;
}
if ($remote_addr != 192.168.1.104) {
set $BLOCKING "${BLOCKING}B";
}
if ($BLOCKING = AB) {
return 403;
break;
}
in server block.
Problems in your code:
if Directives in location are considered as evil due to nginx` strange declaration rules. They're doing most of the time strange things, so try to avoid it.
$arg_ContainerOID does not catch an argument named "ConId"
Remark: This is not working in dockerized nginx in bridge mode, because the real IP is masked by the firewall.
You can use something like this:
location / {
auth_request /auth-here;
}
location /auth-here {
internal;
proxy_pass http://192.168.234.130:80/auth.php;
proxy_pass_request_body off;
proxy_set_header Content-Length "";
proxy_set_header X-Original-URI $request_uri;
}
Then in your script you can check $_SERVER['HTTP_X_ORIGINAL_URI'] and return HTTP 200 to allow the request or HTTP 403 to deny the request.
You will need the http_auth_request_module for the above to work, as explained in the documentation.

Nginx looking for files instead of URI when proxying

I'm trying to setup nginx as reverse proxy.
When I using just this simple config, all works well.
location / {
proxy_pass https://domain.name;
proxy_ssl_server_name on;
}
But in my case I have a legacy API and a lot of conditions, and when I using more complex prefix, regex or exact match in case, when my URI looks like this one:
/v1/Server.ashx?parameter=value
nginx looking for file Server.ashx in default root folder "/usr/share/nginx/html/v1/Server.ashx" instead of proxying, and returns 404.
How can I fix this problem?
In my case, this approach helped.
Open for any other advices.
server{
listen 8111;
server_name 192.168.137.43;
location /v1/Server.ashx {
error_page 418 = #specificpage;
error_page 419 = #websocket;
if ($query_string = "parameter=value") {
return 418;
}
if ($query_string = "") {
return 419;
}
if ($query_string = "otherparameter=othervalue") {
return 419;
}
proxy_pass https://domain.name;
proxy_ssl_server_name on;
}
location / {
error_page 419 = #websocket;
if ($request_uri = "/v2") {
return 419;
}
if ($request_uri = "/v2?parameter=value") {
return 419;
}
proxy_pass https://domain.name;
proxy_ssl_server_name on;
}
location #specificpage {
proxy_pass https://other.domain.name;
proxy_ssl_server_name on;
}
location #websocket {
proxy_pass http://domain.name;
proxy_set_header Upgrade $http_upgrade;
proxy_set_header Connection "upgrade";
proxy_set_header Host $host;
}
}

nginx redirect different roots to different ports

After hours of checking documents and stackoverflow, I still cannot figure out how to do this.
this is my nginx.conf:
http {
upstream backend {
least_conn;
server 192.168.77.81:8078 weight=4;
server 192.168.77.231:8078 weight=7 max_fails=1 fail_timeout=1s;
}
upstream static_backend {
server 192.168.77.81:8079;
}
server {
listen 8068;
access_log off;
error_log off;
location / {
proxy_pass http://backend;
proxy_set_header Host $host;
proxy_set_header X-Real-IP $remote_addr;
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
}
location /static/ {
proxy_pass http://192.168.77.81:8079;
}
}
}
events {}
I want to redirect all the http://192.168.77.81:8068/static to http://192.168.77.81:8079/static
but it all results in either 301 Moved Permanently or http://192.168.77.81:8078/static
which drive me crazy
I also have tried alias and root, and they don't work as well
any advice would be very appreciated!
simply just do proxy_pass ~ /static
this "~" took me hours...

nginx reverse proxy "catch-all" location

EDIT: To be more clear, this is nginx version 1.13.8.
Take the following as an example nginx.conf file:
http {
upstream portal_backend {
server pc-loc43-01:15080;
}
upstream auth_backend {
server pc-loc43-01:16080;
}
server {
listen 9080 default_server;
server_name my-reverse-proxy;
location / {
auth_basic off;
proxy_http_version 1.1;
proxy_set_header Host $http_host;
proxy_pass http://portal_backend/;
}
location /auth {
auth_basic off;
proxy_http_version 1.1;
proxy_set_header Host $http_host;
proxy_pass http://auth_backend/auth;
}
}
}
I want to configure nginx to default to location / if it is unable to match the request to any of the locations, but I cannot find how to do this.
I don't see anything wrong with your code.
location / { is already the default location block for "unhandled" locations.
This would match all locations:
location / {
# ...
}
This would match the root only:
location = / {
# ...
}
This will match /auth and sub directories:
location /auth {
# ...
}
It must be related to how nginx does request matching -- somehow auth and authorize are too similar and it causes nginx problems (not a great explanation and maybe someone more experienced with nginx internals can chime in). The "solution" was to duplicate location / into location /authorize, so now the config file looks like:
...
location / {
auth_basic off;
proxy_http_version 1.1;
proxy_set_header Host $http_host;
proxy_pass http://portal_backend/;
}
location /authorize {
auth_basic off;
proxy_http_version 1.1;
proxy_set_header Host $http_host;
proxy_pass http://portal_backend/;
}
...
All the other routes work as I would have expected, e.g. /users, /customers, /whatever are all handled by location /

nginx try_files from proxy'd app, then nginx

I'm attempting to have nginx reverse proxy static files from an application if the application is serving them, else serve them itself. Currently, I have this configuration:
upstream app_server {
server unix:/tmp/gunicorn.sock fail_timeout=0;
}
server {
listen 8080;
server_name example.com;
access_log /var/log/nginx.access.log;
error_log /var/log/nginx.error.log;
keepalive_timeout 5;
location /static {
try_files $uri #proxy_to_app;
alias /path/to/__static;
sendfile off;
}
location / {
try_files $uri #proxy_to_app;
}
location #proxy_to_app {
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
proxy_set_header Host $http_host;
proxy_redirect off;
proxy_pass http://app_server;
}
}
This works if the files don't exist in /path/to/__static; it sends the request to the application server. However, if the files also exist in /path/to/__static, nginx serves the files itself.
Reversing the try_files line (try_files #proxy_to_app $uri) fails in both cases. If the client requests /static/css/test.css, the application receives a request for /css/test.css, and it never seems to try /path/to/__static even though the application returns a 404.
Updated to include full configuration.
location /static/ {
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
proxy_set_header Host $http_host;
proxy_redirect off;
proxy_pass http://app_server;
proxy_intercept_errors on;
error_page 404 =200 /local$uri;
}
location /local/static/ {
internal;
alias /path/to/__static/;
}

Resources